Closed Mercerenies closed 2 years ago
Closed by 0f87968. There are now two equality functions in GDLisp.
=
behaves just like the built-in equality operator ==
in GDScript. It compares numbers, strings, and arrays for equality (recursively checking =
on arrays), and objects for reference equality. It also works on Symbol
as of #28. Note that it will fail if given values of different types. Like GDScript, arrays of different types (PoolIntArray
vs Array
, for instance) cannot be compared using this operator. Integers will compare equal to their floating-point equivalent.equal?
works like =
on numbers and strings. On arrays, dictionaries, and Cons
cells, it recursively calls equal?
. On other types, it still uses reference equality. equal?
will hang forever on cyclic data. equal?
will return false without error if given values of different types. Arrays of different types will still compare element-wise, and integers will compare equal to their floating-point equivalent.a |
b |
= |
equal? |
---|---|---|---|
1 |
1 |
true | true |
1 |
1.0 |
true | true |
1 |
"1" |
error | false |
nil |
nil |
true | true |
[1] |
[1] |
true | true |
{'a 1} |
{'a 1} |
false | true |
'('a 1) |
'('a 1) |
false | true |
['(1)] |
['(1)] |
false | true |
((literally PoolIntArray) [0]) |
[0] |
error | true |
Currently, we have one equality operator:
=
.=
simply compiles blindly to the Godot==
equality operator, which works well enough on numbers and strings. It also seems to work on arrays but not dictionaries for some reason. Most importantly, it's not extensible for custom classes, so it doesn't work on user-defined classes, or cons cells, or even symbols.We need proper equality operators in GDLisp. First, let's take a look at the way other languages do it.
On the one side, we have other recent multiple-dispatch languages like Julia.
==
is a multimethod in Julia (like every function), which has, at least on my version of the interpreter, 155 overloads. We could heavily overload our existing=
once we have #11.On the other extreme, Common Lisp has no fewer than five equality operators for different purposes.
eq
compares pointers and is guaranteed to work correctly on symbols.eql
expandseq
to work on numbers and characters.=
is a numerical-only comparison operator that ignores type (so(eql 0 0.0)
is false but(= 0 0.0)
is true.equal
works likeeql
but also traverses arrays and lists recursively for value equality.equalp
generalizesequal
even more, looking for structural equality on arbitrary structures and hash tables. And that's not even to mention the type-specific equality operators such aschar=
,char-equal
,string=
,string-equal
.Needless to say, there's likely a balance to be struck between the two extremes. I'd love to have a multimethod implementation efficient enough to support Julia's approach, but I'm not confident that that's the reality of the situation.