From: Tamas Papp
Subject: getting element-type of simple-array
Date: 
Message-ID: <87wsxf6dqx.fsf@pu100877.student.princeton.edu>
I need to find out the type of simple-arrays (to be mapped to cffi
types for foreign calls).  When the array is not a simple-array, I
need to return nil.

I am using the following code:

(let ((type (type-of elements)))
  (if (eq (first type) 'simple-array)
      (second type)
      nil))

but it looks like a kludge.  Is there a neater solution?

Tamas

From: jayessay
Subject: Re: getting element-type of simple-array
Date: 
Message-ID: <m3hcojvmf2.fsf@sirius.goldenthreadtech.com>
Tamas Papp <······@gmail.com> writes:

> I need to find out the type of simple-arrays (to be mapped to cffi
> types for foreign calls).  When the array is not a simple-array, I
> need to return nil.
> 
> I am using the following code:
> 
> (let ((type (type-of elements)))
>   (if (eq (first type) 'simple-array)
>       (second type)
>       nil))
> 
> but it looks like a kludge.  Is there a neater solution?

See array-element-type

http://www.lispworks.com/documentation/HyperSpec/Body/f_ar_ele.htm


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Frank Buss
Subject: Re: getting element-type of simple-array
Date: 
Message-ID: <1249cs0hugw3v$.hu71hrczy65p.dlg@40tude.net>
Tamas Papp wrote:

> I am using the following code:
> 
> (let ((type (type-of elements)))
>   (if (eq (first type) 'simple-array)
>       (second type)
>       nil))
> 
> but it looks like a kludge.  Is there a neater solution?

I've just learned a nice syntax for defgeneric from Pascal in another
thread and one idea is this:

(defgeneric array-type-or-nil (object)
  (:method ((object simple-array *)) (array-element-type object))
  (:method ((object t))))

(array-type-or-nil (make-array (list 10) :element-type '(unsigned-byte 8)))
-> (UNSIGNED-BYTE 8)

(array-type-or-nil 10) -> NIL

The only strange thing I don't understand is that LispWorks 4.3.7 returns
for both tests NIL, but if I use this method:

  (:method ((object array *)) (array-element-type object))

it works. But

(type-of (make-array (list 10) :element-type '(unsigned-byte 8)))

returns (SIMPLE-ARRAY (UNSIGNED-BYTE 8) (10)).

In SBCL it works with simple-array as expected.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Kalle Olavi Niemitalo
Subject: Re: getting element-type of simple-array
Date: 
Message-ID: <87wsxfvj0b.fsf@Astalo.kon.iki.fi>
Frank Buss <··@frank-buss.de> writes:

> (defgeneric array-type-or-nil (object)
>   (:method ((object simple-array *)) (array-element-type object))
>   (:method ((object t))))

There are two problems with that.

1. ((object simple-array *)) is not valid syntax for a
   specialized lambda list.  As no lambda list keywords are
   present, each element should be either var or (var
   [specializer]).  Three-element lists are allowed only
   after &OPTIONAL or &KEY.  The Lisp is probably ignoring
   the extra element.

2. SIMPLE-ARRAY is not listed in figure 4-8 in section 4.3.7
   (Integrating Types and Classes), so there doesn't have to
   be a class with that name.  But specializers in the lambda
   list must be names of classes or (eql ...) lists.  Not all
   type specifiers are allowed.

For a function that is defined for all values up front and cannot
ever be extended, I think TYPECASE is more appropriate than
DEFGENERIC.  TYPECASE gets the precedence of clauses from the
order they are listed, rather than from class precedence lists,
so it can support the entire syntax of type specifiers.
From: Kalle Olavi Niemitalo
Subject: Re: getting element-type of simple-array
Date: 
Message-ID: <871wfnx01l.fsf@Astalo.kon.iki.fi>
Tamas Papp <······@gmail.com> writes:

> (let ((type (type-of elements)))
>   (if (eq (first type) 'simple-array)
>       (second type)
>       nil))
>
> but it looks like a kludge.  Is there a neater solution?

SBCL 0.9.5.50:
(type-of (make-array 3 :element-type 'bit))
=> (simple-bit-vector 3)

So it is not good to make assumptions on the format of type
specifiers returned by TYPE-OF.  Instead:

(if (typep elements 'simple-array)
  (array-element-type elements)
  nil)

SBCL inlines this TYPEP check, so it is probably faster too.
From: Tamas Papp
Subject: Re: getting element-type of simple-array
Date: 
Message-ID: <87sl835qcq.fsf@pu100877.student.princeton.edu>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> Tamas Papp <······@gmail.com> writes:
>
>> (let ((type (type-of elements)))
>>   (if (eq (first type) 'simple-array)
>>       (second type)
>>       nil))
>>
>> but it looks like a kludge.  Is there a neater solution?
>
> SBCL 0.9.5.50:
> (type-of (make-array 3 :element-type 'bit))
> => (simple-bit-vector 3)
>
> So it is not good to make assumptions on the format of type
> specifiers returned by TYPE-OF.  Instead:
>
> (if (typep elements 'simple-array)
>   (array-element-type elements)
>   nil)
>
> SBCL inlines this TYPEP check, so it is probably faster too.

Thanks everyone, I decided to use Kalle's solution.

Tamas