Re: Nested bacquotes are so hard (at least for me :) )!



On 2008-08-21, rock69 <rocco.rossi@xxxxxxxxx> wrote:
On Aug 21, 5:02 pm, rock69 <rocco.ro...@xxxxxxxxx> wrote:
On Aug 21, 4:27 pm, Kenny <kentil...@xxxxxxxxx> wrote:



rock69 wrote:
On Aug 21, 3:58 pm, rock69 <rocco.ro...@xxxxxxxxx> wrote:

Tinkering a little, I've just discovered that it expands correctly by
replacing ,,@body with ,',@body which seems logical of course :) yet
it still requires one more evaluation step. In other words, it works
only if I replace the invocation (ntimes 10 (format t "Hello World!~
%")) with (eval (ntimes 10 (format t "Hello World!~%"))) which is of
course a ridiculous thing to have to do, so I'm still pretty much
stuck, only a little closer maybe to the solution.

rock69 wrote:

I was doing some experimenting with MACROLET, just to figure out how
it works a little better, but I can't get the following code to work.
It only prints "Hello World!" once instead of 10 times. There's no
specific goal for this code. I was just experimenting for learning
purposes only.

(macrolet ((with-ps-gensyms ((&rest names) &body body)
                      `(let ,(loop for n in names collect `(,n (gensym)))
                         ,@body))
     (ntimes (n &rest body)
             `(with-ps-gensyms (g h)
                               `(let ((,h ,,n))
                                  (do ((,g 0 (+ ,g 1)))
                                      ((>= ,g ,h))
                                      ,,@body)))))
    (ntimes 10 (format t "Hello World!~%")))

OK, I got it all wrong. It turns out I didn't need nested backquotes
in the first place. This works fine:

(defmacro ntimes (n &rest body)
                   `(with-ps-gensyms (g h)
                                     (let ((,h ,n))
                                        (do ((,g 0 (+ ,g 1)))
                                            ((>= ,g ,h))
                                            ,@body))))

Looks like I've got some more studying to do :)

Does anyone know where I can find some really extensive info on
backquote syntax? I've seen the HyperSpec, On Lisp, and ANSI Common
Lisp, but it still feels like something's missing. Mr. Pitman help,
please.

Do what I do, just keep adding and removing quotes and ticks and commas
and moving them around at the same time until it works. This is where
the monkeys really earn their bananas. Sometimes I break stuff out into
a second macro just to keep my sanity. When it gets depressing, just
remember, you could be trying to use Scheme to do macros. When you are
ready to kill yourself, use F#.

hth, kenny

:) Yeah, I guess it really is just a matter of trial and error. Like
Graham says, it's like trying to figure out a complex integral by just
looking at it.

F# no way! LOL

Now this REALLY puzzles me. Going back to the previous version and
feeding it to SBCL this is what I get:

(macrolet ((with-ps-gensyms ((&rest names) &body body)
`(let ,(loop for n in names collect `(,n (gensym)))
,@body))
(ntimes (n &rest body)
`(with-ps-gensyms (g h)
`(let ((,h ,',n))
(do ((,g 0 (+ ,g 1)))
((>= ,g ,h))
,',@body)))))
(ntimes 10 (format t "Hello World!~%")))

OUTPUT:

(LET ((#:G605 10))
(DO ((#:G604 0 (+ #:G604 1)))
((>= #:G604 #:G605))
(FORMAT T "Hello World!~%")))

Like I said, it doesn't get evaluated, but the expansion appears to be
correct. Why doesn't it continue and evaluate it instead of stopping
at this point???

Because it has already done the required number of evaluation rounds.

Your macro produced the code (WITH-PS-GENSYMS (G H) `(LET ((,H ,10)) ...)).

This expression was substituted in place of the macro.

And this expression's action is to construct the list (LET ((#:G05 10) ...).
It sets up bindings for variables G and H, giving them a pair of gensyms as
initial values, and then it evaluates the inner backquote `(LET ((,H ,10)) ...
etc ...). This backquote produces (LET ((#:G05 10)) ...) which is your
output.

Lisp doesn't have built-in ``do what I mean'' logic which would automatically
recognize that the newbie programmer's expression has produced data which looks
like Lisp code that maybe ought to be evaluated.

If you wanted it evaluated, why did you stick an extra level of backquote in
front of it? Backquote is a lot like regular quote: it suppresses evaluation.
You didn't get the evaluation you wanted because you explicitly put in a
backquote to suppress it.

The expression `(LIST 1 2) produces (LIST 1 2), just like '(LIST 1 2) does. If
you want to produce (1 2) then evaluate the expression (LIST 1 2), with no
quoting.

All you have to do is strip the outer backquote from your expression. Drop the
` from before (WITH-PS-GENSYMS ...), keeping the one before the inner (LET ...)
and then remove all occurences of ,' (comma quote) so that ,',@body becomes
,@body, et cetera.
.



Relevant Pages

  • Re: Macro misunderstandings: 5 hours experience with lisp
    ... Long story short, I am teaching myself Lisp and have gotten stuck on something that, to me, does not make sense. ... If you wish to make a macro that expands to multiple forms, you'll need to wrap them in a PROGN or something similar. ... the evaluation of the in the line calling the macro, and the first should be the result of the print function in the argument supplied by the caller). ...
    (comp.lang.lisp)
  • Re: nested backquoting (newbie) question in Clisp
    ... Graham's ANSI Common Lisp book and have bumped into the following: ... Evaluation is what is done to the output of the backquote. ... backquote is most often used in macro definitions. ...
    (comp.lang.lisp)
  • Re: Setf macro macro
    ... is available at the time of first evaluation, that is, when the outer ... backquote is evaluated.'' (To use the value of r that is available at ... ,@,p means ``the value of p is a form; splice in the value of the ...
    (comp.lang.lisp)
  • Re: Very poor Lisp performance / about Mathematica
    ... > The site uses Mathematica to do its math. ... backquote and comma in CLTL. ... So,,@q means ``the value of q is a list of forms; splice the list ... available at the time of second evaluation, that is, when the ...
    (comp.lang.lisp)
  • Re: nested backquoting (newbie) question in Clisp
    ... we think forward to what the evaluation will ... Evaluation is what is done to the output of the backquote. ... expansion of the backquote. ... for constructing complicated nested lists. ...
    (comp.lang.lisp)