Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong order of evaluation in application of curried function #50

Open
nrnrnr opened this issue Jul 26, 2017 · 6 comments
Open

Wrong order of evaluation in application of curried function #50

nrnrnr opened this issue Jul 26, 2017 · 6 comments

Comments

@nrnrnr
Copy link

nrnrnr commented Jul 26, 2017

Moscow ML seems to be applying functions the Caml way, rather than what is called for in the Definition of Standard ML. The manual says to report this deviation as a bug. For me, it's a show-stopping bug.

Example source code:

structure S = struct
  fun shout_then_apply f = (print "Shouting.\n"; f)
  fun id x = x
  val _ = shout_then_apply id (print "Evaluating second argument.\n")
end

The standard says that the first print should be called when shout_then_apply is applied to id, which is before the second print is evaluated. But that's not what mosml does:

For comparison, here's output from MLton:

nr@homedog ©152/g/textbook> mosmlc -toplevel -o a mosmlbug.sml
nr@homedog ©152/g/textbook> ./a
Evaluating second argument.
Shouting.
nr@homedog ©152/g/textbook> mlton -output b mosmlbug.sml
nr@homedog ©152/g/textbook> ./b
Shouting.
Evaluating second argument.
nr@homedog ©152/g/textbook> 

Standard ML of New Jersey also gets the evaluation order right.

For me, this is a show-stopping bug---is there any chance of getting it fixed?

@nrnrnr
Copy link
Author

nrnrnr commented Jul 26, 2017

Followup: I found this workaround:

  val _ = let val g = shout_then_apply id in g end (print "Take two.\n")

which behaves in a way that is consistent with the standard. So the bug is no longer show-stopping; it's just a bug.

@sestoft
Copy link
Collaborator

sestoft commented Jul 27, 2017 via email

@nrnrnr
Copy link
Author

nrnrnr commented Jul 27, 2017

I'm sure it's rarely encountered, but in the next release of the manual you might want to point it out, rather than encourage people to report "any deviation" as a bug. And other people might like to know about the workaround...

(My real application is slightly sordid, which is to instrument the evaluation of a let expression without wrapping the expression in anything. I evaluate the function applyCheckingOverflow (fn x => x)\ expression, where

  fun applyCheckingOverflow f =
    if !recursionLimit <= 0 then
      raise RuntimeError "recursion too deep"
    else
      let val _ = recursionLimit := !recursionLimit - 1
      in  fn arg => f arg before (recursionLimit := !recursionLimit + 1)
      end

If the application happens to raise an exception, it is caught elsewhere, and the counter is reset.

P.S. @rossberg is pretty good company!

@sestoft
Copy link
Collaborator

sestoft commented Jul 28, 2017 via email

@dcurrie
Copy link
Contributor

dcurrie commented Dec 21, 2017

This bug has been noted in mosml/doc/bugs as long as I can remember!

  • e

@sestoft
Copy link
Collaborator

sestoft commented Dec 21, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants