freenode/#lisp - IRC Chatlog
Search
21:44:04
phoe
the specific details of how eq/eql/equal/equalp don't matter from this point of view since even if you had 50 different equality operators then you could still find some place where you'll need a 51st one
22:56:54
phoe
let me ask you this question: is (list 1 2 3) equal to (list 1 2 3)? (and by that I mean the generic English sense, not having them compared by CL:EQUAL)
22:58:46
phoe
if you answer yes, then I say that when I SETF CAR of the first one then the CAR of the other is not modified, hence they must not be equal to one another
22:59:15
phoe
if you answer no, then I say that I can substitute one for the other in a call to e.g. PRINT, or MAPCAR #'1+, hence they must be equal to one another
22:59:28
phoe
aeth: yes, I've mentioned this up above - functional data structures have well-defined equality
23:00:19
phoe
mostly because they no longer have identity that is as meaningful as it would be in non-functional contexts
23:00:20
aeth
although you still get an issue with types, like is 1 equal to 1.0? Well, they're =, but that's because = is defined that way.
23:00:54
aeth
no-defun-allowed: iirc, Scheme permits that (even encourages that?) but that's really, really hard to do.
23:01:18
no-defun-allowed
aeth: What about (lambda (x) (check-type x number) x) and (lambda (x) (- (- x)))?
23:01:21
phoe
comparing functions is a big no-no because then you get into undecidability real quick
23:02:21
aeth
no-defun-allowed: right, that's one of two things I don't like about Scheme's equality rules; the other being that the more advanced equality forms don't use = so (equal? 1 1.0) => #f
23:02:41
phoe
no-defun-allowed: they are not equal, because (- (- x)) is the --x operator from C++ (see the double dash?), hence, it's equivalent to (decf x)
23:09:22
dbotton_
phoe that I understand. The issue I was having once understanding which equality was intended was equal has different forms of equality depending on type
23:11:37
dbotton_
as pointed out it was an arbitrary choice, but still there must have been some reason to do so
23:12:25
dbotton_
between vector and string seems clear to offer equal and equalp as case sensitive or insensitive comparison
23:13:09
phoe
dbotton_: likely this was an effect of the fact that if a predicate applies recursive equality then it applies itself only
23:13:26
phoe
e.g. EQUAL doesn't apply EQL anywhere, other than for the cases where it decays into EQL and/or EQ
23:14:35
phoe
you can define your own equality predicate that works differently, e.g. compares vectors by their size/element type/descends into elements by applying itself and otherwise behaves like EQUAL
23:15:17
phoe
I guess, and only guess, this is for performance reasons and because arrays are not functional data structures like conses
23:15:40
phoe
comparing conses by value makes sense, but comparing arrays by value is not something that is requested as usually as it is for conses
23:16:11
phoe
if you are doing arrays then you are most likely mutating them, so it makes sense to compare mutable data structures by identity first and foremost
23:17:47
aeth
call it trivial-equality... just DEFGENERICs for the built-in data types (there aren't that many) and relying on user code for the rest
23:18:47
aeth
you could also just have a trivial-generics or something; then you could fit in a bunch of other common generics like NAME
23:19:23
aeth
Any NAME that has more than one argument (unless optional/key) is going to break so much code that (defgeneric name (object)) is safe