another round of call-chaining mystery?

kris foo at bar.com
Thu Mar 29 23:45:28 PDT 2007


James Dennett wrote:
> kris wrote:
> 
>>James Dennett wrote:
>>
>>>kris wrote:
>>>
>>>
>>>>James Dennett wrote:
>>>>
>>>>
>>>>>kris wrote:
>>>>
>>>>[snip]
>>>>
>>>>
>>>>>>There never was any argument of which you claim. I simply noted that
>>>>>>eval-order had been clarified before, using your usage of "eval-order"
>>>>>>from within the same post. If you revisit, you'll see that was
>>>>>>actually
>>>>>>referring to call-chaining instead, so there's perhaps a misuse of
>>>>>>terms:
>>>>>>
>>>>>> Cout.opCall("Hello, ").opCall(Cin.get);
>>>>>>
>>>>>>As you can see, there is only one parameter passed to each call, and
>>>>>>therefore the order of /parameter/ eval is "not at stake here" (as I
>>>>>>noted to Frits). 
>>>>>
>>>>>
>>>>>There are two arguments to the second opCall.  One is
>>>>>the result of Cout.opCall("Hello, ") and the other is
>>>>>the result of Cin.get, and they can be evaluated in
>>>>>either order unless some rule prohibits it.
>>>>
>>>>I think you'll find that call-chaining does not operate in that manner,
>>>>James? If you look a bit closer, you'll see that the lhs has to be
>>>>evaluated first, simply to get something to deref the rhs. Further,
>>>>there is only one argument permitted to the opCall() itself
>>>>
>>>>For a fuller description, I suggest you bring it up with Walter instead?
>>>
>>>
>>>Walter's post in this thread (<eui80b$19hl$1 at digitalmars.com>)
>>>seems to confirm my viewpoint as quoted above.  If you still
>>>don't think so after reading his message, I'd be interested
>>>if you can explain where Walter's explanation differs from
>>>mine.
>>>
>>>Regards,
>>>
>>>James.
>>
>>Simply because that's what Walter led us to believe a long time ago,
>>James, and it is how the compiler is implemented. Don't know what else
>>to tell you.
> 
> 
> I doubt that Walter lead you to believe that the order of
> evaluation was defined for the particular example code
> under discussion here.  ("Call chaining" is not the issue
> at hand; order of evaluation of function arguments is the
> relevant issue.)
> 

*sigh*

let's tease a couple of things apart, James? First, there is the 
question of call chaining operating in an ordered fashion. Second, 
there's the question of whether the miserable example is "correct" or 
not. Would you agree?


> Did you read the message of Walter's to which I referred?

Naturally


> 
> Walter wrote, today:
> 
> 
>>The nested opCall will get called before the outer opCall,
>>but otherwise the order is undefined (and will change
>>depending on the function calling convention, whether it
>>is a virtual call or not, etc.).
> 
> 
> This is very concrete and very specific, and supports what
> I wrote above.  Are you suggesting that you disagree with
> this?  (If so, with what do you disagree: that Walter wrote
> this, that it supports my viewpoint, or something else?)

You're tying two concerns together. Walter notes that the nested opCall 
is always called before the outer. This is consistent with the 
requirements for call-chaining (they should be called left to right). 
The only question remaining is that of what happens with three chained 
calls. I'm awaiting the answer from Walter, but I would certainly hope 
that call-chaining invocation order is maintained.

As for that sordid little example, it has generated way to much concern 
for something that should be merely of passing interest. It just happens 
to work because of output buffering, and no other reason.

In tango, the console is buffered and, in general, one has to flush the 
output before it will be emitted (just like a file). Console output has 
historically had a few 'shortcuts' added such as a newline adding a 
hidden .flush for interactive console usage. There is no newline in this 
daft example, and the only .flush present is on the first line. Thus, 
the example is relying on cleanup-code to flush the output buffers on 
its behalf. As I've noted before, this hardly exhibits good coding 
practice.

To make it perfectly clear, there was *never* any claim or belief that 
the Cin.get is or was evaluated before the Cout("hello "). We all 
intuitively *know* that the "hello " should be emitted before the 
Cin.get, but it isn't in that example. Again, it is because of buffering 
and the complete lack of an intervening flush on the console output.

There's a good reason why "mystery" is in the topic line ;)

I do hope that helps?



More information about the Digitalmars-d mailing list