Thanks for the explanation All.  I have a much better grasp of what's going on 
now. 

Just one more question: It is defined behavior, or should I submit a patch for 
Clojure 1.3?

Micah

On Oct 20, 2011, at 7:55 PM, Chouser wrote:

> 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

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