Zach Tellman's potemkin library includes several useful ways to tweak
deftypes and defrecords.  I wish Clojure itself provided more ways to do
this, but in the meantime, potemkin is the best way to create something
custom, like a deftype that behaves mostly like defrecord with some
different hashing and equality behavior.

On Thu, Jun 11, 2015 at 11:36 AM, Mars0i <marsh...@logical.net> wrote:

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

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

Reply via email to