What is the design guideline for =?

88 views
Skip to first unread message

Warren Lynn

unread,
Oct 20, 2012, 3:54:19 PM10/20/12
to clo...@googlegroups.com
With Clojure 1.4, I see this:

(defrecord AA [a])
(= (AA. 1) {:a 1})         => false
(= [1 2] '(1 2))             => true

Another thread mentioned the second case. So if the second case is true, I thought the first one should be true too (different concrete type, but same data).I am quite confused. Is there any design guideline that can help me understand the behavior above? Thanks.

AtKaaZ

unread,
Oct 20, 2012, 4:00:54 PM10/20/12
to clo...@googlegroups.com
=> (.equals (AA. 1) {:a 1} )
true
=> (= (AA. 1) {:a 1} )
false
=> (.equals {:a 1} (AA. 1) )
true
=> (= {:a 1} (AA. 1) )
false

Looks like "=" is not ".equals", hmm... but this doc says different: http://clojuredocs.org/clojure_core/clojure.core/=
Equality. Returns true if x equals y, false if not. Same as
Java x.equals(y) except it also works for nil, and compares
numbers and collections in a type-independent manner. Clojure's immutable data
structures define equals() (and thus =) as a value, not an identity,
comparison.



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



--
I may be wrong or incomplete.
Please express any corrections / additions,
they are encouraged and appreciated.
At least one entity is bound to be transformed if you do ;)

Brian Goslinga

unread,
Oct 20, 2012, 7:02:02 PM10/20/12
to clo...@googlegroups.com
When records were first introduced there was a little debate over what the behavior of first case should be. If = is defined solely in terms of .equals then two different records with the same key/value mappings must [1] be = to each other to obey the contract of the Map interface even though the values are likely meant to be conceptually distinct. For instance if you had (defrecord Square [length color]) and (defrecord Rope [length color]), then you would have (= (Square. 1 :red) (Rope. 1 :red)) even though a red square is not the same thing as red rope.

To work around the issue, = was changed to be in terms of equiv (see the definitions in [2]). This allows compliance with the Map interface and prevents (= (Square. 1 :red) (Rope. 1 :red)).

[1] One idea was to have a hidden key corresponding to the record's type be visible when using the Map interface; that would cause a great deal of complexity and was rejected.

Warren Lynn

unread,
Oct 20, 2012, 8:00:26 PM10/20/12
to clo...@googlegroups.com

To work around the issue, = was changed to be in terms of equiv (see the definitions in [2]). This allows compliance with the Map interface and prevents (= (Square. 1 :red) (Rope. 1 :red)).

[1] One idea was to have a hidden key corresponding to the record's type be visible when using the Map interface; that would cause a great deal of complexity and was rejected.


I see. This does make sense for record. Thanks. I just wish the decision were consistent and so case two would be false too. All these inconsitencies here and there are adding to the mental burden which we hope to reduce when we come to LISP in the first place.
 
Reply all
Reply to author
Forward
0 new messages