Thanks. Seems my assessment and SBCL's self-description match perfectly, as they explicitly aim to "reward the use of type declarations throughout development" and exhort users to "always declare the types of function arguments and structure slots as precisely as possible".
They do want their users to use one of Common Lisp's least safe features pervasively.
If the point was to mine assertions for type information, they could have encouraged the use of assertions. But they don't. They encourage the use of declarations, which is entirely not the same thing, and it's a bad thing for the Common Lisp source code ecosystem, even if not for the SBCL ecosystem. Hurray for SBCL.
> They do want their users to use one of Common Lisp's least safe features pervasively
It's not an unsafe Common Lisp feature. The standard does say nothing about its unsafeness. Only implementations may be unsafe. The Common Lisp standard says nothing how the implementation deal with type declarations.
There is a wide range of behavior in Common Lisp implementations dealing with type declarations. Some will do nothing with type declarations - thus its not more or less safe if one define types.
Some will add more runtime checks when types are declare. Thus the code is MORE safe at runtime.
Some compilers may add less runtime checks and will create specialized code -> less safe.
SBCL provides several ways to deal with that depending on compiler settings.
That SBCL advanced features are a disadvantage is nonsense.
> If the point was to mine assertions for type information, they could have encouraged the use of assertions.
With that in mind:
> Some will add more runtime checks when types are declare. Thus the code is MORE safe at runtime.
Users can portably and safely use assertions if they want that behavior. Encouraging the use of declarations instead is neither portable nor safe since, as you said:
> Some compilers may add less runtime checks and will create specialized code -> less safe.
There are several misconceptions about how people use Common Lisp.
> Users can portably and safely use assertions if they want that behavior
The point is that SBCL can check both at compile-time and at runtime. Which the others (exception: CMUCL and Scieneer CL) can't.
* (defun foo (a) (declare (string a)) (+ a 10))
; in: DEFUN FOO
; (+ A 10)
;
; caught WARNING:
; Derived type of A is
; (VALUES STRING &OPTIONAL),
; conflicting with its asserted type
; NUMBER.
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
; caught 1 WARNING condition
FOO
That means SBCL tells me already at compile-time that there is a problem in my code. That's something which a development environment can exploit. I get a list of compiler warnings and can then fix my code - without the need to run it and to go into a break - and without the need to have a test case.
Now if I fix that error and run that code in my other implementation - that problem is also fixed there.
Now you assume that adding an assertion would have had a benefit for the other implementation, since it would then create a runtime assertion violation if not a string is provided.
The thing is: this is usually not done. Nobody writes code with assertions everywhere in Common Lisp.
What Lisp a developer really does: if we need to provide a runtime check, then we write a CLOS method.
Thus by default we encourage developers to use CLOS:
CL-USER 23 > (defmethod foo ((s string))
(concatenate 'string s "bar"))
#<STANDARD-METHOD FOO NIL (STRING) 4020259F8B>
CL-USER 24 > (foo 3)
Error: No applicable methods for #<STANDARD-GENERIC-FUNCTION FOO 406000173C> with args (3)
1 (continue) Call #<STANDARD-GENERIC-FUNCTION FOO 406000173C> again
2 (abort) Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
> Some compilers may add less runtime checks and will create specialized code -> less safe.
There is another misconception. Nobody forces me to use those compilers or use them in an unsafe mode.
The choice of compilers in Common Lisp is to give the user different tools for different situations. It does not force me to run my code containing type declarations in an unsafe mode - which usually is controlled by compiler switches: OPTIMIZE qualities for SAFETY, DEBUG and SPEED.
If I set safety to 3, most compilers will not create unsafe code - even though there are type declarations.
If we have a type violation in a CLOS method, SBCL even catches that:
* (defmethod baz ((s string)) (+ s 10))
; in: DEFMETHOD BAZ (STRING)
; (+ S 10)
;
; caught WARNING:
; Derived type of S is
; (VALUES STRING &OPTIONAL),
; conflicting with its asserted type
; NUMBER.
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
; caught 1 WARNING condition
WARNING: Implicitly creating new generic function COMMON-LISP-USER::BAZ.
#<STANDARD-METHOD COMMON-LISP-USER::BAZ (STRING) {5132DEA1}>
The developer then will fix that code. When it then runs on another Lisp -> benefit.
So my advice usually is: even if one develops for another Lisp implementation, additionally use SBCL to check your code.
They do want their users to use one of Common Lisp's least safe features pervasively.
If the point was to mine assertions for type information, they could have encouraged the use of assertions. But they don't. They encourage the use of declarations, which is entirely not the same thing, and it's a bad thing for the Common Lisp source code ecosystem, even if not for the SBCL ecosystem. Hurray for SBCL.