metadata on function objects

61 views
Skip to first unread message

Brian Marick

unread,
Oct 11, 2011, 8:13:16 PM10/11/11
to clo...@googlegroups.com
In 1.2.x, functions defined with defn had metadata attached:

user=> (meta odd?)
{:ns #<Namespace clojure.core>, :name odd?, :file "clojure/core.clj", :line 1093, :arglists ([n]), :added "1.0", :doc "Returns true if n is odd, throws an exception if n is not an integer"}

In 1.3, this metadata is missing:

user=> (meta odd?)
nil

The previous behavior was useful. I made use of it. Is it a bug that it's gone away? If not, what's the reasoning behind the change?

-----
Brian Marick, Artisanal Labrador
Now working at http://path11.com
Contract programming in Ruby and Clojure
Occasional consulting on Agile


Sean Corfield

unread,
Oct 11, 2011, 8:20:30 PM10/11/11
to clo...@googlegroups.com
On Tue, Oct 11, 2011 at 5:13 PM, Brian Marick <mar...@exampler.com> wrote:
> In 1.3, this metadata is missing:
>
> user=> (meta odd?)
> nil

user=> (meta #'clojure.core/odd?)
{:ns #<Namespace clojure.core>, :name odd?, :arglists ([n]), :added
"1.0", :static true, :doc "Returns true if n is odd, throws an
exception if n is not an integer", :line 1323, :file
"clojure/core.clj"}
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/
Railo Technologies, Inc. -- http://www.getrailo.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

Brian Marick

unread,
Oct 11, 2011, 8:22:52 PM10/11/11
to clo...@googlegroups.com

On Oct 11, 2011, at 7:20 PM, Sean Corfield wrote:
> user=> (meta #'clojure.core/odd?)
> {:ns #<Namespace clojure.core>, :name odd?, :arglists ([n]), :added
> "1.0", :static true, :doc "Returns true if n is odd, throws an
> exception if n is not an integer", :line 1323, :file
> "clojure/core.clj"}

I understand that. Useful code is sometimes given a function object to work with, not a Var.

Sean Corfield

unread,
Oct 11, 2011, 8:25:34 PM10/11/11
to clo...@googlegroups.com
On Tue, Oct 11, 2011 at 5:22 PM, Brian Marick <mar...@exampler.com> wrote:
> I understand that. Useful code is sometimes given a function object to work with, not a Var.

Ah, I get your point now...

What about:

(meta (var odd?))

(meta (resolve 'odd?))

Stuart Sierra

unread,
Oct 11, 2011, 8:48:49 PM10/11/11
to clo...@googlegroups.com
I suppose you could iterate over all known Vars and construct a map from fns to the Vars that contain them. Then, given a fn, you can look up the Var and get its metadata. It would break if anyone redefines or binds the Var, of course.

-S

Brian Marick

unread,
Oct 11, 2011, 8:53:10 PM10/11/11
to clo...@googlegroups.com

On Oct 11, 2011, at 7:48 PM, Stuart Sierra wrote:

> I suppose you could iterate over all known Vars and construct a map from fns to the Vars that contain them. Then, given a fn, you can look up the Var and get its metadata. It would break if anyone redefines or binds the Var, of course.

How about putting the information back on the function? Who would be harmed by reverting back to old behavior?

Chas Emerick

unread,
Oct 11, 2011, 9:22:05 PM10/11/11
to clo...@googlegroups.com

On Oct 11, 2011, at 8:53 PM, Brian Marick wrote:

>
> On Oct 11, 2011, at 7:48 PM, Stuart Sierra wrote:
>
>> I suppose you could iterate over all known Vars and construct a map from fns to the Vars that contain them. Then, given a fn, you can look up the Var and get its metadata. It would break if anyone redefines or binds the Var, of course.
>
> How about putting the information back on the function? Who would be harmed by reverting back to old behavior?

Much of the information in var metadata is just not applicable to the function — and, in the presence of binding and with-redefs, you want to be sure to keep function and var metadata distinct. IIRC, the application of function/var metadata changed when functions became eligible for "updating" via with-meta.

That said, it seems like there are some bits of var metadata that should migrate to the underlying function. Probably worth filing a bug for it.

- Chas

Sam Ritchie

unread,
Oct 11, 2011, 9:39:27 PM10/11/11
to clo...@googlegroups.com
I remember not really understanding the way defn hung metadata off of its functions. In 1.2, it returned different responses on successive calls to defn. for example:

user> (clojure-version)
"1.2.1"
user> (defn my-func "a docstring!" [x] x)
#'user/my-func
user> (meta #'my-func) ;; var first
{:ns #<Namespace user>, :name my-func, :file "NO_SOURCE_FILE", :line 1, :arglists ([x]), :doc "a docstring!"}
user> (meta my-func) ;; function value, before re-defn
{:ns #<Namespace user>, :name my-func}
user> (defn my-func "a docstring!" [x] x)
#'user/my-func
user> (meta my-func) ;; function value after defn the second time
{:ns #<Namespace user>, :name my-func, :file "NO_SOURCE_FILE", :line 1, :arglists ([x]), :doc "a docstring!"} 

1.3 is at least consistent:

user> (clojure-version)
"1.3.0"
user> (defn my-func "a docstring!" [x] x)
#'user/my-func
user> (meta #'my-func)
{:arglists ([x]), :ns #<Namespace user>, :name my-func, :doc "a docstring!", :line 1, :file "NO_SOURCE_FILE"}
user> (meta my-func)
nil
user> (defn my-func "a docstring!" [x] x)
#'user/my-func
user> (meta my-func)
nil


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en



--
Sam Ritchie, Twitter Inc
@sritchie09

(Too brief? Here's why! http://emailcharter.org)

Alan Malloy

unread,
Oct 11, 2011, 10:15:21 PM10/11/11
to Clojure
This. Metadata on functions in 1.2 was mostly accidental, from what I
can tell.

David Nolen

unread,
Oct 11, 2011, 10:36:50 PM10/11/11
to clo...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages