Search code examples
smlsmlnj

Why doe this SML code evaluate to 7 and not 6?


I've been shown this SML code as an example of an inner binding shadowing an outer one.

let val x = 1
in
  (let val x=2 in x+1 end) + (let val y = x+2 in y+1 end)
end

After the example, the author writes that the code above evaluates to "7," and when I run it, I get the same result:

: val it = 7 : int

I don't understand why. If x "shadows" the outer binding, then in the initial let, it should be 2, correct? So the function should be:

2 + 1 
3
3 + 2 (x = 3, y = x + 2, so y = 3 + 2 = 5) 
5
5 + 1 (y = 5, 5 + 1 = 6)
6

Even if I misunderstood how shadowing works, the final result should be 5, not 6 and not 7. So what's happening here?


Solution

  • As sometimes happens, writing the question made the answer finally click.

    The block should be evaluated as follows:

    x = 2
    x + 1
    2 + 1
    result: 3
    result: 3 + ( y + 1), y = (x + 2) where x=1 (from above)
     3 + ( 1 + 2) + 1
     7