Is the following code supposed to print 1 followed by 2 or 2 followed by 1?
val _ = (fn () => (print "1\n"; fn x => x)) () (print "2\n"; ())
In SML/NJ, MLton and PolyML it does the former, while in Moscow ML it does the latter. Is this specified somewhere in the standard? I noticed equivalent code in OCaml behaves the way Moscow ML does which is not very surprising seeing how Moscow ML was based on Caml Light. Could this be a bug in Moscow ML?
The following code works the same in all 4 SML compilers (but different in OCaml):
val _ = (print "1\n"; 1) + (print "2\n"; 2)
It seems to me like SML/NJ, MLton and PolyML evaluate all function arguments left to right, OCaml evaluates them right to left, and Moscow ML seems inconsistent.
On 18/08/11 15:06, Ivan Tomac wrote:
It seems to me like SML/NJ, MLton and PolyML evaluate all function arguments left to right, OCaml evaluates them right to left, and Moscow ML seems inconsistent.
I'd say that it seems like, given an expression (f x y), SML/NJ, MLton and PolyML evalute x, then (f x), then ((f x) y), while Moscow ML evaluates x, then y, then (f x y) (essentially uncurrying the function first). If OCaml prints 2 then 1 in the second example you gave, that seems like strange behaviour (evaluating y then x then (f x y)).
Alex
On Thu, Aug 18, 2011 at 4:00 PM, Alex Merry alex.merry@cs.ox.ac.uk wrote:
On 18/08/11 15:06, Ivan Tomac wrote:
It seems to me like SML/NJ, MLton and PolyML evaluate all function arguments left to right, OCaml evaluates them right to left, and Moscow ML seems inconsistent.
I'd say that it seems like, given an expression (f x y), SML/NJ, MLton and PolyML evalute x, then (f x), then ((f x) y), while Moscow ML evaluates x, then y, then (f x y) (essentially uncurrying the function first). ?If OCaml prints 2 then 1 in the second example you gave, that seems like strange behaviour (evaluating y then x then (f x y)).
what about evaluating f?
Alex
-- Alexander Merry DPhil Computer Science Department of Computer Science University of Oxford
polyml mailing list polyml@inf.ed.ac.uk http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
On 18/08/11 16:08, Ramana Kumar wrote:
what about evaluating f?
More testing required. In Poly/ML, the following test produces the output "14253": (print "1"; (fn () => (print "2"; fn x => (print "3"; x)))) (print "4") (print "5");
So the order of evaluation of (f x y) is f x (f x) y ((f x) y)
This seems like a natural evaluation order for an eager functional language.
Alex
On 18/08/2011 17:02, Alex Merry wrote:
On 18/08/11 16:08, Ramana Kumar wrote:
what about evaluating f?
So the order of evaluation of (f x y) is f x (f x) y ((f x) y)
This seems like a natural evaluation order for an eager functional language.
I have always understood that the Definition of Standard ML (rule 100) requires this order. The syntax of an application is exp ::= atexp exp atexp ... and the semantics first evaluates the exp to b, then the atexp to v and then applies b to v.
David
On 18 Aug 2011, at 17:50, David Matthews wrote:
On 18/08/2011 17:02, Alex Merry wrote:
On 18/08/11 16:08, Ramana Kumar wrote:
what about evaluating f?
So the order of evaluation of (f x y) is f x (f x) y ((f x) y)
This seems like a natural evaluation order for an eager functional language.
I have always understood that the Definition of Standard ML (rule 100) requires this order. The syntax of an application is exp ::= atexp exp atexp ... and the semantics first evaluates the exp to b, then the atexp to v and then applies b to v.
I think it's rule 101 not 100 (which is the rule for assignment). But read in conjunction with the state and exception conventions that are given before the rules, you are definitely right about this. I think I would be horrified if the call of cond below raised Div rather than CondFailed:
exception CondFailed; val (cond: ('a -> bool) -> 'a -> ('a -> 'b) -> 'b) = fn test => fn v => ( if test v then fn f => f v else raise CondFailed ); cond (fn v => v <> 0) 0 (raise Div);
Regards,
Rob.
I recall reading somewhere (can't find it now) that Moscow ML is incorrect, but that it was done deliberately for efficiency reasons, the thinking being that it would be unlikely to be an issue in practice.
That is (as I recall), in f x1 x2 x3 (f not an application) it will evaluate _all_ the arguments before evaluating _any_ of the applications
Peter - is this correct ?
Regards,
Jeremy Dawson
Ivan Tomac wrote:
Is the following code supposed to print 1 followed by 2 or 2 followed by 1?
val _ = (fn () => (print "1\n"; fn x => x)) () (print "2\n"; ())
In SML/NJ, MLton and PolyML it does the former, while in Moscow ML it does the latter. Is this specified somewhere in the standard? I noticed equivalent code in OCaml behaves the way Moscow ML does which is not very surprising seeing how Moscow ML was based on Caml Light. Could this be a bug in Moscow ML?
The following code works the same in all 4 SML compilers (but different in OCaml):
val _ = (print "1\n"; 1) + (print "2\n"; 2)
It seems to me like SML/NJ, MLton and PolyML evaluate all function arguments left to right, OCaml evaluates them right to left, and Moscow ML seems inconsistent. _______________________________________________ polyml mailing list polyml@inf.ed.ac.uk http://lists.inf.ed.ac.uk/mailman/listinfo/polyml