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.

Reply via email to