I’ve written a few posts about features of the Lisp language that a newcomer arriving from C++ might not have encountered. I’m going through them alphabetically, so here is a summary page of the functions beginning with the letter ‘D’:
I’ve written a few posts about features of the Lisp language that a newcomer arriving from C++ might not have encountered. I’m going through them alphabetically, so here is a summary page of the functions beginning with the letter ‘D’:
Another obscure Lisp feature that the newcomer might not have encountered is dynamic-extent. This is used as part of a declare operation. It is purely a compiler hint, the Lisp implementation is free to ignore dynamic-extent entirely.
What a dynamic-extent declaration does is to indicate to the compiler that one or more symbols are entirely local to the form. Their values do not return to the caller, they are not inserted into objects or lists, they live and die completely in the form where the dynamic-extent declaration appears. They are local storage. When this is known, the compiler has the option of stack-allocating the objects referenced by the symbols, rather than throwing them into the garbage-collected heap. This can reduce computational overhead in the maintenance of the heap, and so speed up execution.
The next obscure command we’ll talk (briefly) about is dribble. This is nothing more than an output capturing function that allows you to keep a record of your interaction with the Lisp environment. You should usually not be using this. You should be using SLIME under Emacs to do your Lisp development, and you can keep a much more helpful record using those tools. I will note that dribble does not play well with SLIME, at least in my setup, which uses SBCL v1.1.14, Emacs 24.1.1, and SLIME from late January, 2013.
For notes on dpb, please see the earlier articles on byte and deposit-field.
Now we move on to a set of three macros, do-all-symbols, do-external-symbols, and do-symbols. These macros allow the code to iterate over a list of symbols as they are known to the Lisp image. The programmer might use these to inspect the execution environment and possibly call code in optional libraries, but there are usually easier ways to achieve that. One place that I have seen it used is similar to the use of weak symbols in the C++ linker. A piece of code can use do-external-symbols to detect collisions and import other symbols into its namespace only when there is no existing function/variable with the same name. The assumption is that there might be some very basic interface that is optionally extended in another file. The extended package can pick out those functions and variables from the basic package that are not re-implemented. Naturally, this requires very tight cooperation between the two interfaces, but I’ve seen it done.
What do these functions do? Well, do-symbols iterates over all symbols available to a package (or the current package if none is supplied). Generally, that’s all the symbols that the package creates, plus all the external symbols in other packages, including all the symbols in the Lisp language itself.
The do-external-symbols macro iterates over all symbols exported by the package (or the current package if none is supplied). This is the one you’re most likely to use.
The do-all-symbols macro iterates over all symbols in all packages. It’s a symbol dump of the Lisp image itself.
Note that do-symbols and do-all-symbols may list some symbols more than once, so if your goal is to visit each symbol exactly once, you’ll have to take steps to skip the duplicates.