From: basman
Subject: macro for substituting variables in an expression tree
Date: 
Message-ID: <0acd623c-6b39-4ea0-8644-6608d5500e62@j22g2000hsf.googlegroups.com>
So I want to write a macro to produce a function that does variable
substitutions in an expression tree, like so:

CL-USER(309): (defmacro subst-vars (tree vars)
		(labels ((helper (x)
			   (cond
			    ((listp x) (cons 'list (mapcar #'helper x)))
			    ((member x vars) x)
			    (t `',x))))
		  `#'(lambda (,@vars) ,(helper tree))))
SUBST-VARS
CL-USER(310): (macroexpand '(subst-vars (foo (bar (baz ?x ?y) ?z)
(baz ?x)) (?x ?y ?z)))
#'(LAMBDA (?X ?Y ?Z) (LIST 'FOO (LIST 'BAR (LIST 'BAZ ?X ?Y) ?Z) (LIST
'BAZ ?X)))
T
CL-USER(311):

The macro above expands into a definition of a function that will have
the input-output behaviour that I want.  But, it would be nice, just
for my own debugging purposes, if the subst-vars call above expanded
instead to:
#'(lambda (?x ?y ?z) `(foo (bar (baz ,?x ,?y) ,?z) (baz ,?x)))

Try as I might, I can't seem to make this happen because of nesting
issues.  I feel like this must be a known problem... am I missing
something obvious?

From: basman
Subject: Re: macro for substituting variables in an expression tree
Date: 
Message-ID: <09aeea91-6763-466b-953c-612976fdfda6@l42g2000hsc.googlegroups.com>
Hmm, in hindsight, this is a silly question :)

On May 19, 7:02 pm, basman <········@gmail.com> wrote:
> So I want to write a macro to produce a function that does variable
> substitutions in an expression tree, like so:
>
> CL-USER(309): (defmacro subst-vars (tree vars)
>                 (labels ((helper (x)
>                            (cond
>                             ((listp x) (cons 'list (mapcar #'helper x)))
>                             ((member x vars) x)
>                             (t `',x))))
>                   `#'(lambda (,@vars) ,(helper tree))))
> SUBST-VARS
> CL-USER(310): (macroexpand '(subst-vars (foo (bar (baz ?x ?y) ?z)
> (baz ?x)) (?x ?y ?z)))
> #'(LAMBDA (?X ?Y ?Z) (LIST 'FOO (LIST 'BAR (LIST 'BAZ ?X ?Y) ?Z) (LIST
> 'BAZ ?X)))
> T
> CL-USER(311):
>
> The macro above expands into a definition of a function that will have
> the input-output behaviour that I want.  But, it would be nice, just
> for my own debugging purposes, if the subst-vars call above expanded
> instead to:
> #'(lambda (?x ?y ?z) `(foo (bar (baz ,?x ,?y) ,?z) (baz ,?x)))
>
> Try as I might, I can't seem to make this happen because of nesting
> issues.  I feel like this must be a known problem... am I missing
> something obvious?
From: Pascal J. Bourguignon
Subject: Re: macro for substituting variables in an expression tree
Date: 
Message-ID: <7cwslpqtdj.fsf@pbourguignon.anevia.com>
basman <········@gmail.com> writes:

> Hmm, in hindsight, this is a silly question :)
>
> On May 19, 7:02�pm, basman <········@gmail.com> wrote:
>> So I want to write a macro to produce a function that does variable
>> substitutions in an expression tree, like so:
>>
>> CL-USER(309): (defmacro subst-vars (tree vars)
>> � � � � � � � � (labels ((helper (x)
>> � � � � � � � � � � � � � �(cond
>> � � � � � � � � � � � � � � ((listp x) (cons 'list (mapcar #'helper x)))
>> � � � � � � � � � � � � � � ((member x vars) x)
>> � � � � � � � � � � � � � � (t `',x))))
>> � � � � � � � � � `#'(lambda (,@vars) ,(helper tree))))
>> SUBST-VARS
>> CL-USER(310): (macroexpand '(subst-vars (foo (bar (baz ?x ?y) ?z)
>> (baz ?x)) (?x ?y ?z)))
>> #'(LAMBDA (?X ?Y ?Z) (LIST 'FOO (LIST 'BAR (LIST 'BAZ ?X ?Y) ?Z) (LIST
>> 'BAZ ?X)))
>> T
>> CL-USER(311):
>>
>> The macro above expands into a definition of a function that will have
>> the input-output behaviour that I want. �But, it would be nice, just
>> for my own debugging purposes, if the subst-vars call above expanded
>> instead to:
>> #'(lambda (?x ?y ?z) `(foo (bar (baz ,?x ,?y) ,?z) (baz ,?x)))
>>
>> Try as I might, I can't seem to make this happen because of nesting
>> issues. �I feel like this must be a known problem... am I missing
>> something obvious?

There's no silly question.

First, no top-post!

Then, why a macro?  This processing can be done perfectly well in a
function.  Even if eventually you want to use this feature from a
macro, it should still be implemented as a function, for the
modularity and ease of debugging.

Now, to answer to your question, notice that #\` and #\, are bound to
reader macros, and that their "expansion" (what is returned by the
reader macro) actually is implementation dependant.  Some
implementation will print back these implementation specific operators
as backquote and comma; for example, in clisp:

C/USER1[73]> '`(a ,b c)
`(A ,B C)

Then you could use these implementation specific operators on the
implementations that have them and do the right thing with them:

C/USER1[76]> (first '`(a b c))
SYSTEM::BACKQUOTE
C/USER1[79]> (second '`(,a ,@b c))
((SYSTEM::UNQUOTE A) (SYSTEM::SPLICE B) C)
C/USER1[80]> 

-- 
__Pascal Bourguignon__
From: basman
Subject: Re: macro for substituting variables in an expression tree
Date: 
Message-ID: <7b04a868-36ab-4e56-a0ca-5c4dee60075a@d45g2000hsc.googlegroups.com>
>
> Now, to answer to your question, notice that #\` and #\, are bound to
> reader macros, and that their "expansion" (what is returned by the
> reader macro) actually is implementation dependant.  Some
> implementation will print back these implementation specific operators
> as backquote and comma; for example, in clisp:
>
> C/USER1[73]> '`(a ,b c)
> `(A ,B C)
>
> Then you could use these implementation specific operators on the
> implementations that have them and do the right thing with them:
>
> C/USER1[76]> (first '`(a b c))
> SYSTEM::BACKQUOTE
> C/USER1[79]> (second '`(,a ,@b c))
> ((SYSTEM::UNQUOTE A) (SYSTEM::SPLICE B) C)
> C/USER1[80]>
>
> --
> __Pascal Bourguignon__


Hmm ok.  It is still a bit unsatisfying to have to use an
implementation-specific way.  But I guess it's unavoidable given that
backquote and comma are implementation-dependent reader macros?
- Bhaskara
From: basman
Subject: Re: macro for substituting variables in an expression tree
Date: 
Message-ID: <7f7ff695-3b69-48c6-9eaa-992f087804c8@l42g2000hsc.googlegroups.com>
On May 20, 9:24 am, basman <········@gmail.com> wrote:
> > Now, to answer to your question, notice that #\` and #\, are bound to
> > reader macros, and that their "expansion" (what is returned by the
> > reader macro) actually is implementation dependant.  Some
> > implementation will print back these implementation specific operators
> > as backquote and comma; for example, in clisp:
>
> > C/USER1[73]> '`(a ,b c)
> > `(A ,B C)
>
> > Then you could use these implementation specific operators on the
> > implementations that have them and do the right thing with them:
>
> > C/USER1[76]> (first '`(a b c))
> > SYSTEM::BACKQUOTE
> > C/USER1[79]> (second '`(,a ,@b c))
> > ((SYSTEM::UNQUOTE A) (SYSTEM::SPLICE B) C)
> > C/USER1[80]>
>
> > --
> > __Pascal Bourguignon__
>
> Hmm ok.  It is still a bit unsatisfying to have to use an
> implementation-specific way.  But I guess it's unavoidable given that
> backquote and comma are implementation-dependent reader macros?
> - Bhaskara

To expand further on my question, is there some reason why backquote
and comma are not handled like quote in ANSI CL - by having special
forms (backquote X) and (comma X) that they expand to?
- Bhaskara
From: Pascal Costanza
Subject: Re: macro for substituting variables in an expression tree
Date: 
Message-ID: <69g35rF30p175U1@mid.individual.net>
basman wrote:
> On May 20, 9:24 am, basman <········@gmail.com> wrote:
>>> Now, to answer to your question, notice that #\` and #\, are bound to
>>> reader macros, and that their "expansion" (what is returned by the
>>> reader macro) actually is implementation dependant.  Some
>>> implementation will print back these implementation specific operators
>>> as backquote and comma; for example, in clisp:
>>> C/USER1[73]> '`(a ,b c)
>>> `(A ,B C)
>>> Then you could use these implementation specific operators on the
>>> implementations that have them and do the right thing with them:
>>> C/USER1[76]> (first '`(a b c))
>>> SYSTEM::BACKQUOTE
>>> C/USER1[79]> (second '`(,a ,@b c))
>>> ((SYSTEM::UNQUOTE A) (SYSTEM::SPLICE B) C)
>>> C/USER1[80]>
>>> --
>>> __Pascal Bourguignon__
>> Hmm ok.  It is still a bit unsatisfying to have to use an
>> implementation-specific way.  But I guess it's unavoidable given that
>> backquote and comma are implementation-dependent reader macros?
>> - Bhaskara
> 
> To expand further on my question, is there some reason why backquote
> and comma are not handled like quote in ANSI CL - by having special
> forms (backquote X) and (comma X) that they expand to?

Because it's hard to get the details right.

See http://citeseer.ist.psu.edu/bawden99quasiquotation.html


Pascal

-- 
1st European Lisp Symposium (ELS'08)
http://prog.vub.ac.be/~pcostanza/els08/

My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: John Thingstad
Subject: Re: macro for substituting variables in an expression tree
Date: 
Message-ID: <op.ubgm5noeut4oq5@pandora.alfanett.no>
P� Tue, 20 May 2008 15:31:48 +0200, skrev basman <········@gmail.com>:

> On May 20, 9:24 am, basman <········@gmail.com> wrote:
>> > Now, to answer to your question, notice that #\` and #\, are bound to
>> > reader macros, and that their "expansion" (what is returned by the
>> > reader macro) actually is implementation dependant.  Some
>> > implementation will print back these implementation specific operators
>> > as backquote and comma; for example, in clisp:
>>
>> > C/USER1[73]> '`(a ,b c)
>> > `(A ,B C)
>>
>> > Then you could use these implementation specific operators on the
>> > implementations that have them and do the right thing with them:
>>
>> > C/USER1[76]> (first '`(a b c))
>> > SYSTEM::BACKQUOTE
>> > C/USER1[79]> (second '`(,a ,@b c))
>> > ((SYSTEM::UNQUOTE A) (SYSTEM::SPLICE B) C)
>> > C/USER1[80]>
>>
>> > --
>> > __Pascal Bourguignon__
>>
>> Hmm ok.  It is still a bit unsatisfying to have to use an
>> implementation-specific way.  But I guess it's unavoidable given that
>> backquote and comma are implementation-dependent reader macros?
>> - Bhaskara
>
> To expand further on my question, is there some reason why backquote
> and comma are not handled like quote in ANSI CL - by having special
> forms (backquote X) and (comma X) that they expand to?
> - Bhaskara

See the apendix of CLTL2 for a example implementation of backquote.
http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node367.html#SECTION003600000000000000000
The problem is that these operations sometimes get optimized away. The  
behaviour is specified, but the implementation is free to change the  
operations performed to improve efficiency.

--------------
John Thingstad