Closures in Lisp

(defun int-seq ()
  (let ((i 0))
    (lambda ()
      (incf i))))

(defun main ()
  (let ((next-int (int-seq)))
    (format t "~a~%" (funcall next-int))
    (format t "~a~%" (funcall next-int))
    (format t "~a~%" (funcall next-int))
    
    (let ((new-ints (int-seq)))
      (format t "~a~%" (funcall new-ints)))))

(main)

Lisp supports anonymous functions and closures, which are powerful features for creating flexible and reusable code. This example demonstrates how to use these concepts.

The int-seq function 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.

In the main function:

  1. 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.

  2. We see the effect of the closure by calling next-int a few times.

  3. To confirm that the state is unique to that particular function, we create and test a new one.

When you run this program, you should see output similar to:

1
2
3
1

This demonstrates that the closure maintains its own state, and each new closure created by int-seq has its own independent counter.

In Lisp, closures are a fundamental concept and are used extensively in functional programming patterns. They provide a way to create functions with private state, which can be very useful for implementing iterators, callbacks, and other advanced programming techniques.