In chapter 6 of "Let Over Lambda" I found anaphoric macro called alet
. It works like let
, but especially useful when the last form of alet
body is a lambda expression, since it allows using of the lambda expression before it actually occurs in the text.
This is the first version of the macro, alet%
:
(defmacro alet% (letargs &rest body)
`(let ((this) ,@letargs)
(setq this ,@(last body))
,@(butlast body)
this))
So far, so good. But next the author decides to enhance the macro with the following reasoning:
alet%
can be made to not return the last form in its body—which we anticipate to be a lambda form—but instead a function that looks up another function inside the let form's lexical scope, then calls that function instead. This is sometimes called indirection because instead of returning a function to do something, we return a function that looks up a function using a pointer dereference, then uses that function instead. Indirection is a concept ubiquitous throughout programming languages for good reason. It lets us change things at run-time that, without indirection, are fixed at compile-time.
alet
is defined as:
(defmacro alet (letargs &rest body)
`(let ((this) ,@letargs)
(setq this ,@(last body))
,@(butlast body)
(lambda (&rest params)
(apply this params))))
What is the difference? What can this final version do that alet%
can't? alet
returns lambda which will call another lambda. What it's good for? If someone could give an example of indirection use, it would be appreciated.