Kaz Kylheku <email@example.com> wrote:
| Ah, but in Lisp, this is commonly done at *compile* time. Moreover,
| two or more domain-specific languages can be mixed together, nested in
| the same lexical scope, even if they were developed in complete
| isolation by different programmers. Everything is translated and
| compiled together. Some expression in macro language B can appear in
| an utterance of macro language A. Lexical references across these
| nestings are transparent:
| ... establish some local variable foo ...
| ... reference to local variable foo set up in language-a!
A concrete example of this is using a macro package such as Tim
Bradshaw's HTOUT together with (say) one's own application-specific
Lisp code. You can blithely nest macro-generated HTML inside Lisp
code inside macro-generated HTML, etc., and have *direct* access to
anything in an outer lexical scope! Big win. Consider the following
small excerpt from <URL:http://rpw3.org/hacks/lisp/appsrv-demo.lhp>
(which has been reformatted slightly to make the nesting more apparent).
Note that any form *not* starting with a keyword switches from the
HTML-generating language ("language-B") to normal Lisp ("language-A")
and that the MACROLET "htm" switches from normal Lisp ("A") back to
HTML generation ("B"):
(lhp-basic-page () ; Contains a call of WITH-HTML-OUTPUT.
(loop for e from 1 to pows
and h in headings do
(let ((p (cond ((= e 1) ":") ((= e pows) "") (t ","))))
(htm (:th (:nowrap)
(fmt h e) p)))))
(loop for i from 1 to nums do
(:tr (:align "right")
(loop for e from 1 to pows do
(princ (expt i e) s))))))))
Note how the innermost reference of "i" [in "(expt i e)"] is nested
inside *four* language shifts from the binding of "i" [in the LOOP form],
;; "i" is bound here
;; "i" is used here
Oh, and by the way, all of that HTML-generating code gets expanded
into Lisp code at macro-expansion time [roughly, at compile time].
Rob Warnock <firstname.lastname@example.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607