I just updated my Elisp memoization function so
that it’s no longer a dirty hack. To work around the lack of closures,
due to the lack of lexical scope in Elisp, the original version used
uninterned symbols to store the look-up table. The new version in the
lexical-let, which does the same thing internally to fake
a closure. The new version in my dotfiles
repository uses the brand new
Emacs 24 lexical scoping.
It was “dirty” because it built a lambda function out of a list at run
time, taking advantage of the way Elisp currently handles
functions. The reason for this was that I wanted to inject the
original documentation string into the new function which can’t
normally be done when
lambda is used the correct way. When I updated
the function I fixed this as well. It uses a trick provided by Elisp,
which is different than the Common Lisp way that I assumed.
Both Elisp and Common Lisp have a
documentation function for
programmatically accessing symbol documentation. The Elisp version
only provides function documentation, so it only accepts one
(defun foo ()
The Common Lisp version must be told what type of documentation to
return, such as
(documentation 'foo 'function)
As it might be expected, this is
setf-able! It’s possible to update
or modify documentation strings without needing to redefine the
(setf (documentation 'foo 'function) "New doc string.")
Unfortunately it’s not
setf-able in Elisp. Instead you can set the
function-documentation property of the symbol. The
function will prefer this over the string stored in the function
(put 'foo 'function-documentation "Foo updated.")
=> "Foo updated."
The downside is that this is a second place to put docstrings, leading
to surprising behavior for developers unaware of this hack.
(put 'foo 'function-documentation "Old docstring.")
(defun foo ()
=> "Old docstring."
This can be fixed by setting the symbol property for
(put 'foo 'function-documentation nil)
I prefer the Common Lisp method.