evw@infometrics.nl
1/17/2016 2:56:00 PM
Op zondag 17 januari 2016 11:18:25 UTC+1 schreef Marco Antoniotti:
> On Saturday, January 16, 2016 at 2:27:01 PM UTC+1, Ernst van Waning wrote:
> > Op vrijdag 15 januari 2016 16:51:10 UTC+1 schreef Jim Newton:
> > > On Friday, January 15, 2016 at 3:31:17 PM UTC+1, Siebe de Vos wrote:
> > > > Check the type array: while * is not a type-specifier as such, it can be
> > > > used in the syntactical position of a type.
> > > >
> > > > S.
> > >
> > > So I think sb-ext:valid-type-specifier-p returns the wrong value.
> > > Which also means that my suggested implementation of valid-type-p is consequently wrong.
> > >
> > > (defun valid-type-p (type-designator)
> > > #+sbcl (SB-EXT:VALID-TYPE-SPECIFIER-P type-designator) ;; TODO also exclude cl:*
> > > #+(or clisp allegro) (ignore-errors (subtypep type-designator t))
> > > #-(or sbcl clisp allegro) (error "VALID-TYEP-P not implemented for ~A" (lisp-implementation-type))
> > > )
> >
> > Dear Jim,
> >
> > Since about a week or so, I use the following code to find out if a form represents a type:
> >
> > (defun typenamep (x)
> > "(typenamep x)
> > T if <x> is a typename, NIL if it is not."
> > (cond ((eq x 't) (values t t))
> > ((or (typep x 'symbol) (typep x '(cons symbol)))
> > (handler-case ; handle incomplete typenames
> > (multiple-value-bind (subtype? sure?) (subtypep x 'atom)
> > (if (and subtype? sure?)
> > (values subtype? sure?)
> > (subtypep x 'sequence)))
> > ;; incomplete type names are definitely not typenamep
> > (error () (values nil t))))
> > (t ; exclude 'function or 'values in (car x)? CLtL2, p.96
> > (values nil t))))
> >
> > It is portable and has done its job so far, maybe you can use it as well :)
> >
> > Kind regards,
> > Ernst
>
> Nope. It is not portable, or, at a minimum consistent.
>
> LW > (typenamep (gensym))
> NIL
> T
>
> CCL> (typenamep (gensym))
> T
> T
>
> Which is the case that raised this all issue.
>
> IMHO, CCL, CMUCL and SBCL and others need to fix the behavior of (SUBTYPEP (GENSYM) T) in order have a portable version...
>
> Cheers
> --
> MA
Dear Marco,
Well, portable inthe sense that the code does not depend on #+some-CL-implementation. The values it produces certaily depend on the implementation. Comparing the CLs on my machine:
;; (subtypep (gensym) t) ->
;; clisp-2.49: -------- error - invalid type specification
;; sbcl-1.2.11: ------- t, t
;; ccl-1.11-rc1-r16620: t, t
;; abcl-1.3.2: -------- t, t
IIRC and IIUC, any object in CL belongs to type T, but Clisp does not seem to agree. IIRC and IIUC again, the direct subtypes of T are atom and sequence, so I tried again:
;; (subtypep (gensym) 'atom) ->
;; clisp-2.49: -------- error - invalid type specification
;; sbcl-1.2.11: ------- nil, nil
;; ccl-1.11-rc1-r16620: nil, nil
;; abcl-1.3.2: -------- t, t
;; (subtypep (gensym) 'sequence) ->
;; clisp-2.49: -------- error - invalid type specification
;; sbcl-1.2.11: ------- nil, nil
;; ccl-1.11-rc1-r16620: nil, nil
;; abcl-1.3.2: -------- nil, t
Both sbcl and ccl do not see any symbol as type, abcl differs, does not seem to distinguish a symbol from a typename written as a symbol. Then here is what typenamep produces:
;; (typenamep (gensym)) ->
;; clisp-2.49: -------- nil, t (error exit)
;; sbcl-1.2.11: ------- nil, nil
;; ccl-1.11-rc1-r16620: nil, nil
;; abcl-1.3.2: -------- t, t
A symbol is not (necessarily) an atomic typename. I am not sure why Clisp signals an error in this case.
Kind regards,
Ernst