member types and array-element-type? 
Author Message
 member types and array-element-type?

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



Wed, 06 Aug 2003 01:50:47 GMT  
 member types and array-element-type?

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?

--



Wed, 06 Aug 2003 03:18:09 GMT  
 member types and array-element-type?

    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



Wed, 06 Aug 2003 04:43:49 GMT  
 member types and array-element-type?

Quote:

> 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

--

Glaer ok reifr skyli gumna hverr, unz sinn ber bana.



Wed, 06 Aug 2003 05:47:11 GMT  
 member types and array-element-type?

    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



Sat, 09 Aug 2003 01:31:39 GMT  
 member types and array-element-type?

Quote:

> 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



Sat, 09 Aug 2003 05:43:09 GMT  
 member types and array-element-type?


    >> 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



Sat, 09 Aug 2003 06:24:04 GMT  
 member types and array-element-type?

Quote:

> 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))))

Quote:
> 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



Sat, 09 Aug 2003 17:43:30 GMT  
 member types and array-element-type?

Quote:

> 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.

--

Glaer ok reifr skyli gumna hverr, unz sinn ber bana.



Sun, 10 Aug 2003 01:01:07 GMT  
 member types and array-element-type?


    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



Sun, 10 Aug 2003 04:05:18 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. (typep (make-array 10 :element-type 'bit) '(array bit (10)))

2. Deallocating derived type array with pointer members

3. access type referencing nested array element

4. UPGRADED-ARRAY-ELEMENT-TYPE

5. The set of specialized array element types must be closed under intersection

6. (upgraded-array-element-type nil)

7. specialize method based on array element type

8. upgraded-array-element-type

9. Question about array ops on arrays of types of arrays of ...(ack)

10. Shifting array element & regex on array element

11. private pointer derived data type members

12. Compile-time parameter/member type-checking

 

 
Powered by phpBB® Forum Software