Subject: Re: Why don't people like lisp?
From: rpw3@rpw3.org (Rob Warnock)
Date: Fri, 24 Oct 2003 03:36:38 -0500
Newsgroups: comp.lang.python,comp.lang.lisp
Message-ID: <236dnaWsIZ8LeQWiXTWc-w@speakeasy.net>
Kaz Kylheku <kaz@ashi.footprints.net> 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:
| 
|   (language-a
|     ... establish some local variable foo ...
|     (language-b
|       ... reference to local variable foo set up in language-a!
|       ))
+---------------

Exactly so!

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.
	  ...
	  (:table ()
	    (:tr ()
	      (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
	      (htm
		(:tr (:align "right")
		  (loop for e from 1 to pows do
		    (htm
		      (:td ()
			(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],
that is:

	    (Lisp
	      ;; "i" is bound here
	      (HTML
	        (Lisp
	          (HTML
	            (Lisp
		      ;; "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

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607