0

I write two different pieces of code trying to figure out the substitution v.s. evaluation order SML uses with respect to function arguments. But the results confused me a lot.

The toy function is as below

fun pow x y = if y=0 then 1 else x * (pow x y-1));

It only works as I expected when I surround the expression, i.e. y-1 with parens. So I augment it with a simple print statement to track what's going on.

fun pow x y = (print("y is: "^ Int.toString(y)^"\n");
if y = 0 then  1 else x * (pow x y-1))

It runs like value y remains the same every time the function is called( Apparently y-1 is not properly evaluated or parsed as a whole here.)

However, another dummy code I wrote below works perfectly out of my expectation, though.

fun foo x y= x+y;
val res= foo 2 3-9

res = -4 which does not run in the same logic as above.

Any insights on this will be appreciated!!

(I have read some simple illustration about adding parens allows to determine where the argument ends, but it's not so convincing)

Ze Gao
  • 91
  • 1
  • 7

1 Answers1

1

pow x y - 1 is equivalent to (pow x y) - 1. The same is true for your foo example, but 2 + (3 - 9) and (2 + 3) - 9 actually have the same result, which is why you don't see a difference.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • It makes sense, but I also wonder why it behaves that way. If the grammar(or the exact parsing procedure) is provided, then tons of thanks :D – Ze Gao Jul 27 '17 at 14:45
  • 1
    @ZeGao It behaves this way because function application has higher precedence than any infix operator, that is `f x op g y` (where `op` is some infix operator such as `+`) will always be parsed as `(f x) op (g x)`. You can find a grammar [here](https://people.mpi-sws.org/~rossberg/sml.html), but that doesn't really help here as it doesn't list precedence. – sepp2k Jul 27 '17 at 14:58
  • I think I kinda understand it. An expression probably/potentially has blank-spaces, which are exactly used as delimiters among currying arguments. So as to resolve such conflicts, it's safe to surround the expressions with parens, otherwise the parser have no way to distinguish those cases. – Ze Gao Jul 27 '17 at 14:59