I've read what he has to say about backquotes, but he really doesn't
give as clear and concise a method for figuring out what's going on as
Graham does.

To evaluate a backquoted expression, you remove the outermost
backquote and each matching ~, and replace the expression following
each matching ~ with its value. Evaluating an expression that begins
with a ~ causes an error.

A ~ matches a backquote if there are the same number of ~ as
backquotes between them. This means that in a well-formed expression
the outermost backquote matches the innermost ~s.

THE ABOVE LAST STATEMENT IS CRUCIAL IN UNDERSTANDING HOW IT WORKS!

Suppose that x evaluates to say user/a, which evaluates to 1; and that
y evaluates to user/b, which evaluates to 2.

You can set this up pretty easily like this:

(def x `a)
(def a 1)
(def y `b)
(def b 2)

Evaluating the follwing expression

``(w ~x ~~y)

gives:

`(user/w ~user/x ~user/b)

Actually, what the REPL will print out is:

(clojure.core/seq (clojure.core/concat (clojure.core/list (quote user/
w)) (clojure.core/list user/x) (clojure.core/list user/b)))

But it's the SAME THING! ;)

Now evaluate again, and of course what you get is:

(user/w user/a 2)

A piece of cake ;)


Rock





On Aug 11, 11:07 pm, rob <r.p.l...@gmail.com> wrote:
> Let Over Lambda by Hoyte contains a very lucidly well-written
> discussion of quotation levels in macros.  It also includes a pretty
> useful technique for being explicit about variable capture.  The code
> is in Common Lisp, but will mostly only differ syntactically from the
> Clojure code (for the basic example, I mean).  There is one non-
> trivial difference to implement for use in Clojure, which is that
> Lisp-1 versus Lisp-2 requires being concerned about capture of
> function names as well, but as indicated in the text this is a simple
> modification to make.
>
> On Aug 11, 1:21 pm, Rock <rocco.ro...@gmail.com> wrote:
>
> > For nested backquotes, Paul Graham in ANSI Common Lisp gives the
> > clearest explanation. He makes it look almost trivial. As a matter of
> > fact, once you get the hang of it, it's not at all that complicated.
>
> > I've pretty much verified that what he says concerning CL backquotes
> > applies perfectly to Clojure as well. The only difference is that you
> > have to remember that in Clojure, backquotes can *resolve* unqualified
> > symbols too (which is actually powerful and cool). So no problem
> > there.
>
> > Rock
>
> > On Aug 11, 6:00 pm, Jonathan Smith <jonathansmith...@gmail.com> wrote:
>
> > > For the sake of contradicting myself, in this paper Alan Bawden
> > > explains quasi-quote much better than I can.
>
> > >https://eprints.kfupm.edu.sa/60346/1/60346.pdf
>
> > > Note the explanation towards the end of defmacro and constructs such
> > > as ',' (in clojure I believe it would be '~' )
>
> > > Also note that Clojure has the added wrinkle of namespace
> > > qualification.
>
> > > On Aug 11, 1:31 am, Jonathan Smith <jonathansmith...@gmail.com> wrote:
>
> > > > On Aug 10, 3:20 pm, Dragan Djuric <draga...@gmail.com> wrote:
>
> > > > > For example:
>
> > > > > (defmacro creator [param]
> > > > >  `(defmacro created [p] `(the code...)) ;; note the nested quote...
> > > > > how to resolve that? any examples?
>
> > > > Although I wouldn't cite my own code as a necessarily *good* or easy
> > > > to understand example, I'll pimp it anyway as it is written and
> > > > already on the net...
>
> > > >http://github.com/JonathanSmith/CRIB/blob/89a3f4d9c797ef6f4e4f456001f...
>
> > > > A macro is exactly the same as a function, except it has special
> > > > evaluation rules.
> > > > You'll notice that in what I posted, I only use defmacro once,
> > > > everything else is a function that returns a list
>
> > > > (I've found that this gives me extra flexibility later on when I want
> > > > to continue extending the macro-metaphor... (or if I happen to want to
> > > > do runtime definition of certain things, I can swap out the macro for
> > > > a function call and an 'eval')).
>
> > > > You'll also notice that syntax quote qualifies every symbol that it is
> > > > passed.
> > > > Your particular example wouldn't work, because you can't define a name-
> > > > space qualified symbol. There are two ways that you could circumvent
> > > > this.
> > > > 1.) use regular old list
> > > > (list 'defmacro 'created ['p] `(code ...))
>
> > > > 2a.) Escape and quote certain things:
>
> > > > `(defmacro ~'created [p#] `(code goes here..))
>
> > > > or
>
> > > > 2b.) `(defmacro ~'created [p#]  ~(fn-that-returns-your-code p# and
> > > > probably some args and stuff))
>
> > > > or
>
> > > > 2c.)
> > > > (let [fn-that-generates-expansion
> > > >             (code-to-generate-a-fn-that-generates-an-expansion)]
> > > > `(defmacro ~'created [p#] (~fn-that-generates-expansion p#)))
>
> > > > You don't actually need to use nested backquote* (For anything**,
> > > > AFAIK), I tend to avoid it because I think it makes the code fairly
> > > > unreadable (yes, more unreadable than what I posted). I normally use a
> > > > helper function and pass the arguments (similar to a foo and foo-1
> > > > function when doing recursion).
>
> > > > ---------------------
> > > > * backquote == syntaxquote
>
> > > > ** I think I used nested backquotes one time in common lisp for
> > > > something, but I can't remember *why* it was necessary, in particular.
> > > > I think it is the case where you want to pass a symbol from one macro-
> > > > environment to the next, say generating a bunch of accessors...
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to