From: Bruno Haible <bruno@cl...>  20040420 19:08:09

The type specifier (COMPLEX type) should, according to ANSI CL's description (HyperSpec/Body/syscla_complex.html), only depend on (upgradedcomplexelementtype type). * (upgradedcomplexparttype '(eql 0)) RATIONAL * (upgradedcomplexparttype 'rational) RATIONAL Therefore the types (COMPLEX (EQL 0)) and (COMPLEX RATIONAL) should be the same. But TYPEP doesn't work this way: * (typep #c(0 1) '(complex rational)) T * (typep #c(0 1) '(complex (eql 0))) NIL And SUBTYPEP doesn't work this way either: * (subtypep '(complex rational) '(complex (eql 0))) NIL T [Taken from clisp's type.tst] Platform: Linux/x86. SBCL version: 0.8.9 compiled by CMUCL 18e. 
From: Christophe Rhodes <csr21@ca...>  20040504 11:18:56

Bruno Haible <bruno@...> writes: > The type specifier (COMPLEX type) should, according to ANSI CL's description > (HyperSpec/Body/syscla_complex.html), only depend on > (upgradedcomplexelementtype type). > [...] > [Taken from clisp's type.tst] > Platform: Linux/x86. SBCL version: 0.8.9 compiled by CMUCL 18e. Thank you for the report. I believe I've fixed this (properly, this time; those interested in SBCL history may wish to know that the broken behaviour was almost entirely my fault in the first place, and dates back to the halcyon days of pre7) in sbcl0.8.10.9, but I'm still uncertain about details; if there are still observable oddities, we want to know about them. :) In particular, I think UPGRADEDCOMPLEXPARTTYPE is fairly bogus, in that there is no sensible answer to (upgradedcomplexparttype '(eql 0)) or to (upgradedcomplexparttype '(or singlefloat doublefloat)); the first because the type lattice upgrading requirement is inconsistent with the meaning of the type (COMPLEX (EQL 0)), and the second because in fact the complex specialized representations don't form a lattice at all, because there is no complex representation that can hold all objects of type REAL. Cheers, Christophe  http://wwwjcsu.jesus.cam.ac.uk/~csr21/ +44 1223 510 299/+44 7729 383 757 (setpprintdispatch 'number (lambda (s o) (declare (special b)) (format s b))) (defvar b "~&Just another Lisp hacker~%") (pprint #36rJesusCollegeCambridge) 
From: Bruno Haible <bruno@cl...>  20040505 10:48:59

Christophe Rhodes wrote: > > The type specifier (COMPLEX type) should, according to ANSI CL's > > description (HyperSpec/Body/syscla_complex.html), only depend on > > (upgradedcomplexelementtype type). > Thank you for the report. I believe I've fixed this Thanks! > In particular, I think UPGRADEDCOMPLEXPARTTYPE is fairly bogus UPGRADEDCOMPLEXPARTTYPE is reasonably specified as  a function from { subtypes of REAL } to { subtypes of REAL }, for which  for any type T, T <= (U T),  for any types T1 and T2, T1 <= T2 implies (U T1) <= (U T2). The following implementations of it are all valid: (defun upgradedcomplexparttype (type &optional environment) ; #1 (cond ((subtypep type 'NIL) 'NIL) (t 'REAL))) (defun upgradedcomplexparttype (type &optional environment) ; #2 (cond ((subtypep type 'NIL) 'NIL) (subtypep type 'RATIONAL) 'RATIONAL) (subtypep type 'SHORTFLOAT) 'SHORTFLOAT) (subtypep type 'SINGLEFLOAT) 'SINGLEFLOAT) (subtypep type 'DOUBLEFLOAT) 'DOUBLEFLOAT) (subtypep type 'FLOAT) 'FLOAT) (t 'REAL))) (defun upgradedcomplexparttype (type &optional environment) ; #3 type) The only two "problems" with it are:  What should be the result when the input type is not a recognizable subtype of REAL? Say, (UPGRADEDCOMPLEXPARTTYPE 'SYMBOL) (UPGRADEDCOMPLEXPARTTYPE '(SATISFIES SYMBOLP)) (UPGRADEDCOMPLEXPARTTYPE '(SATISFIES REALP)) I think one may give an error here.  The upgrading can be defined arbitrarily, independently how the implementation actually works. This is because there is no MAKECOMPLEX function taking a type specifier as argument, and no way to SETF REALPART or SETF IMAGPART of an existing complex number. For CLISP, definition #1 reflects the implementation realities but I'll use definition #3 because it allows a maximum of type inference. > there is no sensible answer to > (upgradedcomplexparttype '(eql 0)) > because the type lattice upgrading requirement is > inconsistent with the meaning of the type (COMPLEX (EQL 0)) Err, the type (COMPLEX (EQL 0)) is _defined_ as a function of (upgradedcomplexparttype '(EQL 0)). See http://www2.cs.cmu.edu/Groups/AI/html/hyperspec/HyperSpec/Body/syscla_complex.html If you define (upgradedcomplexparttype '(EQL 0)) => RATIONAL, the type (COMPLEX (EQL 0)) is equivalent to (COMPLEX RATIONAL). > there is no sensible answer to > (upgradedcomplexparttype '(or singlefloat doublefloat)); > because in fact the complex specialized representations don't > form a lattice at all, because there is no complex representation that > can hold all objects of type REAL. Possible results of (upgradedcomplexparttype '(or singlefloat doublefloat)) can be (OR SINGLEFLOAT DOUBLEFLOAT), FLOAT, or REAL. Since FLOAT is the disjoint union of SINGLEFLOAT, DOUBLEFLOAT, etc., and because of the contagion rules http://www2.cs.cmu.edu/Groups/AI/html/hyperspec/HyperSpec/Body/fun_complex.html http://www2.cs.cmu.edu/Groups/AI/html/hyperspec/HyperSpec/Body/sec_12144.html (COMPLEX FLOAT) is the disjoint union of (COMPLEX SINGLEFLOAT), (COMPLEX DOUBLEFLOAT) etc. (COMPLEX REAL) and (COMPLEX FLOAT) can well be abstract types, in the sense that they have no direct instances other than those of (COMPLEX SINGLEFLOAT), (COMPLEX DOUBLEFLOAT) etc. Why not? Bruno 
From: Christophe Rhodes <csr21@ca...>  20040505 11:05:20

Bruno Haible <bruno@...> writes: >> there is no sensible answer to >> (upgradedcomplexparttype '(eql 0)) >> because the type lattice upgrading requirement is >> inconsistent with the meaning of the type (COMPLEX (EQL 0)) > > Err, the type (COMPLEX (EQL 0)) is _defined_ as a function of > (upgradedcomplexparttype '(EQL 0)). See > http://www2.cs.cmu.edu/Groups/AI/html/hyperspec/HyperSpec/Body/syscla_complex.html It is also defined as, in the very next paragraph: (complex typespecifier) refers to all complexes that can result from giving numbers of type typespecifier to the function complex, plus all other complexes of the same specialized representation. and there are no complexes that can result from giving numbers of type (EQL 0) to the function COMPLEX. Cheers, Christophe  http://wwwjcsu.jesus.cam.ac.uk/~csr21/ +44 1223 510 299/+44 7729 383 757 (setpprintdispatch 'number (lambda (s o) (declare (special b)) (format s b))) (defvar b "~&Just another Lisp hacker~%") (pprint #36rJesusCollegeCambridge) 
From: Paul F. Dietz <dietz@dl...>  20040505 11:08:58

Christophe Rhodes wrote: > It is also defined as, in the very next paragraph: > (complex typespecifier) refers to all complexes that can result > from giving numbers of type typespecifier to the function complex, > plus all other complexes of the same specialized representation. > and there are no complexes that can result from giving numbers of type > (EQL 0) to the function COMPLEX. Doesn't the 'plus all other complexes of the same specialized representation' save you there? Paul 