From ... From: Erik Naggum Subject: Re: Macrolet within defmacro question Date: 1999/11/02 Message-ID: <3150510670469809@naggum.no>#1/1 X-Deja-AN: 543396964 References: <381e6f04@news.cadvision.com> mail-copies-to: never X-Complaints-To: newsmaster@eunet.no X-Trace: oslo-nntp.eunet.no 941521874 21895 195.0.192.66 (2 Nov 1999 05:51:14 GMT) Organization: Naggum Software; +47 8800 8879; +1 510 435 8604; http://www.naggum.no NNTP-Posting-Date: 2 Nov 1999 05:51:14 GMT Newsgroups: comp.lang.lisp * Wade Humeniuk | Can you do a macrolet like this within a defmacro? yes, but remember that a macro is really an ordinary function, it is just called at a different time than other functions. specifically, the macro is called with the form in question to yield the expansion, which is simply a new form as seen by the recipient of the value -- as with any other function, whatever was in scope _inside_ that function is gone when you exit it. to capture something, the function needs to be in the scope of whatever you want to capture. | What am I doing wrong??? you're trying to use macros that are no longer in scope. the following should work as you expect, as it makes the macros visible in the _expanded_ form. note that this doesn't have any significant cost. to look at the results, I use Allegro CL's walker (excl::walk) -- LWW probably has something similar that lets you macroexpand an entire form recursively and reduce the noise. (defmacro declare-html-style-sheet ((type-of-ss &key (stream '*standard-output*)) &rest elements &environment env) (declare (ignore type-of-ss env)) `(macrolet ((COLOR (color-value) `(progn (write-string "color: ") (write-string (string-downcase ,color-value)) (write-char #\;))) (ELEMENT (element-name &rest properties) `(progn (write ,element-name) (write-line ": {") ,@properties (write-line "}"))) (BODY (&rest properties) `(ELEMENT 'BODY ,@properties)) (ROOT (&rest properties) `(ELEMENT '* ,@properties))) (let ((*standard-output* ,stream)) ,@elements))) (excl::walk '(declare-html-style-sheet (:css2 :stream *standard-output*) (ROOT (COLOR :tan)) (BODY (COLOR :olive)))) => (progn (let ((*standard-output* *standard-output*)) (progn (write '*) (write-line ": {") (progn (write-string "color: ") (write-string (string-downcase :tan)) (write-char #\;)) (write-line "}")) (progn (write 'BODY) (write-line ": {") (progn (write-string "color: ") (write-string (string-downcase :olive)) (write-char #\;)) (write-line "}")))) stylistically, I don't think exploiting the case insensitivity of Common Lisp is such a good idea. it's better to stick to one form of a symbol. #:Erik