freenode/#lisp - IRC Chatlog
Search
21:17:48
Nilby
My opinion is if you're typing into a REPL where a docstring isn't a keypress away you are losing much productivity.
21:19:27
dbotton__
Already noted down now the difference for the future, but now looking to see what was the reason that was chosen, in particular since different behavior for list, string and array
21:21:37
dbotton__
I understand why the ranges of equality have a place, but why would equal's author choose a such a difference with arrays vs strings
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