Is there a good reason that they are not universal functions or simply historical?
Common Lisp has some layers of the language in some of its areas. Higher-level software components may need to be built on lower-level structures.
One of his goals was fast enough for a range of applications.
Common Lisp also introduced the idea of ββsequences, an abstraction of lists and vectors, at a time when the language did not have an object system. CLOS came a few years after the initial Common Lisp project.
Take, for example, something like equality - for numbers.
Lisp has = :
(= ab)
This is the fastest way to compare numbers. = also defined only for numbers.
Then there is eql , equal and equalp . They work for numbers, but also for some other data types.
Now, if you need a higher speed, you can declare types and tell the compiler to generate faster code:
(locally (declare (fixnum ab) (optimize (speed 3) (safety 0))) (= ab))
So why = not a common CLOS function?
a) it was introduced when CLOS did not exist
but no less important:
b) in Common Lisp, it was not known (and this is still not the case) how to make a common CLOS function = as fast as a non-general function for typical usage scenarios - while maintaining dynamic typing and extensibility
The common CLOS function simply has a speed limit. Shipping costs.
CLOS is best used for higher-level code, which then really benefits from features such as extensibility, multitask, inheritance / combinations. Generic functions should be used for a specific generic behavior - and not as a collection of similar methods.
Thanks to the best implementation technology, implementation-specific language improvements, etc., it may be possible to extend the range of code that can be written using CLOS. It has been tried with programming languages ββsuch as Dylan and Julia.
Presumably this is a bad form for overriding these names?
Common Lisp implementations do not allow replacing them in this way. Keep in mind that your replacement functions must be implemented in such a way that they work in sequence with the old functions. In addition, older versions may be tied in some way and cannot be replaced everywhere.
Is there a way to tell defgeneric not to generate a software error and go ahead and replace the function binding?
You will need to make sure that the replacement works when it is replaced. Code replacement functions may use those functions that you replace.
However, implementations allow you to replace CL functions, but this is implementation specific. For example, LispWorks provides the lispworks:*packages-for-warn-on-redefinition* and lispworks:*handle-warn-on-redefinition* . They can be linked or changed globally.
What is wisdom and best practice considered here?
There are two approaches:
- use specific ways to replace standard Lisp functions
It may be dangerous. In addition, you need to support it for all CL implementations you want to use ...
- use the language pack in which you define your new language. Here it will be the standard Common Lisp plus your extensions / changes. Export everything that the user will use. In your software, use this package instead of
CL .