See the following code where I tried out how already been declared variable x acts after being newly bound and then used within a function declaration. Why it is acting like this?
- val x = 2;
val x = 2 : int
- fun addx y = y + x;
val addx = fn : int -> int
- addx(5);
val it = 7 : int
- val x = 5;
val x = 5 : int
- addx(5);
val it = 7 : int
- subx y = y - x;
- fun subx y = y - x;
val subx = fn : int -> int
- subx(7);
val it = 2 : int
- 3 + x;
val it = 8 : int
- addx(10);
val it = 12 : int
This is caused by a combination of two features: immutability and variable shadowing. Variables are immutable, and cannot be reassigned to new values. But SML does allow you to shadow variable bindings, meaning that you are allowed to reuse an existing variable name for a new purpose (within a new lexical scope).
In the code you wrote, you used the name
xtwice for two different variables. The second declaration ofxshadows the first, i.e., any code in the lexical scope that follows which mentionsxis referring to the new declaration, not the old one. (Because of this possible confusion, some people consider variable shadowing to be bad code style.)We can rename the second declaration to make everything much clearer: