On Apr 15, 2009, at 13:31, Rich Hickey wrote:

> That's an open question. There are many reasons it is better as a
> normal key. The arguments for being metadata are:
>
> It allows for things other than maps to have 'types'
> It doesn't impact equality
> It doesn't appear as a 'field' to other code
>
> Advantages to having it be a map key/attribute:
>
> That's really what type/class is, another attribute, thus only things
> that have attributes (maps) should have it.
> It will impact equality*
> It will appear as a 'field' to other code, in particular things like
> Datalog
>
> * - a key issue here is that only exact type equality is supported.

I found a couple of situations where a third choice is preferable:  
put type-related information both in the metadata and in the map  
itself. In all these situations, the main reason is the impact on  
equality, and usually the type information in the metadata is not the  
same as the type information in the map itself.

As an example, take algebraic data types as defined in  
clojure.contrib.types. A simple binary tree structure can be defined  
with

(defadt ::tree
   empty-tree
   (leaf value)
   (node left-tree right-tree))

Values of this type are represented as maps in which the value  
associated with :clojure.contrib.types/tag is the constructor (`empty- 
tree, `leaf, or `node), with the :type in the metadata being ::tree.  
This double labelling makes sure that all tree values are recognized  
as being of the same type in dispatching, but also that equality  
tests take into account the constructor in addition to its arguments.

Note that there is no need here to have the type ::tree as part of  
the value, as it is impossible to create two different types with  
identical constructor names in the same namespace (the constructor  
names are interned via def) and both the type tag and the constructor  
names are namespace qualified. The only way to make a data item equal  
to a ::tree value would be to construct explicitly a map containing  
the namespace-qualified key :clojure.contrib.types/tag, which I would  
call a malicious attempt to break something.

In this example, the type information for equality is more specific  
than the type information for dispatching, but there are also  
situations in which the opposite is required. Both are simple to  
implement in Clojure.

Konrad.


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