Stefan Kamphausen <ska2...@googlemail.com> writes:

> On Nov 8, 3:46 am, Alex Osborne <a...@meshy.org> wrote:
> As far as the documentation says, Vars can't have metadata:
>
> "Symbols and collections support metadata," -- http://clojure.org/metadata
>
> "Symbols, Lists, Vector, Sets and Maps can have metadata" --
> http://clojure.org/reader

I don't think the documentation is *wrong* per se, it just only seems to
cover the immutable types.  Vars, refs, atoms, agents and namespaces can
all have metadata as well, but it works a little differently for them as they
are mutable.  You change their metadata using the alter-meta!
function.  The with-meta function will not work on them.

> Really? Then why the metadata of the symbol empty?
> user=> (meta 'greet)
> nil
>
> Or am I not accessing the symbol's metadata that way?

You are creating a new symbol 'greet, which doesn't have metadata.
Symbols are immutable types, you can't alter them and you can't alter
their metadata.  Instead what you do is create a new symbol with
metadata attached.

It might make more sense if we consider the case of metadata on
collections.  I can create a new empty vector with metadata using either
#^ or with-meta:

  (meta (with-meta [] {:foo true})) ; => {:foo true}
  (meta #^{:foo true} [])           ; => {:foo true}

Having done so doesn't change the original empty vector "[]", as vectors
are immutable:

  (meta []) ; => nil

The same is true for symbols:

  (meta (with-meta 'greet {:a 1})) ; => {:a 1}
  (meta 'greet) ; => nil

Note that (perhaps suprisingly) this doesn't work:

  (meta #^{:a 1} 'greet) ; => {:a 1}

Why?  Well because #^ attaches the metadata to the next read form.
What's the next read form?  It's 'greet.  But in fact 'greet is just
sugar for (quote greet).  So we're actually affixing the metadata to a
list containing two symbols (quote and greet).  When the compiler
evaluates (quote greet) it turns it into just the symbol greet and then
throws the list (and thus our metadata) away.

> * What part of the (Java)-code should I read to understand the
> implementation of metadata (if I assume that my understanding of how
> the classes extent/implement is not correct).

I think you are just being confused by the differences in how metadata
works with mutable and immutable types.

There are three interfaces to do with metadata:

IMeta.java       meta -- reading metadata
IObj.java        with-meta -- "changing" metadata on immutables
IReference.java  alter-meta! reset-meta! -- changing metadata on mutables

For the immutable types the implementation is in Obj.java.  For mutables
it is in AReference.java.

I hope that helps clarify things a bit.

Alex

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