Closures in Scheme

Scheme supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.

(define (int-seq)
  (let ((i 0))
    (lambda ()
      (set! i (+ i 1))
      i)))

This function int-seq returns another function, which we define anonymously in the body of int-seq. The returned function closes over the variable i to form a closure.

(define (main)
  ; We call int-seq, assigning the result (a function)
  ; to next-int. This function value captures its
  ; own i value, which will be updated each time
  ; we call next-int.
  (define next-int (int-seq))

  ; See the effect of the closure by calling next-int
  ; a few times.
  (display (next-int))
  (newline)
  (display (next-int))
  (newline)
  (display (next-int))
  (newline)

  ; To confirm that the state is unique to that
  ; particular function, create and test a new one.
  (define new-ints (int-seq))
  (display (new-ints))
  (newline))

(main)

To run the program, you would typically save this code in a file (e.g., closures.scm) and run it using a Scheme interpreter. The exact command may vary depending on your Scheme implementation, but it might look something like this:

$ scheme < closures.scm
1
2
3
1

In Scheme, closures are a fundamental concept and are used extensively in functional programming. The ability to create and return functions that capture their lexical environment is a powerful feature of the language.