andrewducker: (Default)
andrewducker ([personal profile] andrewducker) wrote2009-04-09 03:38 pm

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.

[identity profile] drainboy.livejournal.com 2009-04-09 03:46 pm (UTC)(link)
I hate long parameter lists, they end up as a jumble of variable names, where you have to constantly look up ordering to get the functionality you want.

I'm almost tempted to say have one input parameter and one output parameter, where both of those parameters are a list of named variables. You could still deal with default variable values (if your flavour of C has them) in the header file (if your flavour of C has them) and you could still call f(g()) because the output named parameter list of g would contain the input parameter list of f.

Though I'm sure this would get messy as you'd have to then remember the actual names of all the named parameters you wanted to pass.

This might also be more difficult to optimise in terms of putting parameters into registers, though I'm sure compiler writers would find a way (maybe by having JIT recompilation based on code use like C# etc.)

And I'm sure you can do this in Lua already.

[identity profile] drainboy.livejournal.com 2009-04-09 03:59 pm (UTC)(link)
I'm not so convinced they would. You could act like it's a bag of variables, whilst still checking at compile time that all the variables were of the correct type.

Obviously you're right about intellisense, though it's not as good in C++ as in C# (or maybe MSDev 2005 isn't as hot as 2008).

A bag of input parameters would mean you'd no longer have to put all the default variables at the end and fill them in explicitly if you merely wanted the last variable to be a non-default value.

[identity profile] drainboy.livejournal.com 2009-04-09 04:02 pm (UTC)(link)
Actually, thinking about it, whilst you could guarantee the types of the input variables, you might not be sure what you were getting out of the function, so g(f()) might be difficult to strongly type, unless you had default named outputs.

Which starts to get overly complex and doesn't sound worth it :)

[identity profile] figg.livejournal.com 2009-04-09 04:23 pm (UTC)(link)
Named paramaters are kinda neat, and a little better than passing a list.