From: Elliott Slaughter
Subject: Backquote at Macro-expansion Time
Date: 
Message-ID: <27132f7c-b443-4ba4-b9b9-ff781fc8c0d0@w34g2000prm.googlegroups.com>
Hi everyone,

For one of my projects, I would like to be able to make a macro which
wraps an expression in a backquote. In an imaginary implementation,
the macro (called wrap) would work as follows:

> (defvar x 'a)
> (wrap x)
X
> (wrap ,x)
A

In Arc (which is currently implemented in Scheme), I would write the
above macro as such:

arc> (= x 'a)
b
arc> (mac wrap (expr) (list 'quasiquote expr))
#3(tagged mac #<procedure>)
arc> (wrap x)
x
arc> (wrap ,x)
a

But since there is no standard English name for backquote in CL, I
can't make backquote an argument to list. To an extent, I can get
around this is some implementations, which provide an internal
backquote macro which seems to do what I want. For example, in CLISP,
I can

[2]> (defvar x 'a)
X
[3]> (defmacro wrap (expr) (list 'system::backquote expr))
WRAP
[4]> (wrap x)
X
[5]> (wrap (system::unquote x))
A

But watch what happens when I try to use the comma syntax for unquote:

[8]> (wrap ,x)
*** - READ: comma is illegal outside of backquote

It seems that even CLISP, which provides backquote and unquote macros,
attempts (and in the above case fails) to resolve backquote and comma
syntax at read-time.

I have not done a thorough examination of other implementations but my
understanding is that the situation is more or less the same (at least
with respect to read-time expansion of backquote).

This is rather annoying since I don't want to type system::unquote
inside calls to my macro. I also would rather not leave the expression
unquoted and force myself to type quotes all over the place. I suppose
I could attempt to redefine comma as a read-macro expanding to a
system::unquote, but I don't know if CL would allow me to redefine a
basic part of the language like the comma, or if it would be safe to
do so even if it were possible.

So then, is it possible to accomplish what I want in CL? (Is it
possible to do it portably, or failing that, do with read-time
conditionals such that the user of my macro wouldn't notice the
difference? And which implementations would this be doable under?) If
it is possible, what is the best method to accomplish this? If not,
why not?

If anyone could provide suggestions, insights, or other information
about working with backquote, I would really appreciate it.

From: Kaz Kylheku
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <18b40d03-b6d9-4f29-ab42-24ca0cb7207c@x35g2000hsb.googlegroups.com>
On 5$B7n(B26$BF|(B, $B8aA0(B7:50, Elliott Slaughter <················@gmail.com>
wrote:
> Hi everyone,
>
> For one of my projects, I would like to be able to make a macro which
> wraps an expression in a backquote.

This is not possible in a portable way in Common Lisp, where the
backquote is specified purely as a read syntax, which may be expanded
as early as read-time. There is no standard-defined representation of
a backquote form as some kind of ordinary expression. The reader
itself may simply return the generated code which implements the
behavior of the backquote.

 In an imaginary implementation,
> the macro (called wrap) would work as follows:
>
> > (defvar x 'a)
> > (wrap x)
> X
> > (wrap ,x)
> A

A comma with no matching backquote is an error in CL.

The behavior of the above WRAP can be obtained simply by using the
backquote:

  `x  ->  X
  `,x ->  A

So WRAP is not particularly useful. What may be useful is the ability
to stick the expression into a larger backquote, so that for instance
(wrap ,x) is equivalent to, say, `(,y ,x).

A lot of this type of stuff can be done with doubly-nested backquotes.

Since you can't have dangling commas, consider designing the syntax
around the idea that the backquote fragment is closed by a backquote,
i.e.:

  (wrap `,x)

The idea is that WRAP will ``strip off'' the outer backquote and
``splice'' the rest into another backquote.

  (defmacro wrap (expr)
    ``(,y ,,expr)))

  (let ((x 1) (y 2)) (wrap `x))  ->  (2 X)

  (let ((x 1) (y 2)) (wrap `,x))  -> (2 1)

Suppose you want to handle splices as well. The problem is that `,@x
is invalid, but we can write WRAP so that it ``strips off'' the
backquote as well as the outer list, and splices the enclosed
expressions into the target backquote. I.e.

  (wrap `(,x ,z)) <==> `(,y ,x ,z))

This is how:

  (defmacro wrap (expr)
    ``(,y ,@,expr)))

  (let ((x 1) (y 2)) (wrap `(x))) -> (2 X)

  (let ((x 1) (y 2) (z 3)) (wrap `(x z))) -> (2 X Z)

  (let ((x 1) (y 2) (z 3)) (wrap `(,x ,z))) -> (2 1 3)

So the effect is as if WRAP were merging two backquotes together:

  `(,y) + `(x z) -> `(,y x z)

  `(,y) + `(,x ,z) -> `(,y ,x ,z)

> But watch what happens when I try to use the comma syntax for unquote:
>
> [8]> (wrap ,x)
> *** - READ: comma is illegal outside of backquote

This is a deliberate check in CLISP. A lone comma could simply be
allowed to generate the SYSTEM::UNQUOTE form. Instead, CLISP's reader
establishes a special variable which tracks that a backquote is being
read. If the comma reader is invoked and finds that a backquote isn't
being read, it signals the above error.

> It seems that even CLISP, which provides backquote and unquote macros,
> attempts (and in the above case fails) to resolve backquote and comma
> syntax at read-time.

Of course the read syntax has to be resolved at read-time to some
extent. CLISP resolves it in a minimal way; the backquote is
transliterated into a macro call very similar to Scheme quasiquote.
The macro then does the rest of the expansion.
From: Elliott Slaughter
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <e9f7e23c-9ba4-43d4-b993-f1837e6621c0@s21g2000prm.googlegroups.com>
On May 25, 4:33 pm, Kaz Kylheku <········@gmail.com> wrote:
> This is not possible in a portable way in Common Lisp, where the
> backquote is specified purely as a read syntax, which may be expanded
> as early as read-time. There is no standard-defined representation of
> a backquote form as some kind of ordinary expression. The reader
> itself may simply return the generated code which implements the
> behavior of the backquote.

If this can't work portably for all implementations, can anyone offer
information on which implementations it might work on? (That is, which
implementations provide a macro which could be used to force backquote
expansion at compile-time, like CLISP's system::backquote?)

> The behavior of the above WRAP can be obtained simply by using the
> backquote:
>
>   `x  ->  X
>   `,x ->  A
>
> So WRAP is not particularly useful.

Yes, the example was contrived. What I am actually trying to do is
allow the user of my macro (which isn't entirely trivial on its own)
to unquote arbitrary sections of code so they are evaluated prior to
parsing the rest of the code (this is necessary because the
unevaluated code gets piped to another Lisp process which may not have
the right environment to evaluate certain sections of code).

> What may be useful is the ability
> to stick the expression into a larger backquote, so that for instance
> (wrap ,x) is equivalent to, say, `(,y ,x).
>
> A lot of this type of stuff can be done with doubly-nested backquotes.
>
> Since you can't have dangling commas, consider designing the syntax
> around the idea that the backquote fragment is closed by a backquote,
> i.e.:
>
>   (wrap `,x)
>
> The idea is that WRAP will ``strip off'' the outer backquote and
> ``splice'' the rest into another backquote.
>
>   (defmacro wrap (expr)
>     ``(,y ,,expr)))
>
>   (let ((x 1) (y 2)) (wrap `x))  ->  (2 X)
>
>   (let ((x 1) (y 2)) (wrap `,x))  -> (2 1)

But (wrap `,x) isn't really any different from just (wrap x), right?
And (wrap `x) is the same as (wrap 'x). So you really aren't saving
any syntax over just using quotes everywhere to protect against
evaluation, and the extra backquotes really obscure the code.

Since for my macro, more values would have to be quoted than left
unquoted, I wanted to introduce an implicit backquote to save the user
typing and improve readability. Previously I had the entire body
quoted, but I found some errors where I really did want certain parts
of the code evaluated. And since the parts that required evaluation
might be nested very deeply in the &body section of the macro call,
adding an explicit backquote would obscure the code more than
anything.

> This is a deliberate check in CLISP. A lone comma could simply be
> allowed to generate the SYSTEM::UNQUOTE form. Instead, CLISP's reader
> establishes a special variable which tracks that a backquote is being
> read. If the comma reader is invoked and finds that a backquote isn't
> being read, it signals the above error.

Does the check necessarily need to be a read-time check?
system::unquote still fails outside of system::backquote even without
read-time checks. What do you lose if this check is done at macro-
expansion time?

> Of course the read syntax has to be resolved at read-time to some
> extent. CLISP resolves it in a minimal way; the backquote is
> transliterated into a macro call very similar to Scheme quasiquote.
> The macro then does the rest of the expansion.

If you wanted to perform backquote expansion at macro-expansion time
rather than read-time, would system::backquote and system::unquote in
CLISP (or their equivalents in other implementations) be sufficient to
accomplish this? (I'm not saying it would necessarily be the Right
Thing, but would it be possible?)

Thanks for your insights.

--
Elliott Slaughter

"Any road followed precisely to its end leads precisely nowhere." -
Frank Herbert
From: Pascal J. Bourguignon
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <7cprr9h1bv.fsf@pbourguignon.anevia.com>
Kaz Kylheku <········@gmail.com> writes:

> On 5月26日, 午前7:50, Elliott Slaughter <················@gmail.com>
> wrote:
>> Hi everyone,
>>
>> For one of my projects, I would like to be able to make a macro which
>> wraps an expression in a backquote.
>
> This is not possible in a portable way in Common Lisp, where the
> backquote is specified purely as a read syntax, which may be expanded
> as early as read-time. There is no standard-defined representation of
> a backquote form as some kind of ordinary expression. The reader
> itself may simply return the generated code which implements the
> behavior of the backquote.

This is very possible in portable Common Lisp.
Since #\, is a reader macro, you will have to resolve it with reader macros.

You could override both #\` and #\, reader macros.

Your #\,  reader macro would read the optional ··@ and a sexp and
return your own forms:  

  ,toto  --> (my-backquote:comma    toto)
  ,@toto --> (my-backquote:comma-at toto)

Your #\'  reader macro would set put back the normal reader macros,
unread the backquote and let them do their normal work.  Something like:

(lambda (stream ch)
  (let ((*readtable* (readtable-with-normal-backquote-comma *readtable*)))
     (unread ch stream)
     (read stream)))

> [...]
> Of course the read syntax has to be resolved at read-time to some
> extent. CLISP resolves it in a minimal way; the backquote is
> transliterated into a macro call very similar to Scheme quasiquote.
> The macro then does the rest of the expansion.

-- 
__Pascal Bourguignon__
From: Elliott Slaughter
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <3c277239-8c42-4d8a-b957-933b1eebb600@l17g2000pri.googlegroups.com>
On May 26, 2:16 am, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> Kaz Kylheku <········@gmail.com> writes:
> > On 5$B7n(B26$BF|(B, $B8aA0(B7:50, Elliott Slaughter <················@gmail.com>
> > wrote:
> >> Hi everyone,
>
> >> For one of my projects, I would like to be able to make a macro which
> >> wraps an expression in a backquote.
>
> > This is not possible in a portable way in Common Lisp, where the
> > backquote is specified purely as a read syntax, which may be expanded
> > as early as read-time. There is no standard-defined representation of
> > a backquote form as some kind of ordinary expression. The reader
> > itself may simply return the generated code which implements the
> > behavior of the backquote.
>
> This is very possible in portable Common Lisp.
> Since #\, is a reader macro, you will have to resolve it with reader macros.
>
> You could override both #\` and #\, reader macros.
>
> Your #\,  reader macro would read the optional ··@ and a sexp and
> return your own forms:
>
>   ,toto  --> (my-backquote:comma    toto)
>   ,@toto --> (my-backquote:comma-at toto)
>
> Your #\'  reader macro would set put back the normal reader macros,
> unread the backquote and let them do their normal work.  Something like:
>
> (lambda (stream ch)
>   (let ((*readtable* (readtable-with-normal-backquote-comma *readtable*)))
>      (unread ch stream)
>      (read stream)))

Thanks for the information. I actually found a 20 year-old
implementation of backquote by Guy Steele which seems to work this
way. http://lib.store.yahoo.net/lib/paulgraham/glsbq.lisp
From: Kent M Pitman
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <uy75xc845.fsf@nhplace.com>
···@informatimago.com (Pascal J. Bourguignon) writes:

> Your #\'  reader macro would set put back the normal reader macros,
> unread the backquote and let them do their normal work.  Something like:
> 
> (lambda (stream ch)
>   (let ((*readtable* (readtable-with-normal-backquote-comma *readtable*)))
>      (unread ch stream)
>      (read stream)))

I would be surprised if this turned out to be portable.
Consider:   ,,x
From: Kent M Pitman
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <uzlqcj3ko.fsf@nhplace.com>
Kent M Pitman <······@nhplace.com> writes:

> ···@informatimago.com (Pascal J. Bourguignon) writes:
> 
> > Your #\'  reader macro would set put back the normal reader macros,
> > unread the backquote and let them do their normal work.  Something like:
> > 
> > (lambda (stream ch)
> >   (let ((*readtable* (readtable-with-normal-backquote-comma *readtable*)))
> >      (unread ch stream)
> >      (read stream)))
> 
> I would be surprised if this turned out to be portable.
> Consider:   ,,x

Actually, upon further reflection, I think portability is not the
issue in the example I gave. I'm just not plain sure the technique
will work at all in other that the simplest of cases.

I also wonder about the suggestion of putting this on single-quote 
because single-quote is technically semantic, not syntactic.  That
is, although most people wouldn't do it, and would regard it as
bad style, the following is defined to work:

 (case 'quote
  ('x 'yes)
  (t  'no))
 => YES

So remember that just because QUOTE is in play, it doesn't imply that special
processing of syntax within it should be done, or else you'd have a problem
that (quote something) and 'something did not read the same.

I don't dispute your basic claim that you can override ` and , with your own
macros, I just don't believe quote needs to get involved in this at all.
It sounds like a big mistake to involve it, actually.
From: Pascal J. Bourguignon
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <7cmymcf9u9.fsf@pbourguignon.anevia.com>
Kent M Pitman <······@nhplace.com> writes:

> Kent M Pitman <······@nhplace.com> writes:
>
>> ···@informatimago.com (Pascal J. Bourguignon) writes:
>> 
>> > Your #\'  reader macro would set put back the normal reader macros,
>> > unread the backquote and let them do their normal work.  Something like:
>> > 
>> > (lambda (stream ch)
>> >   (let ((*readtable* (readtable-with-normal-backquote-comma *readtable*)))
>> >      (unread ch stream)
>> >      (read stream)))
>> 
>> I would be surprised if this turned out to be portable.
>> Consider:   ,,x
>
> Actually, upon further reflection, I think portability is not the
> issue in the example I gave. I'm just not plain sure the technique
> will work at all in other that the simplest of cases.
>
> I also wonder about the suggestion of putting this on single-quote 
> because single-quote is technically semantic, not syntactic.  That
> is, although most people wouldn't do it, and would regard it as
> bad style, the following is defined to work:
>
>  (case 'quote
>   ('x 'yes)
>   (t  'no))
>  => YES
>
> So remember that just because QUOTE is in play, it doesn't imply that special
> processing of syntax within it should be done, or else you'd have a problem
> that (quote something) and 'something did not read the same.
>
> I don't dispute your basic claim that you can override ` and , with your own
> macros, I just don't believe quote needs to get involved in this at all.
> It sounds like a big mistake to involve it, actually.

Sorry, I meant backquote of course, not quote.  it should have been #\`
Indeed quote has nothing to do here.

-- 
__Pascal Bourguignon__
From: Kent M Pitman
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <ulk1xfppn.fsf@nhplace.com>
Elliott Slaughter <················@gmail.com> writes:

> For one of my projects, I would like to be able to make a macro which
> wraps an expression in a backquote.

(a) Why do you want to do this?  Although I've heard people want to do this
    over the years, I've never seen a very convincing case.  In the early
    days of Maclisp's backquote, we could do this and it so often led to 
    program error that we took out the capability.  In fact, Maclisp also
    had a variable backquote-expand-when that allowed you to decide when it
    expanded and we found that wasn't really something that was best left
    to users either.  So I'm curious what the use case is that you really
    do want this--I just have never found this to be much of a problem.

(b) Given that you want to do this, why is it not possible to make your
    own readtable and backquote/comma macros, and your own quasiquote and
    unquote and all that?  It's been a while since I looked at this in 
    detail, but I seem to recall that this isn't the world's hardest 
    programming problem.  What seems to be throwing you off is that you
    think you have to use the system one or you're stuck; it seems to me
    that you can just write your own.
From: Kjetil S. Matheussen
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <Pine.LNX.4.58.0805262055440.4292@notam02.uio.no>
On Sun, 25 May 2008, Elliott Slaughter wrote:

> Hi everyone,
> 
> For one of my projects, I would like to be able to make a macro which
> wraps an expression in a backquote. In an imaginary implementation,
> the macro (called wrap) would work as follows:
> 
> > (defvar x 'a)
> > (wrap x)
> X
> > (wrap ,x)
> A
> 
> In Arc (which is currently implemented in Scheme), I would write the
> above macro as such:
> 
> arc> (= x 'a)
> b
> arc> (mac wrap (expr) (list 'quasiquote expr))
> #3(tagged mac #<procedure>)
> arc> (wrap x)
> x
> arc> (wrap ,x)
> a
> 

This is a crazy solution. I don't know common lisp that well,
but I know scheme quite well, and I would think the following
scheme program, which solves this problem, would be possible
to translate to CL quite easely:


(define (supereval func)
  (let* ((filename (tmpnam))
         (fd (open-file filename "w"))
         (ret (rt-gensym)))
    (delete-at-exit filename)
    (display "(define " fd)
    (display ret fd)
    (display " " fd)
    (func (lambda something
            (for-each (lambda (s)
                        (display s fd))
                      something)))
    (display ")\n" fd)
    (close fd)
    (load filename)
    (delete-file filename)
    (primitive-eval ret)))


(define x 'a)

(define-macro (wrap expr)
  `(supereval (lambda (out)
                 (out "`" ',expr))))

(wrap x)
=> x
(wrap ,x)
=> a
From: Elliott Slaughter
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <8796deb4-b8a9-46b3-8ab8-d7955de62a9a@a32g2000prf.googlegroups.com>
On May 26, 12:00 pm, "Kjetil S. Matheussen"
<··············@notam02.no> wrote:
> This is a crazy solution. I don't know common lisp that well,
> but I know scheme quite well, and I would think the following
> scheme program, which solves this problem, would be possible
> to translate to CL quite easely:
>
> (define (supereval func)
>   (let* ((filename (tmpnam))
>          (fd (open-file filename "w"))
>          (ret (rt-gensym)))
>     (delete-at-exit filename)
>     (display "(define " fd)
>     (display ret fd)
>     (display " " fd)
>     (func (lambda something
>             (for-each (lambda (s)
>                         (display s fd))
>                       something)))
>     (display ")\n" fd)
>     (close fd)
>     (load filename)
>     (delete-file filename)
>     (primitive-eval ret)))
>
> (define x 'a)
>
> (define-macro (wrap expr)
>   `(supereval (lambda (out)
>                  (out "`" ',expr))))
>
> (wrap x)
> => x
> (wrap ,x)
> => a

Uh... why do you write to a file? Couldn't you do the same with string
streams?

But besides that, all this string manipulation seems rather like a
hack. One aught not need to do an explicit write and read in order to
accomplish backquote. (Which is why I posted here, I thought there had
to be a simpler solution than the ideas I had for working around CL's
backquote.)
From: Kjetil S. Matheussen
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <Pine.LNX.4.58.0805270059120.4292@notam02.uio.no>
On Mon, 26 May 2008, Elliott Slaughter wrote:

> On May 26, 12:00 pm, "Kjetil S. Matheussen"
> <··············@notam02.no> wrote:
> > This is a crazy solution. I don't know common lisp that well,
> > but I know scheme quite well, and I would think the following
> > scheme program, which solves this problem, would be possible
> > to translate to CL quite easely:
> >
> > (define (supereval func)
> >   (let* ((filename (tmpnam))
> >          (fd (open-file filename "w"))
> >          (ret (rt-gensym)))
> >     (delete-at-exit filename)
> >     (display "(define " fd)
> >     (display ret fd)
> >     (display " " fd)
> >     (func (lambda something
> >             (for-each (lambda (s)
> >                         (display s fd))
> >                       something)))
> >     (display ")\n" fd)
> >     (close fd)
> >     (load filename)
> >     (delete-file filename)
> >     (primitive-eval ret)))
> >
> > (define x 'a)
> >
> > (define-macro (wrap expr)
> >   `(supereval (lambda (out)
> >                  (out "`" ',expr))))
> >
> > (wrap x)
> > => x
> > (wrap ,x)
> > => a
> 
> Uh... why do you write to a file? Couldn't you do the same with string
> streams?
> 

Probably, but that would be really ugly I guess.


> But besides that, all this string manipulation seems rather like a
> hack. One aught not need to do an explicit write and read in order to
> accomplish backquote. (Which is why I posted here, I thought there had
> to be a simpler solution than the ideas I had for working around CL's
> backquote.)
> 

Depends what you need it for. Usually, code doesn't need
to run fast.
From: Elliott Slaughter
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <9a6b3bfe-a5ae-4cd8-9328-3fa9646d3037@p39g2000prm.googlegroups.com>
On May 26, 4:00 pm, "Kjetil S. Matheussen" <··············@notam02.no>
wrote:
> On Mon, 26 May 2008, Elliott Slaughter wrote:
> > On May 26, 12:00 pm, "Kjetil S. Matheussen"
> > <··············@notam02.no> wrote:
> > > This is a crazy solution. I don't know common lisp that well,
> > > but I know scheme quite well, and I would think the following
> > > scheme program, which solves this problem, would be possible
> > > to translate to CL quite easely:
>
> > > (define (supereval func)
> > >   (let* ((filename (tmpnam))
> > >          (fd (open-file filename "w"))
> > >          (ret (rt-gensym)))
> > >     (delete-at-exit filename)
> > >     (display "(define " fd)
> > >     (display ret fd)
> > >     (display " " fd)
> > >     (func (lambda something
> > >             (for-each (lambda (s)
> > >                         (display s fd))
> > >                       something)))
> > >     (display ")\n" fd)
> > >     (close fd)
> > >     (load filename)
> > >     (delete-file filename)
> > >     (primitive-eval ret)))
>
> > > (define x 'a)
>
> > > (define-macro (wrap expr)
> > >   `(supereval (lambda (out)
> > >                  (out "`" ',expr))))
>
> > > (wrap x)
> > > => x
> > > (wrap ,x)
> > > => a
>
> > Uh... why do you write to a file? Couldn't you do the same with string
> > streams?
>
> Probably, but that would be really ugly I guess.

No more ugly than the file method. Both methods involve writing output
and reading it again, just one writes the data to the file system and
one keeps it in memory.

Actually, upon further consideration, I don't think either method will
work, because when most CL's see the expression

(wrap ,x)

they immediately (at read-time that is) check the comma is inside a
backquote. This doesn't occur in Scheme because #\` and #\, are
converted to quasiquote and unquote, which complete the
transformations at macro-expansion time, but in CL, this
transformation could occur at read-time, before CL even knows wrap is
a macro. As Pascal J. Bourguignon said, you really need to redefine
those characters as read-macros on your own custom quasiquotation
macros. (For an example of such a system, see
http://lib.store.yahoo.net/lib/paulgraham/glsbq.lisp .)

> > But besides that, all this string manipulation seems rather like a
> > hack. One aught not need to do an explicit write and read in order to
> > accomplish backquote. (Which is why I posted here, I thought there had
> > to be a simpler solution than the ideas I had for working around CL's
> > backquote.)
>
> Depends what you need it for. Usually, code doesn't need
> to run fast.

I am not concerned with execution speed. I just don't think one should
involve the reader and writer when all that is involved are code
transformations that could be accomplished with macros.
From: Jens Axel Soegaard
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <483b17b2$0$15894$edfadb0f@dtext01.news.tele.dk>
Kjetil S. Matheussen skrev:
> On Sun, 25 May 2008, Elliott Slaughter wrote:
> 
>> Hi everyone,
>>
>> For one of my projects, I would like to be able to make a macro which
>> wraps an expression in a backquote. In an imaginary implementation,
>> the macro (called wrap) would work as follows:
>>
>>> (defvar x 'a)
>>> (wrap x)
>> X
>>> (wrap ,x)
>> A
>>
>> In Arc (which is currently implemented in Scheme), I would write the
>> above macro as such:
>>
>> arc> (= x 'a)
>> b
>> arc> (mac wrap (expr) (list 'quasiquote expr))
>> #3(tagged mac #<procedure>)
>> arc> (wrap x)
>> x
>> arc> (wrap ,x)
>> a
>>
> 
> This is a crazy solution. I don't know common lisp that well,
> but I know scheme quite well, and I would think the following
> scheme program, which solves this problem, would be possible
> to translate to CL quite easely:
> 
> 
> (define (supereval func)
>   (let* ((filename (tmpnam))
>          (fd (open-file filename "w"))
>          (ret (rt-gensym)))
>     (delete-at-exit filename)
>     (display "(define " fd)
>     (display ret fd)
>     (display " " fd)
>     (func (lambda something
>             (for-each (lambda (s)
>                         (display s fd))
>                       something)))
>     (display ")\n" fd)
>     (close fd)
>     (load filename)
>     (delete-file filename)
>     (primitive-eval ret)))
> 
> 
> (define x 'a)
> 
> (define-macro (wrap expr)
>   `(supereval (lambda (out)
>                  (out "`" ',expr))))
> 
> (wrap x)
> => x
> (wrap ,x)
> => a

I might be missing something in the original post,
but why is the following not sufficient?

(define-syntax wrap
   (syntax-rules (unquote)
     [(wrap (unquote var)) var]
     [(wrap var)           'var]))

(define x 'a)

(wrap x)   ; => x
(wrap ,x)  ; => a


-- 
Jens Axel S�gaard
From: Elliott Slaughter
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <3e41b60a-57d9-4e4e-9abf-fb06d4117df8@a9g2000prl.googlegroups.com>
On May 26, 1:04 pm, Jens Axel Soegaard
<·························@soegaard.net> wrote:
> Kjetil S. Matheussen skrev:
>
>
>
> > On Sun, 25 May 2008, Elliott Slaughter wrote:
>
> >> Hi everyone,
>
> >> For one of my projects, I would like to be able to make a macro which
> >> wraps an expression in a backquote. In an imaginary implementation,
> >> the macro (called wrap) would work as follows:
>
> >>> (defvar x 'a)
> >>> (wrap x)
> >> X
> >>> (wrap ,x)
> >> A
>
> >> In Arc (which is currently implemented in Scheme), I would write the
> >> above macro as such:
>
> >> arc> (= x 'a)
> >> b
> >> arc> (mac wrap (expr) (list 'quasiquote expr))
> >> #3(tagged mac #<procedure>)
> >> arc> (wrap x)
> >> x
> >> arc> (wrap ,x)
> >> a
>
> > This is a crazy solution. I don't know common lisp that well,
> > but I know scheme quite well, and I would think the following
> > scheme program, which solves this problem, would be possible
> > to translate to CL quite easely:
>
> > (define (supereval func)
> >   (let* ((filename (tmpnam))
> >          (fd (open-file filename "w"))
> >          (ret (rt-gensym)))
> >     (delete-at-exit filename)
> >     (display "(define " fd)
> >     (display ret fd)
> >     (display " " fd)
> >     (func (lambda something
> >             (for-each (lambda (s)
> >                         (display s fd))
> >                       something)))
> >     (display ")\n" fd)
> >     (close fd)
> >     (load filename)
> >     (delete-file filename)
> >     (primitive-eval ret)))
>
> > (define x 'a)
>
> > (define-macro (wrap expr)
> >   `(supereval (lambda (out)
> >                  (out "`" ',expr))))
>
> > (wrap x)
> > => x
> > (wrap ,x)
> > => a
>
> I might be missing something in the original post,
> but why is the following not sufficient?

If you are reading this from comp.lang.scheme, then know that the
question regarded accomplishing this in Common Lisp.

> (define-syntax wrap
>    (syntax-rules (unquote)
>      [(wrap (unquote var)) var]
>      [(wrap var)           'var]))
>
> (define x 'a)
>
> (wrap x)   ; => x
> (wrap ,x)  ; => a

And anyways, does this work for arbitrarily nested expressions? e.g.
(wrap (foo (bar (baz ,x))))
From: Luís Oliveira
Subject: Re: Backquote at Macro-expansion Time
Date: 
Message-ID: <87abiaxnv2.fsf@deadspam.com>
Elliott Slaughter <················@gmail.com> writes:

> If anyone could provide suggestions, insights, or other information
> about working with backquote, I would really appreciate it.

cl-quasi-quote might be useful for your purposes:
<http://common-lisp.net/project/cl-quasi-quote/>

-- 
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/