SUBTYPEP not working properly on COMPLEX types
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Won't Fix
|
Undecided
|
Unassigned |
Bug Description
According to the hyperspec for the type specifier (COMPLEX typespec):
"Every element of this type is a complex whose real part and imaginary part are each of type (upgraded-
(complex type-specifier) refers to all complexes that can result from giving numbers of type type-specifier to the function complex, plus all other complexes of the same specialized representation."
This means that (COMPLEX <t1>) and (COMPLEX <t2>) are synonyms if UPGRADED-
(upgraded-
(upgraded-
(subtypep '(complex rational) '(complex integer)) ==> NIL, T
wow, that seems really weird.
Our complex numbers give you back a more specific thing that the UPGRADED- query reports that they'd give you back. i.e. (complex 1 1) *is* a complex integer according to TYPE-OF. I think that's the broken-ness is that the UPGRADED- answer is wrong.
In fact, if "(complex type-specifier) refers to all [...] other complexes of the same specialized representation.", then '(COMPLEX INTEGER) should have an an element #C(1/ 1/2), right?
Because the specialized representation is (allegedly) the same.
But (typep (complex 1/2 1/2) '(complex integer)) => NIL
So I think we should say that the specialized representation isn't the same. We should claim in the interface that (complex integer) is not (complex rational)
This also differs from MAKE-ARRAY where you ask for some element type and if you get a different type, it matters, because it tells you what you can *in* *practice* put in the array. But you can't store anything different in the complex number from what it started as, because numbers are immutable. Consider also one of the stated purposes of the array inquiry function: it was to avoid having to do (TYPE-OF (MAKE-ARRAY 1 :element-type 'sometype)) to see how upgrading happens.
This doesn't help COMPLEX, because it doesn't help you know what (COMPLEX 42s0 1/2) returns.
I wonder what would be the harm if we always said that all complex numbers upgrade to (complex real), but internally we make use of more specialized representations? This would make the subtypep logic for complex easier. array-element- type said that it was T)
(You can get away with misrepresenting what your specialized representations are if there's no way to prove that the specialization is wrong. This would not be true of arrays - if we falsely reported that every array upgrades to element type T, but (MAKE-ARRAY 1 :element-type 'symbol) returned an array that could truly only hold symbols, then the user would be misled if s/he tried to store a non-symbol despite that upgraded-