(eq x y) tests whether x and y are the same object. It is very fast because typically all it has to do is do a machine word comparison, and that comparison is conclusive. (When it is false, there is no more work to do to rule out sameness.)
If x and y are the same number, of the same type, it is not required to report true. Even if they are the the same number that you might think fits into a machine word, though on most implementations that situation will be eq. ANSI Lisp allows for implementations in which small, identical integer values like 7 are not necessarily eq. A Lisp implementation in which all numbers are "boxed" quantities on the heap could be conforming to ANSI.
The eql function is like eq, but the same characters and same numbers of the same type are required to be equal under eql. For all other objects it is like eq. eql might be implemented in terms of doing an eq comparison, and then when that is false, doing more work to rule out sameness of numbers and characters.
Common Lisp's hash tables can use different equalities; that is where it can make a bigger difference. Objects in an eq hash table can use a very simple, fast hashing function. Whereas objects in an eql hash table have to be hashed in such a way that equal integer or floating-point values have the same hash. A value that is a pointer to a boxed bignum integer has to be dereferenced to access some of the value bits of that object.
There are some exotic functions in Lisp that you might never end up using, particularly in the list processing area like pairlis or revappend and whatnot.
My overall point is two-fold. (1) There is nothing in the function name that would indicate the difference between, say, (eq) and (eql) and (equal), any more than you could guess what the difference between (colorise), (clrise) and (clrs) would be on sight. Lisp seems to love doing this. To me, it just seems like an obvious source of very painful bugs (works as expected 99% of the time and then it doesn't).
(2) In many (most?) day-to-day cases, the distinction isn't material, and for those the ecosystem is going to end up preferring one more than the others (which may change over time - hence, 'in vogue'). The references I've seen tend to suggest sticking to (eq) and (equal), for instance, and avoiding (eql) unless you have specific need of it.
For a language that is reputed to be elegant and beautiful, this - well, isn't that. Hence my initial surprise.
What alternative would you suggest?
Giving paragraph-length names to the functions? Common Lisp already has some of the more descriptive function names around and they can be inconvenient if the function is used often. (By the way, there is something that helps to remember what those functions do: shorter names are correlated with more primitive and restrictive checks.)
Having a single function that performs different checks depending on a parameter? If you don’t know which function to use you don’t know which parameter to use either.
Removing the ability to perform different kinds of checks entirely?
I've found their comments, and the constructive responses to them, interesting because I am interested in Lisp but have never learned it.
What I don't find interesting is seeing troad's observations strongly challenged, as you are doing, as if somehow by sharing their observations, they now owe us detailed solutions as well.
It's not cool.
It's a backwards compat breakage, but there is a mechanism in the language which helps with such situations.
txr -C 237
or setting the TXR_COMPAT environment variable to 237 or lower will restore the destructive behavior of sort and shuffle. People who don't want to fix their code can deploy that way.I hate compatibility breaking changes, but it was a real thorn in my side how sort is destructive without any indication in its name, in a language where destructive versions of functions should be separately named.
Now the thing is that sort is not required to be destructive. It is allowed to be. Therefore code written to the language spec will not break if sort becomes pure. But we have to worry about breaking all programs though, not just programs written to the spec. (Unless we are GCC maintainers; different rules apply.) You can't just say, "Oh, programs that call sort on a vector and ignore the return value, expecting the vector to be sorted, are just nonportable junk; let them break."
Generally in Common lisp we have EQ, EQL, EQUAL, EQUALP -> from the most specific to the most general. The most specific has the shortest name: https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node74.html
EQL is actually often used, since it is also the default equality test in Common Lisp. For example the named TEST argument has the default EQL. That information is slightly hidden. Example: (find 1 '(2 3 2 1 3)) is the same as (find 1 '(2 3 2 1 3) :test 'eql) , since EQL is the default test. One can pass a different equality test predicate, if needed.
Some background about naming and equality operators in Lisp: http://www.nhplace.com/kent/PS/EQUAL.html
Other languages for example use some of =, ==, ===, is, ... what may the difference be?
There were many different naming conventions in Lisp over the decades. One was, as mentioned above, the more specific/primitive operators have shorter names. Later (70s/80s, Lisp got a lot more operators and at some point there were operators with long names introduced. This was not liked by everyone, since one needed to type longer names - completion was often new then (or slow).
For example CLOS was added end 80s. Thus it uses names like UPDATE-INSTANCE-FOR-DIFFERENT-CLASS, instead of UPDINSTC ;-) .
Generally, a good Lisp IDE should make getting the documentation (and source code) for any operator easy.
I guess they suggest two instead of one because in most cases the difference is material. And I imagine that they also suggest using = to compare numbers.
When the distinction doesn’t matter one could just use eq. I’m not sure that this covers most uses though.
The family of functions whose names begin with eq are special in that they are applicable to all objects; equal will tell you that "abc" is not 1 without complaining.
So you'd want someone to engage your overall point that there are redundant and deprecated functions, while the specific ones you actually have in mind are not redundant or deprecated (and you know this)? And for that reason, it would be good to keep the specifics out of the discussion? Okay ...
> There is nothing in the function name
Yes there is: the names get longer with increasing complexity of comparison.
The common eq prefix puts them into a family.
> avoiding (eql) unless you have specific need of it.
eql is the default value of the :test argument in numerous library functions.
Rather, you should avoid eq unless you're optimizing. Rarely do you want to compare objects in such a way that (<compare> 12345 12345) might be false!
It is idiomatic, though, to use eq in code that manipulates symbols, like (if (eq arg 'foo) ...).
If one of the arguments of an equality function is a constant, it's possible to pick the strongest equality function which goes with that constant's type. All equality functions reduce to eq when symbols are compared.
> Lisp seems to love doing this.
Many operator names in Lisp are short mnemonics. It is like this in older languages, or older parts of languages. Short identifiers keep programs short.
Short, mnemonic names are part of the elegance of traditional Lisps.
It's not just old versus new; for instance in some very new languages, we see a trend of shortening define to def, or function to fn and such.
My TXR Lisp is much newer than Common Lisp, but I shortened some things. Instead of stable-sort, I have ssort. Or instead of symbol-macrolet, I have symacrolet. In Common Lisp, like in many languages, there is a "layer" of newer identifiers that are longer, often hyphenated compounds. You can tell that define-symbol-macro is newer than defun. However, someone making a new language which is inspired by an existing one can challenge those decisions, going by what identifiers are often used, rather than going by the chronological order in which they were introduced in the inspiring language. Symbol macros were introduced in Common Lisp for, I think, supporting with-slots. But symbol macros turn out to be important, deserving short names.
Why ssort rather than stable-sort? Part of the reason is that I made a change of introducing nsort as the in-place sort, making sort pure. That then establishes the idea that we have a one letter modifier. The s for stable becomes another one. And in fact, I have one more: c for caching. There are all eight combinations, in the order c, s, n: in other words c?s?n?sort. Thus csnort ("cee snort") is the caching, stable, destructive sort. I don't want to punish the programmer and reader of the code with caching-stable-destructive-sort. This is not Java.
You can't cram meaning into the spelling of every identifier, by making it out of a string of English words, because that makes things comically verbose.
Languages don't do that. You can't guess what "water" means, if you're new to English, and your native language doesn't have a cognate like "wasser". You just have to learn the vocabulary word. Some words are compounds of other words, others aren't. Only some compounds have compositional meanings, bearing out the obvious guess.