I was reading the source for ChanL the other day. It contains an example use of channels, to implement f开发者_StackOverflow社区utures. The DEFUNs were declared inside a LET, like so:
(let ((some-var some-value))
(defun foo () ... (reference some-var) ... )
(defun bar () ...))
What purpose does this serve? Is it just to provide some common value that several functions can share, and keep the encapsulation clean?
You already answered your question: to provide shared bindings for a group of functions and keep encapsulation clean.
Simple example from http://letoverlambda.com/textmode.cl/guest/chap2.html:
(let ((direction 'down))
(defun toggle-direction ()
(setq direction
(if (eq direction 'up)
'down
'up))))
(toggle-direction) => UP
(toggle-direction) => DOWN
(toggle-direction) => UP
(toggle-direction) => DOWN
You can also add a function inside this closure which behavior depends on direction.
Those are just closures. Just for the historical context [1],
Closures play a more conspicuous role in a style of programming promoted by Abelson and Sussman’s classic Structure and Interpretation of Computer Programs. Closures are functions with local state. The simplest way to use this state is in a situation like the following:
(let ((counter 0))
(defun new-id () (incf counter))
(defun reset-id () (setq counter 0)))
These two functions share a variable which serves as a counter. The first one returns successive values of the counter, and the second resets the counter to 0. The same thing could be done by making the counter a global variable, but this way it is protected from unintended references.
Paul Graham - On lisp
精彩评论