Since the title includes the word "quirks," the observation I'll make here is entirely appropriate: the post oversimplifies this.
It says: "So as we can see, at both run-time and compile-time, Common Lisp does typechecking to prevent silly errors."
This is not entirely accurate, as the Common Lisp standard does not require such typechecking.
The Common Lisp standard specifies the types of the arguments that a function expects. It generally does not specify what happens if the function receives arguments of unexpected types. It explicitly does not specify this: the standard says that if you give a function unexpected types, the consequences are undefined:
https://www.lispworks.com/documentation/HyperSpec/Body/01_dd...
where "undefined" means that any behavior, from an error message to a harmless failure to a catastrophic failure, can occur:
https://www.lispworks.com/documentation/HyperSpec/Body/01_db...
Let's take + (the addition function) as an example. It "might signal" a type error if some argument is not a number:
https://www.lispworks.com/documentation/HyperSpec/Body/f_pl....
where "might signal" means that the result is unpredictable but if the function does signal an error, it will be of the given type:
https://www.lispworks.com/documentation/HyperSpec/Body/01_db...
I can understand why the standard is written this way. Checking the types of arguments takes time. Sometimes you might not want to check the types for performance reasons.
It seems the author is using SBCL. As a practical matter, SBCL on the default settings will check the types of arguments. SBCL's manual (along with the manual of its predecessor, CMUCL) discusses how to manipulate these settings - the author discusses this, with the DECLARE form. But Common Lisp does not require this checking, so if you need your types checked, consult your implementation's manual. Indeed, SBCL allows you to change the settings for SPEED and SAFETY to specify how much type-checking you want.
All these caveats are also true for structures. The author says structure types are checked - again, as a practical matter, SBCL will check these unless you tell it not to. But that's not what the standard requires. Indeed, the standard explicitly states that "It is implementation-dependent whether the type is checked when initializing a slot or when assigning to it."
https://www.lispworks.com/documentation/HyperSpec/Body/m_def...
[edit] Relevant part of SBCL manual is here:
Thank you for this. There is occasionally disagreement about what "Common Lisp" even means, and the spec is often cited, but as far as all of my posts, library work, and application work are concerned, Common Lisp means "the current reality of the major compilers as implemented in 2025". This is a descriptive / bottom-up definition, and as an active author of software it is the one I'm more concerned with. For instance, `:local-nicknames` have been essentially universally implemented among the compilers, despite not being part of the spec. To me, this makes that feature "part of Common Lisp", especially since basically all CL software written today assumes its availability.
You're right to point out too that the post is somewhat SBCL-centric - this too reflects a descriptive reality that most new CL software is written with SBCL in mind first. Despite that I'd always encourage library authors to write as compatible code as possible, since it's really not that hard, and other compilers absolutely have value (I use several).
Every programming language has a practical definition: it is the intersection of the sets of features that are accepted by the various relevant production compilers and interpreted identically enough to be portable to all of them.
Formal language definitions, standards, and books are great, but you can't compile with them. Abstract language specs that don't have reference implementations or conformance test suites are not particularly useful to either implementors or users.