From: Raymond Toy
Subject: member types and array-element-type?
Date: 
Message-ID: <4npugia554.fsf@rtp.ericsson.se>
Suppose you have the function:

(defun foo (x)
  (declare (type (or (array single-float (*))
                     (array double-float (*))
                     (array (signed-byte 16) (*)))
                 x))
  (array-element-type x))

Assuming you had specialized arrays of the given types, then FOO can
return one of the three values: SINGLE-FLOAT, DOUBLE-FLOAT,
(SIGNED-BYTE 16).  Of course, (SIGNED-BYTE 16) can be written (INTEGER
-32768 32767).

How would you describe the type of the function FOO?  I think that

(MEMBER SINGLE-FLOAT DOUBLE-FLOAT (SIGNED-BYTE 16))

is ok, but suppose ARRAY-ELEMENT-TYPE decided to return (INTEGER
-32768 32767) instead?  Then what?

Why?  I'm trying to get CMUCL to know what the type of
array-element-type can return.

Thanks,

Ray

From: Thomas A. Russ
Subject: Re: member types and array-element-type?
Date: 
Message-ID: <ymiu25uqvwu.fsf@sevak.isi.edu>
But couldn't it also return the type T, since there is unlikely to
really be a single, existing element type which subsumes the three
element types that the array could have?


-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Raymond Toy
Subject: Re: member types and array-element-type?
Date: 
Message-ID: <4nzofm8ika.fsf@rtp.ericsson.se>
>>>>> "Thomas" == Thomas A Russ <···@sevak.isi.edu> writes:

    Thomas> But couldn't it also return the type T, since there is unlikely to
    Thomas> really be a single, existing element type which subsumes the three
    Thomas> element types that the array could have?

I suppose so.  But note that X is not declared as 

(array (or single-float double-float (signed-byte 16)) (*))

X is declared to be one of three possible specialized arrays.

If I had left out the declaration for X, I wouldn't want (foo x) to
always return T.  It should return the actual array element type of
X.  With the declaration, I'm just narrowing down the choices that foo
can return.

This came up in the CMUCL mailing list of someone wanting something
like this to work better:

(defun bar (x)
  (declare (type (array single-float (*)) x))
  (let ((s (coerce 0 (array-element-type x))))
     ;; some stuff using s, and the compiler knowing that s is a
     ;; single-float.
  ))

Right now, CMUCL doesn't know what the type of S, because it doesn't
know that array-element-type can only return single-float in this
situation.

I have something that basically works; I just wanted some
clarification on how to describe what the type of array-element-type
can be under certain situations.

Ray
From: Lieven Marchand
Subject: Re: member types and array-element-type?
Date: 
Message-ID: <m34rxujo68.fsf@localhost.localdomain>
Raymond Toy <···@rtp.ericsson.se> writes:

> Suppose you have the function:
> 
> (defun foo (x)
>   (declare (type (or (array single-float (*))
>                      (array double-float (*))
>                      (array (signed-byte 16) (*)))
>                  x))
>   (array-element-type x))
> 
> Assuming you had specialized arrays of the given types, then FOO can
> return one of the three values: SINGLE-FLOAT, DOUBLE-FLOAT,
> (SIGNED-BYTE 16).  Of course, (SIGNED-BYTE 16) can be written (INTEGER
> -32768 32767).
> 
> How would you describe the type of the function FOO?  I think that
> 
> (MEMBER SINGLE-FLOAT DOUBLE-FLOAT (SIGNED-BYTE 16))
> 
> is ok, but suppose ARRAY-ELEMENT-TYPE decided to return (INTEGER
> -32768 32767) instead?  Then what?
> 

Interesting question. I think it doesn't matter since the two types
are the same. 

CL-USER 1 > (subtypep '(signed-byte 16) '(integer -32768 32767))
T
T

CL-USER 2 > (subtypep '(integer -32768 32767) '(signed-byte 16))
T
T


-- 
Lieven Marchand <···@wyrd.be>
Gla�r ok reifr skyli gumna hverr, unz sinn b��r bana.
From: Raymond Toy
Subject: Re: member types and array-element-type?
Date: 
Message-ID: <4ny9v27f5w.fsf@rtp.ericsson.se>
>>>>> "Lieven" == Lieven Marchand <···@wyrd.be> writes:


    Lieven> Interesting question. I think it doesn't matter since the two types
    Lieven> are the same. 

    Lieven> CL-USER 1 > (subtypep '(signed-byte 16) '(integer -32768 32767))
    Lieven> T
    Lieven> T

    Lieven> CL-USER 2 > (subtypep '(integer -32768 32767) '(signed-byte 16))
    Lieven> T
    Lieven> T


