Re: All the ways to define metadata (and ^:static)

198 views
Skip to first unread message

Andy Fingerhut

unread,
Jan 9, 2013, 4:03:48 AM1/9/13
to clo...@googlegroups.com

On Jan 9, 2013, at 12:37 AM, wujek....@gmail.com wrote:

> Hi. I am currently learning clojure, which is a nice experience, but you all know that.
> I have question about certain metadata definitions, which I couldn't find a straight answer to on the net, and in none of the books I'm reading:
> 1. is ^:dynamic the same as ^{:dynamic true}, just a shortcut?

Yes.

> 2. is (def ^:dynamic ^:blah x) the same as (def ^{:dynamic true :blah true} x)?

Yes.

> My tests show that the answer to the first 2 questions is yes, but I can't seem to find anything that would back that up.

I don't know where else this might be documented, other than the Clojure source code, but one place is on the Clojure cheatsheet, in the section called Metadata, subsection "Abbrevs" for "Abbreviations":

http://clojure.org/cheatsheet
http://jafingerhut.github.com

There you will also see that ^String is an abbreviation for ^{:tag String}, and in general ^Type for ^{:tag Type}

> 3. why so many ways to do the same?

Clojure developers thought it would be nice to have shorter ways to write metadata expressions that simply set a key's value to true, or annotated the type, since those are quite common cases.

I am not sure about the answers to the questions below off-hand. Hopefully someone else can address them.

Andy


> 4. what does ^:static do? I read on SO that it is not used any more, but the source code in clojure.core still has these, and various tutorials use them as well.
> 5. since when does one need to use ^:dynamic on vars to be able to use (binding [...]) to rebind them thread-locally? Clojure in Action has a nice example of a simple mocking framework that uses this feature but without dynamic, but it is about clj 1.2 I think. 1.3 seems to require it though.
>
> Regards,
> wujek

Wujek Srujek

unread,
Jan 9, 2013, 4:08:05 AM1/9/13
to clo...@googlegroups.com
Thanks. Yes, I know about ^String being ^{:tag String} because it is mentioned all over the place. ^:dynamic is not. Thanks for the links, I haven't seen them before, and they do clear this issue up.


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

Philip Potter

unread,
Jan 9, 2013, 9:24:40 AM1/9/13
to clo...@googlegroups.com
On 9 January 2013 08:37, <wujek....@gmail.com> wrote:
> 4. what does ^:static do? I read on SO that it is not used any more, but the source code in clojure.core still has these, and various tutorials use them as well.

This SO thread seems to describe it well:
http://stackoverflow.com/questions/7552632/what-does-static-do-in-clojure

Is there anything you're still unsure about?

> 5. since when does one need to use ^:dynamic on vars to be able to use
> (binding [...]) to rebind them thread-locally? Clojure in Action has a nice
> example of a simple mocking framework that uses this feature but without
> dynamic, but it is about clj 1.2 I think. 1.3 seems to require it though.

You're quite right, this changed in 1.3. It's even the first entry in
the 1.3 changelog:

https://github.com/clojure/clojure/blob/clojure-1.3.0/changes.txt

which reads:

1.1 Earmuffed Vars are No Longer Automatically Considered Dynamic

The old convention was that vars surrounded with *earmuffs* were
automatically considered dynamic and appropriate for a (binding [...])
form. Now, everything must be explicitly made dynamic using ^:dynamic.

Phil

Wujek Srujek

unread,
Jan 9, 2013, 10:17:18 AM1/9/13
to clo...@googlegroups.com
So take this definition from master:
(def
 ^{:arglists '([x])
   :doc "Return true if x implements ISeq"
   :added "1.0"
   :static true}
 seq? (fn ^:static seq? [x] (instance? clojure.lang.ISeq x)))

static is used twice here. What is / was the difference? Is it correct to say that it is now just noise in the code and could be stripped away? Is it correct to say it has nothing to do with 'dynamic', contrary to what the last SO post in the topic you linked to implies?

wujek


Aaron Cohen

unread,
Jan 9, 2013, 10:19:54 AM1/9/13
to clo...@googlegroups.com
Just to be pedantic: in the past, ALL vars were dynamic, regardless of earmuffs. There was a short period of time during the change of the default where vars named with earmuffs were treated as if they had ^:dynamic metadata (and they spit out a warning to developers that this behavior was temporary).

Aaron Cohen

unread,
Jan 9, 2013, 10:32:25 AM1/9/13
to clo...@googlegroups.com
On Wed, Jan 9, 2013 at 10:17 AM, Wujek Srujek <wujek....@gmail.com> wrote:
So take this definition from master:
(def
 ^{:arglists '([x])
   :doc "Return true if x implements ISeq"
   :added "1.0"
   :static true}
 seq? (fn ^:static seq? [x] (instance? clojure.lang.ISeq x)))

static is used twice here. What is / was the difference? Is it correct to say that it is now just noise in the code and could be stripped away? Is it correct to say it has nothing to do with 'dynamic', contrary to what the last SO post in the topic you linked to implies?

^:static really had/has nothing to do with ^:dynamic. It was an experiment Rich was doing to improve performance by generating a static Class method as opposed to an instance of IFn. So, ^:static here is referring to the static keyword from Java.

The ^:static metadata had to be there during the definition of the function itself for the compiler to know to emit a static method, so the first ":static true" in your example is unnecessary. If it wasn't there though, during runtime (:static (meta #'seq)) would be nil which might be confusing.

Those hoops are only necessary because defn hasn't been defined yet at that point of core.clj.

--Aaron

Stuart Sierra

unread,
Jan 9, 2013, 3:12:55 PM1/9/13
to clo...@googlegroups.com
> 4. what does ^:static do?

Nothing. It's leftover from an old experiment in the Clojure compiler.

-S

Andy Fingerhut

unread,
Jan 9, 2013, 4:30:54 PM1/9/13
to clo...@googlegroups.com
Is there any chance a patch to remove all the obsolete :static keywords from Clojure's core.clj would be accepted? Or perhaps there isn't much point in doing so?

I've removed :static as an example keyword in the Metadata section of the latest Clojure cheatsheet published here:

http://jafingerhut.github.com

The version at http://clojure.org/cheatsheet will be updated some time later -- after Clojure 1.5 is released and I've added new 1.5 symbols to it would be a good time.

Andy
Reply all
Reply to author
Forward
0 new messages