On 20 Sep 2012, at 13:48, David Matthews wrote:

> On 20/09/2012 08:20, Lars-Henrik Eriksson wrote:
>> 19 sep 2012 kl. 18.00 skrev David Matthews:
>> 
>> Also the same ML code *will* behave differently when run
>> interactively or stand-alone using Poly/ML:
>> 
>> Poly/ML 5.5.0 Release
>>> fun f() = (print "Say something: "; TextIO.inputLine TextIO.stdIn;
>>> print "Thank you.\n");
>> val f = fn: unit -> unit
>>> PolyML.export("test",f);
>> val it = (): unit
>>> f();Hello
>> Say something: Thank you. val it = (): unit
>> 
>> unix> ./test Say something: Hello Thank you.
>> 
>> I believe that the stand-alone behavior is the reasonable one -- it
>> also agrees with SML/NJ and Moscow ML.
> 
> If you remember that the read-eval-print loop uses TextIO.input1 rather than 
> TextIO.inputLine it all makes sense.  At the end of compiling the next 
> character to be read from stdIn is the character immediately after the 
> closing semicolon.  That may or may not be a newline character depending on 
> what the rest of the input was.  If the code that has just been compiled 
> wants to read from the stream this is where it starts. The next time round 
> the loop the compiler starts after anything that has been removed.  When 
> running as a stand-alone executable the behaviour is exactly the same; it's 
> just that the compiler has not been run so the function starts at the 
> beginning of the stream.
> 
>> Does this cause problems? Yes, for me it does. We use ML in the
>> introductory programming course for CS majors and it causes
>> unnecessary complications for the students.
> 
> I am not completely wedded to the present way of doing things but I feel 
> there has to be a stronger rationale for changing it.  I would be interested 
> to know if anyone else has feelings one way or the other.

I have fairly strong feelings that it is not worth worrying about. Personally, 
I find the Poly/ML behaviour more to my liking than the SML/NJ behaviour 
because beginning execution immediately after reading the semicolon feels more 
intuitive. Programmers and language implementors are all doomed if the rest of 
the line containing the i/o command is not syntactically complete, as in:

print "Type something, please: "; val x = TextIO.inputLine TextIO.stdIn; print (
    "thank you!");

(Poly/ML and SML/NJ both bind something to x and then report a syntax error, 
but the value of x and the syntax errors are different: in Poly/ML, the left 
bracket has been consumed into x and the right bracket is unmatched, but vice 
versa for SML/NJ.)

In any case, isn't this an issue for the implementation of the basis library 
rather than the compiler proper?  I don't see any reason why the interactive 
compiler and the basis library need to share their standard i/o streams. That's 
what happens with the existing implementations, but I don't see that the basis 
library specification mandates it - couldn't a valid implementation of the 
basis library bring up a separate window for its standard i/o?

So I think I side with Larry Paulson in viewing this as an instructive instance 
where the programmer needs to distinguish between implementation-dependent 
behaviour and behaviour that is guaranteed by the relevant specifications or 
standards.

Regards,

Rob.



_______________________________________________
polyml mailing list
[email protected]
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml

Reply via email to