Yes, of course.  But array-element-type doesn't return a (signed-byte
16)---it returns the list '(signed-byte 16):

(type-of (array-element-type (make-array 1 :element-type '(signed-byte 16))))
=>
CONS

I'm just wanted to know what it the type of the function would be, and
how would the different ways of expressing the same thing should be
handled.

I also have problems with this:

(typep 'single-float '(member single-float (signed-byte 16)))
=> T

(typep '(signed-byte 16) '(member single-float (signed-byte 16)))
=> NIL

So you can't really tell if something is of that type.

Perhaps, I'm just totally confused,

Ray
From: Arthur Lemmens
Subject: Re: member types and array-element-type?
Date: 
Message-ID: <3A91936D.8BA2F0AE@xs4all.nl>
Raymond Toy wrote:

> I also have problems with this:
> 
> (typep 'single-float '(member single-float (signed-byte 16)))
> => T
> 
> (typep '(signed-byte 16) '(member single-float (signed-byte 16)))
> => NIL
> 
> So you can't really tell if something is of that type.

I think you're confusing MEMBER and OR: MEMBER combines objects 
(using EQL to check for membership), OR combines arbitrary type 
specifiers. 
So:
 (subtypep '(signed-byte 16) '(member single-float (signed-byte 16)))
 -> NIL
    T
but:
 (subtypep '(signed-byte 16) '(or single-float (signed-byte 16)))
 -> T
    T

Also, you seem to be confusing TYPEP with SUBTYPEP. TYPEP expects
an object and a type specifier, whereas SUBTYPEP expects two type 
specifiers.
So:
  (typep -32767 '(or single-float (signed-byte 16)))
   -> T
but:
 (typep '(signed-byte 16) '(or single-float (signed-byte 16)))
 -> NIL

At least, that's how I understand the standard.

--
Arthur Lemmens
From: Raymond Toy
Subject: Re: member types and array-element-type?
Date: 
Message-ID: <4nd7ce5n23.fsf@rtp.ericsson.se>
>>>>> "Arthur" == Arthur Lemmens <········@xs4all.nl> writes:

    Arthur> Raymond Toy wrote:

    >> I also have problems with this:
    >> 
    >> (typep 'single-float '(member single-float (signed-byte 16)))
    >> => T
    >> 
    >> (typep '(signed-byte 16) '(member single-float (signed-byte 16)))
    >> => NIL
    >> 
    >> So you can't really tell if something is of that type.

    Arthur> I think you're confusing MEMBER and OR: MEMBER combines objects 
    Arthur> (using EQL to check for membership), OR combines arbitrary type 
    Arthur> specifiers. 
    Arthur> So:

I don't think so, but my examples my have been confusing.

[examples snipped]


    Arthur> At least, that's how I understand the standard.

I think I'm not being clear enough in what I want to know.

Here's the original function:

(defun foo (x)
  (declare (type (or (array single-float (*))
                     (array double-float (*))
                     (array (signed-byte 16) (*)))
                 x))
  (array-element-type x))

Assume you have the specialized arrays given above.  For a
sufficiently smart compiler, if you ask it what the return type of the
function FOO is, what would it say?

This function can return 1 of three values:

o The symbol 'single-float
o The symbol 'double-float
o The LIST '(signed-byte 16)

What is the correct description of this type?  Is it

(MEMBER SINGLE-FLOAT DOUBLE-FLOAT (SIGNED-BYTE 16))?

It can't be (or single-float double-float (signed-byte 16)) as you
seem to suggest because FOO DOES NOT return a number.  It
returns the a SYMBOL or a LIST.

Then (typep 'single-float (member single-float double-float
(signed-byte 16))) return T, as expected.  But typep with
'(signed-byte 16) is NIL because it's not eql to any of the types
listed in the member.

Ray
From: Arthur Lemmens
Subject: Re: member types and array-element-type?
Date: 
Message-ID: <3A923C42.D0341BCD@xs4all.nl>
Raymond Toy wrote:

> This function can return 1 of three values:
> 
> o The symbol 'single-float
> o The symbol 'double-float
> o The LIST '(signed-byte 16)
> 
> What is the correct description of this type?  Is it
> 
> (MEMBER SINGLE-FLOAT DOUBLE-FLOAT (SIGNED-BYTE 16))?

No, I don't think so. That would be equivalent to

  (OR (EQL SINGLE-FLOAT) (EQL DOUBLE-FLOAT) (EQL (SIGNED-BYTE 16)))

But (EQL (SIGNED-BYTE 16)) is not the right type specifier for
the list (SIGNED-BYTE 16). For that, you need something like

  (CONS (EQL SIGNED-BYTE) (CONS (EQL 16) (EQL NIL))))

So a correct description of the type you mention would be:

  (OR (EQL SINGLE-FLOAT) (EQL DOUBLE-FLOAT)
      (CONS (EQL SIGNED-BYTE) (CONS (EQL 16) (EQL NIL))))


> Here's the original function:
> 
> (defun foo (x)
>   (declare (type (or (array single-float (*))
>                      (array double-float (*))
>                      (array (signed-byte 16) (*)))
>                  x))
>   (array-element-type x))
> 
> Assume you have the specialized arrays given above.  For a
> sufficiently smart compiler, if you ask it what the return type of the
> function FOO is, what would it say?

Well, it might say 

  (OR (EQL SINGLE-FLOAT) (EQL DOUBLE-FLOAT)
      (CONS (EQL SIGNED-BYTE) (CONS (EQL 16) (EQL NIL))))

but it could say lots of other, equally smart, things as well.
There is no unique, optimal, type specifier for FOO's return type.

--
Arthur Lemmens
From: Raymond Toy
Subject: Re: member types and array-element-type?
Date: 
Message-ID: <4nelwtce81.fsf@rtp.ericsson.se>
>>>>> "Arthur" == Arthur Lemmens <········@xs4all.nl> writes:

    Arthur> Raymond Toy wrote:

    Arthur> Well, it might say 

    Arthur>   (OR (EQL SINGLE-FLOAT) (EQL DOUBLE-FLOAT)
    Arthur>       (CONS (EQL SIGNED-BYTE) (CONS (EQL 16) (EQL NIL))))

    Arthur> but it could say lots of other, equally smart, things as well.
    Arthur> There is no unique, optimal, type specifier for FOO's return type.

Your answer is the one I'm looking for.  (I missed the cons specifier
type in the CLHS.)  Yes, there's no unique optimal specifier but for a
given compiler, I know what array-element-type would return for
certain types so I can create the unique optimal specifier.

This is a bit ugly but workable, although, perhaps not worth the
effort.  You can't really produce good optimal code when the types
aren't fixed at compile time to exactly one of the simple types like
single-float, double-float, (signed-byte 16), etc. :-)

