stdio line-streaming revisited

Chris Nicholson-Sauls ibisbasenji at gmail.com
Thu Mar 29 07:46:05 PDT 2007


Derek Parnell wrote:
> On Thu, 29 Mar 2007 22:40:34 -0700, Walter Bright wrote:
> 
>> kris wrote:
>>>    Cout.opCall("Hello, ").opCall(Cin.get);
>> Given:
>> 	a.f(b,c);
>> can be equivalently written as:
>> 	f(a,b,c);
>>
>> we can transform:
>> 	Cout.opCall("Hello, ").opCall(Cin.get);
>> into:
>> 	opCall(opCall(Cout,"Hello, "), Cin.get);
>>
>> And it is transformed that way, because the optimizer/back end knows 
>> nothing about member functions. They're just more function calls.
>>
>> 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.). 
> 
> Now that makes sense. I can see now why the W&A show is concerned. In fact,
> the call-chaining example seems to flesh out to ...
> 
>    opCall(opCall(Cout,"Hello, "), get(Cin));
> 
> which means that either the 'get' could be called first or the inner
> 'opCall' could be called first. One can never be sure.
> 
> This would mean that the sequence example given by Kris ...
> 
>     Cout ("Please enter your name: ").flush;
>     Cout ("Hello, ") (Cin.get);
> 
> gets transformed in to 
> 
>     flush( opCall( Cout, "Please enter your name: "));
>     opCall( opCall( Cout, "Hello, "), get(Cin));
> 
> The first statement will end up displaying the text on the console, leaving
> the cursor to the right of the ':' character. Now if the 'get' is called
> next, the user types in her name, say "mavis" and the screen will show ...
> 
>   Please enter your name: mavis
>   _
> 
> and then the inner 'opCall' is run which will show (assuming a flush) ...
> 
>   Please enter your name: mavis
>   Hello, mavis
>   _
> 
> 
> However, if the inner 'opCall' is called first the screen will show ...
> 
>   Please enter your name: Hello, _
> 
> and the user types in her name and we get ...
> 
>   Please enter your name: Hello, mavis
>   mavis
>   _
> 
> 
> So the order is reasonable important to sort out.
> 
> Being the conservative procedural type of coder, I would have probably have
> coded ...
> 
>     char[] userName;
>     Cout ("Please enter your name: ").flush;
>     userName = Cin.get();
>     Cout ("Hello, ");
>     Cout (userName);
>     Cout.flush;
> 
> Actually, now that I think about it, I'd really do ...
> 
>     char[] userName;
>     char[] myResponse;
> 
>     Cout ("Please enter your name: ");
>     Cout.flush;
>     userName = Cin.get();
>     myResponse = std.string.format("Hello, %s\n", userName);
>     Cout.( myResponse );
>     Cout.flush;
> 
> That is of course, if I'd really used stdin/stdout in that manner at all
> <G>
> 

I'd do something like...

import tango .io .Console ;
import tango .io .Stdout  ;

char[] userName ;

Stdout ("Please enter your name: "c) .flush ;
userName = Cin.get();
Stdout .formatln("Hello, {}.", userName) .flush ;


That's closer to my usage patterns with Tango.  (I'm a bigger fan of Stdout than Cout in 
most cases, partly because I use plenty of format strings.)

-- Chris Nicholson-Sauls



More information about the Digitalmars-d mailing list