I think that the following is all correct, but I could be wrong about something.
The datatypes page at clojure.org <http://clojure.org/datatypes> says: "defrecord provides ... value-based equality and hashCode", while deftype does not. So (defrecord Rec [x]) (= (Rec. 42) (Rec. 42)) ;=> true but (deftype Typ [x]) (= (Typ. 42) (Typ. 42)) ;=> false. This also means, as I understand it, that data structures that use hashing--maps and sets, for example--hash on value for records, but on identity for types. I believe that the same is true when Java hashtables compare records, or compare types, although I haven't carefully tested this. It makes sense that the primary, most fully functional user-definable datatypes in Clojure should use value-based equality; that's fully in the spirit of a functional language, and is very convenient in many contexts, and hashing should follow the equality semantics of the datatypes. You can always use identical? if you want to test records for identity rather than equality. However, you can't tell maps and sets to use identity for records, afaik. This makes records undesirable if you only care about identity, and need to use a data structure that uses hashing, and care about performance, because value-based hashing is presumably a lot slower than identity-based hashing (which is what my experiments seem to show). On the other hand, records are obviously way, way, more convenient than types in many contexts because the functionality provided by deftype is so bare-bones. It really bothers me that I have to choose between speed and using convenient, idiomatic functionality (defrecord) that is one of several significant reasons that I love Clojure. (This is in an application in which value-based equality would *never* be what I wanted for my datatypes.) Should there be an alternative? Either a way to define e.g. a special kind of set that uses identity rather than value for records, or a way to make records use identity for equality, or another datatype that's just like defrecord but ..., or a way to get more functionality with deftype, or ...? (I don't think that Clojure should include every option or functionality that someone thinks might be convenient in some context. Another reason that I love Clojure is that it *doesn't* do that, but instead provides limited, well-thought out options that allow a lot of flexibility.) In an earlier thread <https://groups.google.com/forum/#!topic/clojure/EdjnSxRkOPk>, Stephen Yi pointed out that although you're allowed to override some Object methods in defrecord, you can't override Object.equals and Object.hashCode. It isn't documented, but the compiler throws an exception if you try it. That makes quite a bit of sense, since changing the meaning of equality for a datatype would be an easy way to introduce confusing bugs. On the other hand, if you do override Object.equals and Object.hashCode for defrecord, you probably know that you're doing something weird, and that you'd better take precautions, if necessary, to avoid later confusion. -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.