3 ms·
Each equality function, at least in Common Lisp, has a distinct goal. Numbers use = if you don't care about type. For instance, the real number 0 and the compl
by koito17 2y ago
Each equality function, at least in Common Lisp, has a distinct goal.
Numbers use = if you don't care about type. For instance, the real number 0 and the complex number 0 + 0i would be treated equal by this function.
Do you care about strict pointer equality? eq.
Do you want to distinguish 0 and 0d0? eql.
Do you care about isomorphism? equal.
The only weird function to me would be equalp, given that it performs case-insensitive comparison of characters etc. Overall, I find complaints about the equality predicates to be based on a misunderstanding of the definition of "equality".
Clojure goes the opposite direction and has a single = function that performs all sorts of reflection and deep comparisons; it's convenient in practice, but it's also easy to burn CPU cycles if you are e.g. comparing large collections and only care about pointer equality.
- DonHopkins 2y agoProof that Brendan Eich never really cared about equality. https://www.reddit.com/r/ProgrammerHumor/comments/225i15/proof_that_brendan_eich_never_really_cared_about/ https://www.reddit.com/r/ProgrammerHumor/comments/225i15/pro... (To contextualize and clarify: It's a classic old JavaScript joke about how Brendan Eich hates gay people getting married so much that he donated money to a political campaign against marriage equality, even though he enjoys the human right of marriage himself. Some bigots think they are more equal than others.)
- otabdeveloper4 2y agoMarriage isn't a human right. Just ask any "men's rights" activist.
- DonHopkins 2y agoWho cares what they think?
- shadowgovt 2y ago> Overall, I find complaints about the equality predicates to be based on a misunderstanding of the definition of "equality". It's more that LISP is the only language I know that exposes how complex the concept of equality actually is. All the other ones I use more-or-less make an implicit assumption that equality means one of the things that LISP offers but if you want the other definitions of equality you either have to build support for them by hand or call out to a library function that's going to use (static or dynamic) reflection to reduce the problem to the one kind of equality the language implements. (Apart from that, the only other complaint is that LISP being as old as it is, the default names for those equalities are too terse to self-describe. You just have to memorize which one is 'eq' and which one is 'eql', there's no way to guess looking at the names themselves).
- kazinator 2y agoCommon Lisp doesn't do a very good job, unfortunately. [1]> (equal '(1 2 3) '(1 2 3)) T [2]> (equal "abc" "abc") T [3]> (equal #(1 2 3) #(1 2 3)) NIL [4]> (subtypep 'string 'vector) T ; T So a string is formally a kind of vector according to t he type system itself, but vectors don't use equal comparison whereas strings do. We can reach for equalp: [1]> (equalp #(1 2 3) #(1 2 3)) T But then we have to accept, something we might not necessarily want: [2]> (equalp #(1 2 3) #(1 2 3.0)) T which will not be true under the equal function that we really wanted to Just Work for simple vectors: [3]> (equal '(1 2 3) '(1 2 3.0)) NIL eql being the default equality function throughout the library is also suboptimal. The specification allows (eq 1 1) to be false, which caters to unrealistically poor implementations such as ones that heap-allocate all integers. This, in spite of the fact that fixnum is required to be at least 16 bits wide: most-positive-fixnum must be at least 32767, and the fixnum type must be a supertype of (signed-byte 16). What this means is that if Common Lisp were fit into a 16 bit machine (good luck with that at all), it would have to provide 16 bit fixnums (easily doable, but not unboxed ones) which defeats the fixnum concept of fixnums being the unboxed range of integers, beyond which we have boxed bignums.
- koito17 2y agovectors don't use equal comparison whereas strings do This behavior is required by the specification. From https://www.lispworks.com/documentation/HyperSpec/Body/f_equal.htm https://www.lispworks.com/documentation/HyperSpec/Body/f_equ... , Two arrays are equal only if they are eq, with one exception: strings and bit vectors are compared element-by-element (using eql). What makes strings and bit vectors special, in my opinion, is that they are homogeneous arrays. Heterogeneous arrays aren't something that I often use outside of Clojure (usually because they are awkward to use in statically typed languages). The specification allows (eq 1 1) to be false Because the specification doesn't limit the magnitude of numbers nor state how they should be stored in memory. The scenario you've described requires an implementation that intentionally makes every number a bignum or an instance of a class (like Smalltalk).
- kazinator 2y ago