On Thu, Oct 20, 2011 at 4:31 PM, Chris Perkins <chrisperkin...@gmail.com> wrote:
> Note: I forgot to preface that with "I think..." :)  Upon experimenting
> briefly, it turns out I was wrong about how Clojure works (that seems to
> happen a lot with me).  A declare/def defines a var even when it's not
> executed!
> user> (defn xxx [] (declare yyy))
> #'user/xxx
> user> yyy
> #<Unbound Unbound: #'user/yyy>
> Well, I learned something today.
But it only interns the Var, it doesn't fully set it up.  Particularly
relevant to the OP's example is that the metadata from the name symbol
is not transferred to the Var (and the changes to the Var based on
:dynamic are not applied) until runtime for the 'def', even though the
Var exists at compile time.

Here's a macro that expands at compile time to the *compile* time
metadata of the var named in its argument:

(defmacro compile-time-meta [x] (meta (resolve x)))

Now observe how it behaves differently than a runtime call to 'meta':

(vector
  (declare ^:dynamic *myvar*)
  (meta #'*myvar*)
  (compile-time-meta #'*myvar*)))

The above returns:

[#'user/*myvar*
 {:ns #<Namespace user>, :name *myvar*, :dynamic true, :declared true, ...}
 {:ns #<Namespace user>, :name #<Unbound Unbound: #'user/*myvar*>}]

First is the Var itself.
Next is the metadata of the Var at runtime, after the entire form has
been compiled and therefore the metadata from the name has been
applied to the Var, including the :dynamic flag.
Finally we see that when our macro was expanded the Var existed but
had minimal metadata.  This was after the declare was compiled but
before any part of the 'vector' form was run.  There is no :dynamic
flag, and anything that depends on that flag at compile time to work
correctly (such as a function that refers the for Var) will fail to
work correctly.

--Chouser

-- 
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