Details
-
Type:
Defect
-
Status:
Open
-
Resolution: Unresolved
-
Affects Version/s: None
-
Fix Version/s: Approved Backlog
-
Component/s: None
-
Labels:None
Description
- What (small set of) steps will reproduce the problem?
user> (def #^{:foo "bar"} x 5)
#'user/x
user> (meta #'x)
{:ns #<Namespace user>, :name x, :file "NO_SOURCE_FILE", :line 1, :foo "bar"}
user> (defn x [] 5)
#'user/x
user> (meta #'x)
{:ns #<Namespace user>, :name x, :file "NO_SOURCE_FILE", :line 1, :arglists ([])}
user> (meta x)
{:ns #<Namespace user>, :name x, :file "NO_SOURCE_FILE", :line 1, :foo "bar"}
- What is the expected output? What do you see instead?
I expect (meta #'x) to evaluate to the value of the final (meta x) in the above.
- What version are you using?
Current master (commit 61202d2ff6925002400a9843e8fbd080f3bef3a5).
- Was this discussed on the group? If so, please provide a link to the discussion.
Prompted by discussion at
- Initial attempt at a diagnosis:
I think this is due to DefExpr's eval method binding the Var to init.eval() first and attaching the supplied metadata to the Var later – see Compiler.java lines 341-352. (Note the Var is always already in place when init.eval() is called, regardless of whether it existed prior to the evaluation of the def / defn.) Thus the init expression supplied by defn sees the old (and wrong) metadata on the Var.