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