Ray
From: Lieven Marchand
Subject: Re: member types and array-element-type?
Date: 
Message-ID: <m3lmr1cmr0.fsf@localhost.localdomain>
Raymond Toy <···@rtp.ericsson.se> writes:

> Here's the original function:
> 
> (defun foo (x)
>   (declare (type (or (array single-float (*))
>                      (array double-float (*))
>                      (array (signed-byte 16) (*)))
>                  x))
>   (array-element-type x))
> 
> Assume you have the specialized arrays given above.  For a
> sufficiently smart compiler, if you ask it what the return type of the
> function FOO is, what would it say?
> 
> This function can return 1 of three values:
> 
> o The symbol 'single-float
> o The symbol 'double-float
> o The LIST '(signed-byte 16)
> 
> What is the correct description of this type?  Is it
> 
> (MEMBER SINGLE-FLOAT DOUBLE-FLOAT (SIGNED-BYTE 16))?
> 

I think it is 

(satisfies array-element-type-return-value-function)

with 

(defun array-element-type-return-value-function (x)
  (member x '(SINGLE-FLOAT DOUBLE-FLOAT (SIGNED-BYTE 16)) :test #'equal))

which is probably something an optimizing compiler won't be able to do
very much with.

-- 
Lieven Marchand <···@wyrd.be>
Gla�r ok reifr skyli gumna hverr, unz sinn b��r bana.