call chaining clarified
kris
foo at bar.com
Thu Mar 29 23:53:05 PDT 2007
Derek Parnell wrote:
> On Thu, 29 Mar 2007 23:14:09 -0700, kris wrote:
>
>
>
>>Thank you for that clarification, Walter.
>>
>>You note that the inner opCall will be evaluated before the outer one;
>>how is x.one(a).two(b).three(c) tranformed?
>
>
> I'm guessing ...
>
> three( two( one(x, a), b), c);
>
> thus either 'x' or 'a' is done first, then the other
> then either 'one' or 'b', then the other
> then either 'two' or 'c', then the other
> and finally 'three'
That's fine. One is invoked before two, before three. No other
expectations are in place
>
>
>>>I suggest that at a minimum, if you wish to retain the current design,
>>>build a test into the test suite that verifies the required order of
>>>evaluation.
>>>
>>>It's possible that in the future, to ensure source code portability of
>>>D, that the order of evaluation will become fixed. Such a change is a
>>>fair amount of work to accomplish, and will incur a runtime penalty (the
>>>implementation defined order allows the compiler to rearrange things to
>>>minimize register pressure). Even if the order was fixed, it still might
>>>not be in the right order for call chaining to work as your design needs
>>>it to.
>>
>>Do you mean in terms of generic call-chaining, or that example
>>specifically? For example, will the code x.one().two().three() always
>>execute one() before two() ?
>
>
> I think it would. But in the case of "x.one(a).two(b)" then you can't be
> sure if 'one' or 'b' will be evaluated first.
That's cool, Derek. The only expectation is that one is called before two
>
>
>>>I also suggest that, with the maturing of the variadic template
>>>capability of D, using it will side step the order of evaluation problem
>>>completely. It'll still be an aesthetically pleasing design to the user.
>>
>>That's certainly a possibility, Walter, but call-chaining is surely
>>expected to operate in an orderly fashion regardless of whether it is
>>used as an IO interface or not? For example, what happens if two() were
>>to return a different object for three() to be applied against? It would
>>surely be incorrect to generate code whereby three() were called against
>>x instead? In other words, for call chaining to operate correctly the
>>following pseudocode should likely hold true:
>>
>># auto result = x.one().two().three();
>>
>>auto tmp1 = x.one();
>>auto tmp2 = tmp1.two();
>>auto result = tmp2.three();
>>
>>Is that incorrect?
>
>
> I think Walter is saying that a test similar to ...
>
> auto tmpA = x.one(a).two(b).three(c);
> auto tmp1 = x.one(a);
> auto tmp2 = tmp1.two(b);
> auto tmp3 = tmp2.three(c);
> assert( tmpA is tmp3);
>
I would hope that would always pass, since without it, plain old
call-chaining would not function dependably (ingoring all the a, b, and c's)
Thanks for fleshing this out like you have
More information about the Digitalmars-d
mailing list