Reputation: 465
I have this statement:
let val x =
let val x = 5
in(fn y =>(y,x+y))
end
in
let val y=3 and z=10
in x z
end
end;
The output is :
(10,15)
I've been trying to track how this answer was produced but am getting confused. Is there a better way to write this that would help me understand what variables are being used where? Thank you!
Upvotes: 3
Views: 148
Reputation: 7190
Can be understood using manual evaluation with detailed explanations.
Starting with your initial expression:
let val x =
let val x = 5
in (fn y => (y,x + y))
end
in
let val y = 3 and z = 10
in x z
end
end;
Line 2,3,4 is an expression whose type is a function, as you see in the in
part. It does not depends on any outer context, so it may be simplified as just fn y => (y, 5 + y)
, substituting x
to 5
, according to the binding given in let
.
So you now have this:
let val x = fn y => (y, 5 + y)
in
let val y = 3 and z = 10
in x z
end
end;
After substitution of x
(and removal of the let
which in then now not necessary any more):
let val y = 3 and z = 10
in (fn y => (y, 5 + y)) z
end;
Note the y
appearing in (y, 5 + y)
are bound to the function's argument, and not to 3
. There is no reference to this outer y
, so its biding may be removed.
Now you have:
let z = 10
in (fn y => (y, 5 + y)) z
end;
Substituting z
to 10
and removing the let
which is not necessary any more, you get:
(fn y => (y, 5 + y)) 10;
This is a function application. You may evaluate it, to get:
(10, 5 + 10);
Which gives the final and constant result you noticed:
(10, 15);
Upvotes: 0
Reputation: 629
You could simplify it to
let fun f y = (y,5+y)
val y=3 and z=10
in
f z
end;
Note that the two instances of y are independent. The inner occurrence of x (which I've eliminated) is independent of the outer one (now renamed f).
Upvotes: 3
Reputation: 5239
First, some alpha-conversion:
let val fnPairOfInputAndInputPlus5 =
let val five = 5
in ( fn input => ( input, five + input ) )
end
in let val ignored = 3 and input = 10
in fnPairOfInputAndInputPlus5 input
end
end;
This code is demonstrating that when you declare a function value, unbound values in the declaring scope, such as the value five
, are "enclosed" by the declaration (hence the term "closures"). Thus the function always returns a pair consisting of its input and its input plus five.
Upvotes: 4