On Thu, Aug 3, 2023 at 8:24 PM John Cowan <cowan(a)ccil.org> wrote:
On Thu, Aug 3, 2023 at 6:06 PM Dan Cross
<crossd(a)gmail.com> wrote:
someone had needed to store a
pair of integers, so they used a CONS cell;
Of course, that was a bad idea. The pair of integers should have been a struct or a
class named after whatever its application-level purpose was: a point, for example.
Probably, but I didn't write the original code, or even make the
change; I did submit the fix, however. :-)
An issue with CLs aggregation primitives is that they can be
expensive, however. QPX was weird; despite things that have been said
about it publicly (
http://www.paulgraham.com/carl.html) QPX was not a
"typical" Lisp program: it is more like FORTRAN written in
S-expressions (many thousand-line Lisp functions with jumps between
various points inside of them are common; those functions like, say,
setq [not setf] a boolean on line 1387, and then reference it on
3298...kind of a mess, but that's what you need to make Lisp fast).
after a while,
the pair
needed to be expanded to a triple, so someone converted the single
CONS cell into a (proper) list.
In that case, a derived struct or class should have been created. The two classes would
use the same accessor methods, just as in C++.
Of course, we all knew this. But when you've got an O(10^6) line
codebase that's extremely fragile, technology and business limitations
demand tradeoffs that are not always what the engineers would choose.
this, of
course, ran afoul of the type system and
raised a condition, which resulted as an ISE in prod. The fix was
trivial (change CDR to SECOND in the right place) but it really struck
me that if the system were statically typed, this would have been
trivially discovered at compile-time.
Absolutely, and if the failure was intolerable, CL's static type declarations would
have caught the use of the wrong type. But you don't have to declare *everything*.
For that matter, there is nothing in a fully statically typed system that requires every
variable, function, argument, etc. to be *declared*: type inference is powerful.
Not really, unless they were used consistently across the entire
codebase (and sadly, they were not).
Common Lisp
does allow you to declare types in some limited regards;
these are usually hints to the compiler for code generation.
They may or may not be, depending on how you set the OPTIMIZE declaration.
like Rob, I
greatly prefer strong, static typing.
Then why weren't you using mypy?
Because it didn't exist at the time (the early 2010s), or if it did,
it was in a very nascent state.
Incidentally,
C is weakly (you can add a pointer to an integer: the
result is another pointer), but statically typed.
That's not weak typing, it's operator overloading, just as when you add an int
to a double. C will not let you, e.g., add an int to a function.
I think there's a bit of a debate as to whether C is weakly or
strongly typed (and certainly, these exist on a spectrum), and some
good judges say it's "moderately typed". I've never heard anyone
refer
to implicit type conversions as "operator overloading", however.
Weak typing is quite rare in high-level languages:
PL/I pointer variables are weakly typed (that is, when you allocate an object you specify
the type of the object and then assign it to the pointer variable), but the rest of the
language is strongly typed.
Once `memcpy` and `void *` are in the mix, all bets are off in C.
- Dan C.