Multiple return values...

Manu turkeyman at gmail.com
Thu Mar 8 16:23:47 PST 2012


On 9 March 2012 01:56, Mantis <mail.mantis.88 at gmail.com> wrote:

> 09.03.2012 1:28, Manu пишет:
>
>> [...]
>>
>> The problem is, that approach feels like a double negative to me. A tuple
>> is fundamentally a structure, returned by value. Implementing hacks to
>> subvert the standard behaviour of returning a structure by value is
>> unintuitive for a start, and you also lose the ability to *actually* return
>> a structure by value should that be what you intend.
>> You're sacrificing a well defined, 'properly' implemented mechanic to
>> imitate something the language simply can't express. I just think that's
>> the wrong way to go about it.
>>
>> Let me try and make my case as I see it...
>>
>> These are 2 distinct concepts, returning multiple values, and returning a
>> struct by value.
>>
>> Returning a structure by value is currently well defined, and behaves as
>> any same programmer would expect; it is written to the stack with memory
>> layout according to the STRUCTURE. This is true for a tuple, and it works
>> as one expects. I have no issue here. If you return a tuple, you SHOULD be
>> able to take the pointer of the first item, perform some arithmetic, and
>> address some other struct member. It is a struct, it ought to behave like
>> one, precisely as any programmer will expect.
>>
>> By contrast, multiple return values are quite the opposite. They are
>> explicitly NON-STRUCTURED. These serve a totally different purpose; to
>> return multiple unstructured things from a function.
>> Imagine an inline function which returns 2 results, only one of which is
>> captured. It is easy and intuitive to eliminate the code path leading to
>> the ignored result. Not so simple if you're returning structured data,
>> because it could be indirectly addressed.
>> In this case, using an explicit syntax to perform this specific task
>> doesn't suffer from the implicit problems associated with subverting the
>> structure syntax (what to do about memory layout/pointer arithmetic?
>> reserve stack space and generate code to store implicitly? ick!), but it
>> also clearly states the programmers intent, and also clearly communicates a
>> presumed behaviour. The presumption in this case is that multiple return
>> values would follow the exact same set of rules as passing multiple args TO
>> a function, but in reverse.
>>
>> Both operations seem useful and important in their own ways, they are
>> also both distinct operations, and they both warrant an expression in the
>> language. Returning a tuple if perfect how it is, it is just not what I
>> want to do in cases like those I list in my OP.
>>
>> How is any programmer supposed to intuitively assume that returning a
>> tuple by value would behave in that way? And how are you supposed to trust
>> it? It's an abuse of concept and syntax. It seems like a convolution that
>> could only possibly confuse people, they are conceptually quite different
>> things, and shouldn't be lumped into the same syntax for my money.
>>
>
> Is tuple required to be anonymous struct? I thought it's implementation
> details that may be done the other way if tuples implemented in language
> rather then library. There's another problem with non-named return values,
> as this:
> auto (sin_a, cos_a) = sincos( a );
> is not equivalent to this:
> auto (cos_a, sin_a) = sincos( a );
>

I can't imagine a syntax that's non-destructive to the existing grammar
where order is not important, but order would be clearly stated in the
auto-complete pop-up, and in the reference. Also mismatching types would
throw errors.

Here it doesn't matter much, but if you are returning more variables, that
> may become confusing and bloated, and will provoke juniors to make errors,
> which is obviously not good for your money =). Note also, since variables
> should be defined /before/ function call, your IDE will not help you to
> avoid such mistakes.
>

If you feel so strongly, state a company policy banning the feature. My
company does that with things like stl, sort the problem right out :)
I don't think that's a reasonable argument to intentionally make the
language unable to express a very useful software concept.

Another thing is that if you may 'save' packed variables for later use,
> such code can be made possible:
> auto t = getSomeTuple(...);
> someVar = t.var;
> foreach( v; t[1..$] ) { // static foreach, gets unrolled for every value
> in t except for the first
>    sum += v;
> }
> Not for everyday use, but sometimes may be useful.
>

If I want to do this, I will do exactly this! :)

Anyway, what's your suggestion for the syntax?
>

I can imagine syntax using parentheses, but I don't think I'm qualified to
propose a robust syntax, I don't know enough about the finer details of the
grammar.
Perhaps if other people agree with me, they could present some creative
solutions to the syntax?

I imagine something like:
auto (x, y) = func(); // specify auto for all results?
float (x, y) = func(); // specify explicit type for all results?
(int x, float y) = func; // explicitly type each result?
int x; ... (x, float y) = func(); // assign to predeclared variable(/s)?
(x, , z) = func(); // ignore the second result value (elimination of the
second result's code path)

I'm sure other more bizarre syntax could be possible too to help reduce
bracket spam. Ideas from things like lambda syntax?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20120309/6e69af06/attachment.html>


More information about the Digitalmars-d mailing list