From: Will Fitzgerald
Subject: Three questions about type specifications
Date: 
Message-ID: <661755b5.0108171419.7f3395fc@posting.google.com>
1. Is there a Common Lisp function that will determine whether a type
specification is valid? (i.e., (integer * 10) is valid, but (integer *
foo) isn't).

2. Is there a way to recover the expansions of DEFTYPEs? Sort of a
macroexpand for type specifications? (That is, if I do (deftype mymod
(n) `(integer 0 (,n))) is there a way to go from (MYMOD 4) -> (INTEGER
0 4)?

3. CLtL2 and the ANSI Hyperspec seem vague about what valid types can
be for compound types in the FLOAT family. Is (typep (float 1) '(float
0 10)) valid, for instance, or must it be (typep (float 1) '(float 0.0
10.0))?

Will Fitzgerald
I/NET, Inc.

From: Larry Hunter
Subject: Re: Three questions about type specifications
Date: 
Message-ID: <m3hev6z2q8.fsf@huge.uchsc.edu>
Will,

At least one of your questions is easy:

   Is there a Common Lisp function that will determine whether a type
   specification is valid? (i.e., (integer * 10) is valid, but
   (integer * foo) isn't).

How about:

(defun test-typespec (typespec) 
  (catch 'test-typespec
    (handler-bind ((error (lambda (ignore)
                             (declare (ignore ignore))
                             (throw 'test-typespec nil))))
      (subtypep typespec t))))

With respect to your second question, I rather doubt there is a
vendor-independent way to recover the expansion of a particular
deftype.  The spec only refers to the effect of fully expanding the
new type, so I think a vendor would be within the spec if they only
kept around the fully expanded information, and not the information
that was used in the actual deftype.  On the other hand, it would seem
reasonable to be able to recover at least this fully expanded
definition, but I can't see any way to do that, either in general or
in ACL. 

And as for your final question, in my reading of the spec (12.1.6
Interval Designators) it is clear that the numbers which designate
intervals in a compound numeric type description (like float) must be
of the base type. For this reason (float 0 10) does not have to be
treated as valid by a conforming implementation, although it is not
unreasonable for an implementation to try to coerce the interval
designators to the base type. 

ACL is apparently inconsistent on this point.  For example, 

   cl-user(111): (typep 0.0 '(float 0 1))
   t
   cl-user(112): (subtypep '(float 0 1) 'float)
   Error: (float 0 1) is not a valid type specifier
     [condition type: simple-error]
   ...
   cl-user(114): (subtypep '(float 0.0 1.0) 'float)
   t
   t

Larry


-- 

Lawrence Hunter, Ph.D.
Director, Center for Computational Pharmacology
Associate Professor of Pharmacology, PMB & Computer Science
URL: http://compbio.uchsc.edu/Hunter

phone  (303) 315-1094           UCHSC, Campus Box C236    
fax    (303) 315-1098           School of Medicine rm 2817b   
cell   (303) 324-0355           4200 E. 9th Ave.                 
email: ············@uchsc.edu   Denver, CO 80262       
From: Barry Margolin
Subject: Re: Three questions about type specifications
Date: 
Message-ID: <Drhf7.50$ku5.823@burlma1-snr2>
In article <····························@posting.google.com>,
Will Fitzgerald <··········@inetmi.com> wrote:
>1. Is there a Common Lisp function that will determine whether a type
>specification is valid? (i.e., (integer * 10) is valid, but (integer *
>foo) isn't).

(defun valid-type-p (type-spec)
  (handler-case
      (progn (typep nil type-spec)
             t)
    (error nil)))
   
>2. Is there a way to recover the expansions of DEFTYPEs? Sort of a
>macroexpand for type specifications? (That is, if I do (deftype mymod
>(n) `(integer 0 (,n))) is there a way to go from (MYMOD 4) -> (INTEGER
>0 4)?

Not in the standard language, but implementation-dependent functions
probably exist.

>3. CLtL2 and the ANSI Hyperspec seem vague about what valid types can
>be for compound types in the FLOAT family. Is (typep (float 1) '(float
>0 10)) valid, for instance, or must it be (typep (float 1) '(float 0.0
>10.0))?

CLTL2 pp.60-61 says "The limits <low> and <high> must each be a
floating-point number, a list of a gloating-point number, or unspecified."
That doesn't seem vague at all.  Integers aren't floating-point numbers, so
the aren't allowed.

In the Hyperspec, this requirement is in section 12.1.6 Interval
Designators, which says that the values in an interval designator for type
<type> must be numbers of type <type>.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Larry Hunter
Subject: Re: Three questions about type specifications
Date: 
Message-ID: <m33d6qz1nb.fsf@huge.uchsc.edu>
Barry,

