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