How would partial application work in an impure language? Not very well :-P
Jokes aside, closures in impure languages are hard to reason about when they are allowed to refer to mutable variables. For instance:
x = 0;
f = function (y) { return x+y; }
x = 1;
y = f(10); // 10 or 11 ?
There is no "right" answer to the question above: both 10 and 11 are reasonable outcomes, and the programmer must know which one is taken by the programming language at hand. Java, for instance, disallows the (Java-equivalent of the) code above. Java allows instead (the equivalent of)
x = 0;
const xc = x;
f = function (y) { return xc+y; }
x = 1;
y = f(10); // 10
because here there is no ambiguity: xc
is a const, so its value at closure-construction-time will be the same at closure-application-time. Java rules are slightly more relaxed than requiring that all the caprtured variables are constants.
Further, note that the problem is not merely theoretical. The blogged article Closing over the loop variable considered harmful shows that the semantics of C# was recently changed because programmers tripped into problems.
Ocaml, which is impure, can partially mitigate the issue when using ref
types. If x : int ref
then
let f1 = fun y -> !x + y
will use the value of x
at application-time, while
let f2 = let xv = !x in fun y -> xv + y
will use the value of x
at closure time.
Finally, C++11 took the choice of allowing many kinds of captures: you can capture a variable value (as in f2
above) or a variable reference (as in f1
).