Oddly enough, your suggestion for valid-type-p doesn't work in Franz
Allegro CL, and possibly other implementations.   The typep predicate
apparently can decide to return nil before doing much of a test of the
typespec, e.g. 

   cl-user(136): (valid-type-p '(float 0 foo))
   t

since

   cl-user(141): (typep nil '(float 0 foo))
   nil

returns nil but does not signal an error, presumably because nil is
not of type float, and therefore cannot be of any compound type
derived from float.

However, by using (subtypep ... t) you can avoid this problem, and get
rid of the superfluous (progn ... t) wrapper, e.g.

(defun valid-typespec-p (type-spec)
  (handler-case
      (subtypep type-spec t)
    (error nil)))

And your use of handler-case instead of the more convoluted
handler-bind in the response I just posted is definitely easier to
read.

Larry


-- 

Lawrence Hunter, Ph.D.
Director, Center for Computational Pharmacology
Associate Professor of Pharmacology, PMB & Computer Science
URL: http://compbio.uchsc.edu/Hunter

phone  (303) 315-1094           UCHSC, Campus Box C236    
fax    (303) 315-1098           School of Medicine rm 2817b   
cell   (303) 324-0355           4200 E. 9th Ave.                 
email: ············@uchsc.edu   Denver, CO 80262       
From: Lieven Marchand
Subject: Re: Three questions about type specifications
Date: 
Message-ID: <m3bsldwk8l.fsf@localhost.localdomain>
Larry Hunter <············@uchsc.edu> writes:

> However, by using (subtypep ... t) you can avoid this problem, and get
> rid of the superfluous (progn ... t) wrapper, e.g.
> 
> (defun valid-typespec-p (type-spec)
>   (handler-case
>       (subtypep type-spec t)
>     (error nil)))
> 

I'm not convinced of your solution either. The function SUBTYPEP is
only defined to take type specifiers as arguments, as noted in its
"Arguments and Values" section and section 1.4.4.3 of the Hyperspec
states clearly that "Except as explicitly specified otherwise, the
consequences are undefined if these type restrictions are violated."

-- 
Lieven Marchand <···@wyrd.be>
She says, "Honey, you're a Bastard of great proportion."
He says, "Darling, I plead guilty to that sin."
Cowboy Junkies -- A few simple words
From: Kent M Pitman
Subject: Re: Three questions about type specifications
Date: 
Message-ID: <sfwae0xpbh8.fsf@world.std.com>
Lieven Marchand <···@wyrd.be> writes:

> Larry Hunter <············@uchsc.edu> writes:
> 
> > However, by using (subtypep ... t) you can avoid this problem, and get
> > rid of the superfluous (progn ... t) wrapper, e.g.
> > 
> > (defun valid-typespec-p (type-spec)
> >   (handler-case
> >       (subtypep type-spec t)
> >     (error nil)))
> > 
> 
> I'm not convinced of your solution either. The function SUBTYPEP is
> only defined to take type specifiers as arguments, as noted in its
> "Arguments and Values" section and section 1.4.4.3 of the Hyperspec
> states clearly that "Except as explicitly specified otherwise, the
> consequences are undefined if these type restrictions are violated."

Then again, the function shown does compute the answer to the question
"can I use this as a typespec in this implementation".

I'm actually curious what computation people are going to try to put
this to.
From: Will Fitzgerald
Subject: Re: Three questions about type specifications
Date: 
Message-ID: <661755b5.0108200715.75b799cc@posting.google.com>
Kent M Pitman <······@world.std.com> wrote in message news:<···············@world.std.com>...

> 
> I'm actually curious what computation people are going to try to put
> this to.


I'm exploring some ideas related to tuple spaces (see the IBM Java
implementation, TSpaces, at
http://www.almaden.ibm.com/cs/TSpaces/intro.html).

The basic match routine, in a LISP idiom, would use typespecs for the
'antitype' or template -- for example,

(tuple-match '((float 1.0 10.0) "test") '(5.0 "test")) => T,
(tuple-match '((float 1.0 10.0) "test") '(some "test")) => NIL,
(tuple-match '((float 1.0 foo) "test") '(5.0 "test")) should throw an
error--or, perhaps, consider '(float 1.0 foo) to be a list, not a
typespec.
From: Kent M Pitman
Subject: Re: Three questions about type specifications
Date: 
Message-ID: <sfwr8u63ckl.fsf@world.std.com>
··········@inetmi.com (Will Fitzgerald) writes:

> 
> Kent M Pitman <······@world.std.com> wrote in message news:<···············@world.std.com>...
> 
> > 
> > I'm actually curious what computation people are going to try to put
> > this to.
> 
> 
> I'm exploring some ideas related to tuple spaces (see the IBM Java
> implementation, TSpaces, at
> http://www.almaden.ibm.com/cs/TSpaces/intro.html).
> 
> The basic match routine, in a LISP idiom, would use typespecs for the
> 'antitype' or template -- for example,
> 
> (tuple-match '((float 1.0 10.0) "test") '(5.0 "test")) => T,
> (tuple-match '((float 1.0 10.0) "test") '(some "test")) => NIL,
> (tuple-match '((float 1.0 foo) "test") '(5.0 "test")) should throw an
> error--or, perhaps, consider '(float 1.0 foo) to be a list, not a
> typespec.

This gets to what I was asking.  Why not use a different datatype that is
recognizable in intent as "i mean a typespec" if you are also going to
allow lists in the same place.  If  you're NOT allowing lists in the same
place, then isn't this just a simple matter of error checking? And in that
case, is (float 1.0 foo) any different than (float 1.0 6.0) where you
meant to say 5.0 instead of 6.0 ... i.e., my point is that not all errors
are detectable.  
From: Erik Naggum
Subject: Re: Three questions about type specifications
Date: 
Message-ID: <3207153995704416@naggum.net>
* ··········@inetmi.com (Will Fitzgerald)
> 1. Is there a Common Lisp function that will determine whether a type
> specification is valid? (i.e., (integer * 10) is valid, but (integer *
> foo) isn't).

  compile and compile-file come to mind.

> 2. Is there a way to recover the expansions of DEFTYPEs? Sort of a
> macroexpand for type specifications? (That is, if I do (deftype mymod (n)
> `(integer 0 (,n))) is there a way to go from (MYMOD 4) -> (INTEGER 0 4)?

  After you have done this, what will you do?  It appears to that you are
  looking for some functionality that can query the type, much like Ada's
  fairly elaborate <type>'<property> concept.  Is that what you really want?

///