An off-by-one error in attaching metadata to functions defined with defn

3 views
Skip to first unread message

Michał Marczyk

unread,
Feb 7, 2010, 9:27:29 PM2/7/10
to clo...@googlegroups.com
Apparently the fn objects constructed with defn will have attached to
them the metadata which was attached to the Var named by the `name'
symbol in the defn form *prior* to the evaluation of defn form -- or
else the metadata of a freshly created Var when the Var did not exist
previously.

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.

Simply switching the if(initProvided) and if(meta != null) around
seems to produce some weird error, though, and my Java-fu is
regrettably too limited for me to be able to suggest a solution. :-(

Please find below a sample interaction at the REPL illustrating the
above (quoted from my earlier answer to Ludovic Kuty).

Sincerely,
Michał

> 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> (x)
> 5
> user> (meta x)
> {:ns #<Namespace user>, :name x, :file "NO_SOURCE_FILE", :line 1, :foo "bar"}
> user> (meta #'x)
> {:ns #<Namespace user>, :name x, :file "NO_SOURCE_FILE", :line 1,
> :arglists ([])}

Reply all
Reply to author
Forward
0 new messages