Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!rutgers!aramis.rutgers.edu!atanasoff.rutgers.edu!lou From: lou@atanasoff.rutgers.edu (Lou Steinberg) Newsgroups: comp.lang.lisp Subject: Re: Question about Macros (Common Lisp) Message-ID: Date: 5 Feb 90 16:39:59 GMT References: <31480@shemp.CS.UCLA.EDU> Distribution: usa Organization: Rutgers Univ., New Brunswick, N.J. Lines: 46 To: srt@maui.cs.ucla.edu In article <31480@shemp.CS.UCLA.EDU> srt@maui.cs.ucla.edu (Scott Turner) writes: > [...] I write a simple defmacro, the important part of which looks > like this: > > `(setf (structure-test foo) > #'(lambda (*spec*) ,@test-part)) > > Let's say that I define this macro in the RULE package. Later on, I go to > use this in the USER package, and looking at the macro-expansion I see > this: > > (lambda (rule::*spec*) (eql *spec* 'hyper)) > > What's the solution? I have to delay the de-reference of the symbol until > the macro is actually expanded. I came up with this: > > `(setf (structure-test foo) > #'(lambda (,(intern "*SPEC*")) ,@test-part)) Even this is not guaranteed to work - it depends on the current package being the same at macro expand time as it was when the macro call was read. On some systems, the interpreter expands macros at macro call time, when the package may be different. To really do it right, you need to search the value of test-part for any symbol whose print-name is "*SPEC*", and use that symbol for your lambda variable. Of course, this means different rules may be using different lambda variables, if they were read in under different packages. A possibly cleaner solution is to find any symbol in test-part that has a print-name of *SPEC* and replace it with YOUR symbol *SPEC*. `(setf (structure-test foo) #'(lambda (*SPEC*) ,@(subst-if '*SPEC* #'(lambda (x) (and (symbol x) (string-equal (symbol-name x) "*SPEC*")))n test-part))) (Warning - the above is not debugged.) -- Lou Steinberg uucp: {pretty much any major site}!rutgers!aramis.rutgers.edu!lou arpa: lou@cs.rutgers.edu