On 2010 Apr 9, at 9:04 PM, Per Vognsen wrote:
On Sat, Apr 10, 2010 at 7:48 AM, Douglas Philips <d...@mac.com> wrote:
Odd:
user=> (binding [m1 (fn [a b] (println "m1 from binding" a b))]
(eval '(if true (m1 "true" "here") (m1 "false"
"there"))))
m1 from binding true here
m1 from binding false there
nil
That doesn't even run for me on HEAD. But I can guess what's going on
from a small experiment:
?? That was presupposing the defmacro m1 from the earlier email.
I'm running 1.1.0 from macports, not HEAD.
The difference between a function and a macro is a flag in the
metadata flag. Metadata is a feature of the container (the var) rather
than the contents. So when you rebind a var that was created by
defmacro, you retain the macrohood of the root. That means it's
invoking your function as a macro at compile time rather than as a
function at run time.
Now that makes sense. How could I have figured that out from the
documentation?
http://clojure.org/vars says:
Functions defined with defn are stored in Vars, allowing for the re-
definition of functions in a running program. This also enables many
of the possibilities of aspect- or context-oriented programming. For
instance, you could wrap a function with logging behavior only in
certain call contexts or threads.
How macros are distinguished from functions is not revealed by the
docs, so far as I can tell, and no mention is made of being able to
rebind macros, however,
http://richhickey.github.com/clojure/clojure.core-
api.html#clojure.core/defmacro says:
defmacro macro
Usage: (defmacro name doc-string? attr-map? [params*] body)
(defmacro name doc-string? attr-map? ([params*] body) + attr-
map?)
Like defn, but the resulting function name is declared as a
macro and will be used as a macro by the compiler when it is called.
Ok, so another example:
user=> (defmacro foo [] (println "invoking foo") '(list 1 2 3))
#'user/foo
user=> (if true (foo) (foo))
invoking foo
invoking foo
(1 2 3)
so far, so good.
user=> (binding [foo (fn [] (println "binding foo") '(list 4 5 6))]
(if true (foo) (foo)))
invoking foo
invoking foo
(1 2 3)
vs:
user=> (defn foo [] (println "defn foo") '(1 2 3))
#'user/foo
user=> (if true (foo) (foo))
defn foo
(1 2 3)
so somehow defn is doing more than rebinding at the top level; the
docs say:
defn macro
Usage: (defn name doc-string? attr-map? [params*] body)
(defn name doc-string? attr-map? ([params*] body) + attr-map?)
Same as (def name (fn [params* ] exprs*)) or (def
name (fn ([params* ] exprs*)+)) with any doc-string or attrs added
to the var metadata
ok, so no we go see what docs for def say: http://clojure.org/vars
Interning
The Namespace system maintains global maps of symbols to Var
objects (see Namespaces). If a def expression does not find an
interned entry in the current namespace for the symbol being def-ed,
it creates one, otherwise it uses the existing Var. This find-or-
create process is called interning. This means that, unless they have
been unmap-ed, Var objects are stable references and need not be
looked up every time.
Given that definition, shouldn't my defn'ing foo after having
defmacro'd foo have left foo flagged as a macro, since def is reusing
the existing var?
--Doug
--
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
To unsubscribe, reply using "remove me" as the subject.