Some Lisp compilers produce two separate object files for a .lisp file: A FASL file that contains the runtime effects, and a CFASL that contains the compile-time effects (such as macro definitions).
But why stop at two object files? A single file could in fact produce any number of runtimes (FASLs).
One example where this would make sense is documentation: Imagine a DEFDOC macro (for documenting variables), whose effects take place at documentation-time:
(defvar x 1)
(defdoc x "A cool variable.")
DEFDOC registers the documentation string "A cool variable." with X in some table, so that it can be looked up.
The FASL would contain (defvar x 1), and the DFASL would contain (defdoc x "A cool variable.").
Now it's up to the programmer to decide when and if to load the DFASL: in the development environment, one would always load documentation-time, but for a packaged application maybe not. There one would only ship the FASLs, not the CFASLs and DFASLs (unless the application is intended to be programmed by users).
I actually did something sort of like this for Atomy. I introduced an in-code documentation system that runs during macroexpansion, if Atomy is run with the -d flag, writing to a documentation output stream. Without the -d flag, they just expand to whatever code they're wrapping/documenting.
ReplyDeleteHa, cool!
ReplyDeleteAFAIK, Racket does exactly this. See http://docs.racket-lang.org/scribble/srcdoc.html
ReplyDelete