andrewducker (
andrewducker) wrote2009-04-09 03:38 pm
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Musings
I've been coming to the conclusion that I don't like the way that methods return variables in C-like languages. Having a single prioritised output parameter seems counterintuitive to me, and leads to two outcomes:
1) It's very easy to ignore/forget the return value.
2) If you have multiple return values then either one of them is the "proper" return value and the other one is passed back as a reference, or you pass back a tuple of some kind, or you have no return value and they both come back as references.
It seems to me that it would be clearer and simpler if you always specified what parameters were in and out.
Rather than
string Reverse(string inputString)
you'd have
Reverse (string inputString, out string outputString)
This doesn't make a lot of difference when it comes to a simple method like that. But if we take one with two outputs:
Do we use:
1) int GetMonthAndDay(DateTime inputDate, out int day)
2) MonthDayPair GetMonthAndDay(DateTime inputDate)
3) void GetMonthAndDay(DateTime inputDate, out int month, out int day)
The first one is clearly awful, the second one requires me to create an extra class, and the third one seems entirely clear.
Also, the use of different parameters means that you have smart method selection going on.
Convert(DateTime inputDate, out long seconds)
Convert(DateTime inputDate, out string nicelyFormatted)
makes it obvious from the parameters exactly what you're expecting to get back from it.
Of course, it does complicate very simple things:
DateTime tomorrow = today.AddDay();
would become
DateTime tomorrow;
today.AddDay(out tomorrow);
I suspect I'm just working on stuff where there are always multiple ins and outs, and also using generics and type inference, which doesn't work on return values, just parameters, and this is leading me to odd conclusions.
1) It's very easy to ignore/forget the return value.
2) If you have multiple return values then either one of them is the "proper" return value and the other one is passed back as a reference, or you pass back a tuple of some kind, or you have no return value and they both come back as references.
It seems to me that it would be clearer and simpler if you always specified what parameters were in and out.
Rather than
string Reverse(string inputString)
you'd have
Reverse (string inputString, out string outputString)
This doesn't make a lot of difference when it comes to a simple method like that. But if we take one with two outputs:
Do we use:
1) int GetMonthAndDay(DateTime inputDate, out int day)
2) MonthDayPair GetMonthAndDay(DateTime inputDate)
3) void GetMonthAndDay(DateTime inputDate, out int month, out int day)
The first one is clearly awful, the second one requires me to create an extra class, and the third one seems entirely clear.
Also, the use of different parameters means that you have smart method selection going on.
Convert(DateTime inputDate, out long seconds)
Convert(DateTime inputDate, out string nicelyFormatted)
makes it obvious from the parameters exactly what you're expecting to get back from it.
Of course, it does complicate very simple things:
DateTime tomorrow = today.AddDay();
would become
DateTime tomorrow;
today.AddDay(out tomorrow);
I suspect I'm just working on stuff where there are always multiple ins and outs, and also using generics and type inference, which doesn't work on return values, just parameters, and this is leading me to odd conclusions.
no subject
no subject
The problem is that function composition is a bitch
instead of doing
y = f(g(x)), you have to do f(x,x1), g(x1,y)
this gets very clumsy and annoying after a while.
Functions are useful for the common case of a single return, and in more mature languages you can return multiple values as pairs.
no subject
Is there a nice way of returning pairs of values? Or do you just get back a class with two things in it, and have to hope that they're the right way round?
no subject
To be frank, I haven't encounted such a problem with python, named parameters and easy tuples make this sort of problem a breeze.
Oh, and you're confusing strict and strong typing. Strict typing is type definition at compile time, and dynamic is at runtime.
Strong typing is the lack of implicit casts, and weak typing has implicit casting.
Oh, and saying 'hey intellisense makes this easy' is akin to 'hey this crutch makes it easy to walk with a broken leg'.
no subject
You're right about the casting - I meant static analysis, which is the "strict" side of things.
I don't understand your problem with intellisense. Care to elucidate?
no subject
It's a shame this is missing from Java, it seems it was planned originally: http://gbracha.blogspot.com/2007/02/tuples.html
I gather that adding this to C# would be difficult now because essentially the CLR type system doesn't have the underlying support. F# has tuples in the language but the underlying implementation is a hack.
Incidentally, has
no subject
no subject
If you had them in a statically typed C-like language you could do this:
And then call like this:
Note that as first-class types, tuples would also be usable for input parameters, variables, etc.
no subject
To put it mildly - ick!
no subject
The function in that style:
I'd think of them rather as anonymous C-style structures than as classes - there's nothing specifically object-oriented here.
no subject
That's more useful, definitely. And would do what I want.
Sold!
Now, someone needs to get on the phone to the C# boys and tell them that their anonymous classes need to work better so that they can be used this way!