Re: Nested bacquotes are so hard (at least for me :) )!
- From: Kaz Kylheku <kkylheku@xxxxxxxxx>
- Date: Fri, 22 Aug 2008 05:27:46 +0000 (UTC)
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.
.
- Follow-Ups:
- Re: Nested bacquotes are so hard (at least for me :) )!
- From: Pascal J. Bourguignon
- Re: Nested bacquotes are so hard (at least for me :) )!
- References:
- Nested bacquotes are so hard (at least for me :) )!
- From: rock69
- Re: Nested bacquotes are so hard (at least for me :) )!
- From: rock69
- Re: Nested bacquotes are so hard (at least for me :) )!
- From: Kenny
- Re: Nested bacquotes are so hard (at least for me :) )!
- From: rock69
- Re: Nested bacquotes are so hard (at least for me :) )!
- From: rock69
- Nested bacquotes are so hard (at least for me :) )!
- Prev by Date: Re: Nested bacquotes are so hard (at least for me :) )!
- Next by Date: Re: Nested bacquotes are so hard (at least for me :) )!
- Previous by thread: Re: Nested bacquotes are so hard (at least for me :) )!
- Next by thread: Re: Nested bacquotes are so hard (at least for me :) )!
- Index(es):
Relevant Pages
|
|