Stefan Monnier <address@hidden
> schrieb am Mo., 12. Juni 2017 um 19:41 Uhr:
>> It's not trying hard, just a simple check for a known, small, and
>> rarely-changing list of primitive symbols.
> To me, that's working very hard:
> - extra code.
> - extra maintenance
> - extra run-time checks.
> - no benefit since this doesn't catch a common situation.
More concretely: what would be a scenario where such a check would
AFAICT, you need all 3 of:
1- First, you'd need someone to be foolish enough to set his record's
type to be one of the primitive types. This is the actual bug that
your extra check would aim to catch.
Yes, though I wouldn't consider it foolish. make-record can be called indirectly, maybe even from a function that somehow generates the type name. People might try to create records named 'integer' and be happy that that appears to work.
2- Then you'd need to pass that object to a chunk of code which uses
`type-of` and then checks the result for that primitive type.
Otherwise, the type you set would behave just like any other
non-primitive type so the "bug" would be harmless anyway.
3- Furthermore, you'd need this object to be manipulated exclusively in
a way which also works with your record object without signaling an
error (e.g. if the primitive type used is `integer`, it means your
object should never be passed to the likes of `+` since otherwise the
bug would already be discovered by `+` without any need for your extra
I haven't seen any evidence that step 1 will ever occur, even by accident.
I don't care about how often some bug will occur. Rather the contrary: it's the rare bugs that are insidious. People learn about the common ones quickly, but nobody will expect a rare bug, until it arises.
No idea how likely is step 2. `type-of` is very rarely used (except via
cl-defmethod) so it's fairly unlikely, but possible.
Step 3 seems again very unlikely in itself, and even more so if step
2 occurred: if you checked with type-of that your object is of type
`integer` there's a very high likelihood that you're going to then use
operations which only work on integers.
Will all 3 steps ever occur at the same time?
I don't think this is an important question. The important point is: Previously, there were invariants such as (integerp x) == (eq (type-of x) 'integer) or that prin1 would only generate #s(hash-table ...) for actual hash tables. Now these invariants are broken. But it's critical that invariants are never broken, no matter how unlikely the breakage is. Imagine a system where 1 + 1 = 3 in one trillionth of the executions: even if the bug were rare, that system would be unusable. Even worse, because it is so rare, it is much more disastrous when it happens, because people started relying on the invariant that is "almost" guaranteed. But there's a discontinuity between "invariant is guaranteed" and "invariant is almost always guaranteed": the latter is identical to "invariant is not guaranteed at all".
Do we really want to make every call to `make-record` pay the extra test
in order to hope to catch this hypothetical case?
Yes, absolutely. I don't care whether it's rare or hypothetical, it breaks an invariant, and invariants must not be broken.