Thursday, May 22, 2008

Lexical Scope and Closures

Lexical scope is not a radical departure from java: the concept already exists. When we create an inner instance class in java, the inner class has access to all the instance variables of all enclosing classes, and even to local variables if it's an anonymous inner class. Similarly, in arc, a locally-defined function has access to all the variables of all enclosing functions. This set of variables and their values is called the closure of the function.

(def powerfn (y) (fn (x) (expt x y)))

(set square (powerfn 2)) ; --> square is (fn (x) (expt x y)) with y = 2
(set cube (powerfn 3)) ; --> cube is (fn (x) (expt x y)) with y = 3

(square 5) ; --> 25
(cube 5) ; --> 125

In this example, the variable y retains its value - 3 or 2 - long after powerfn has exited, in the closure of the function returned by powerfn (the function that is assigned to square and cube)

When rainbow finds a locally-defined function in the course of evaluation, it creates a Closure object which encapsulates the function in question, and its closure. The Closure thus created can subsequently be stored in a variable, and invoked anywhere at any time. The implementation isn't optimal however: it keeps the entire closure, rather than just the closed variables that are actually used by the function in question.

No comments: