Day 32/100: More work on slides and closures

Today I did a little more work on my slides for the MUG presentation, but I also read some more of the (excellent) manual. The section on Closures really helped me understand better what was going on.

For those playing along at home, a closure is when a function is called in such a way that the local state is preserved. So, for example:

(define (silly-function x)
(let ((y (/ x 2)))

This defines a lexical scope for y where y does not exist outside of the scope of the function. If I did the following:

(define y "moo")
(silly-function 8)  => 4
y  => "moo"

"y" is not overwritten.

What makes closure so powerful is best described in this example (taken from the Guile documentation):

(define (make-serial-number-generator)
 (let ((current-serial-number 0))
  (lambda ()
   (set! current-serial-number (+ current-serial-number 1))

(define entry-sn-generator (make-serial-number-generator))

(entry-sn-generator)  => 1
(entry-sn-generator)  => 2

In this case current-serial-number is initialized with 0 and the lambda function turns the function into a variable. Since the function as a whole is saved as a variable you can assign it to another variable and that variable holds the address of the instantiated function. So when you call that variable as a function it looks up the address of the function, brings up the current state of where it left off, and then (in this case) increments the value of current-serial-number.

Simple, no?

I'm pretty sure I'm not explaining this right, but I'll hopefully explain it better for the slides. Closure is one of the important concepts of JavaScript and it's nice to see a clear example of this in Scheme.