Page 1: Lexical scoping and nested functions; closuresPage 2: Closures and function applications ("activations").Page 3: Higher-order functions and closures; "lambda = let"Page 4: Scheme introPage 5: Scheme programs as data; a simple constraint solver using the eval function.Page 6: Final thoughts on functional programmingMeta-note about the diagrams on pages 1-2: I have simplified the diagrams by drawing each "scope" (global, let-local, and function-local) as a single entity. In fact, global and let-local scopes are both more like a stack of mini-scopes, with each binding potentially shadowing previous bindings. When a closure is constructed, its environment pointer points only to already bound values. Later bindings that shadow these original bindings will not be visible to the closure, as in the following:
- let = val x = "hi"; = fun foo() = x ^ " there"; = val x = "yo"; = in = foo() = end; val it = "hi there" : stringHowever, drawing a new environment for every val binding would have made the diagrams much too complicated, so I limited myself to one environment per let or function application.
SML code examples, Scheme code examples
In-class slides: PowerPoint
Diagrams in better (non-rasterized) formats:
- Global environment: Encapsulated PS, xfig
- Let-local environment: Encapsulated PS, xfig
- Function-local environment:
- Step 1: Encapsulated PS, xfig,
- Step 2: Encapsulated PS, xfig,
- Step 3: Encapsulated PS, xfig,