I want to define a method that will specialize on an object of array type with unsigned byte 8 elements. In sbcl, when you (make-array x :element-type '(unsigned-byte 8))
the object class is implemented by SB-KERNEL::SIMPLE-ARRAY-UNSIGNED-BYTE-8. Is there an implementation independent way of specializing on unsigned-byte array types?
Common Lisp has a complete and flexible type system and corresponding tools to inspect, check and manipulate types. It allows creating custom types, adding type declarations to variables and functions and thus to get compile-time warnings and errors.
Numbers are represented by the symbol number. Lisp has two types of numbers: integer and floating-point.
In LISP, an array element is specified by a sequence of non-negative integer indices. The length of the sequence must equal the rank of the array. Indexing starts from zero. The aref function allows accessing the contents of the cells.
A generic function is a lisp function which is associated with a set of methods and dispatches them when it's invoked. All the methods with the same function name belong to the same generic function. The defmethod form is similar to a defun .
Use a sharpsign-dot to insert the implementation dependent object class at read-time:
(defmethod foo ((v #.(class-of (make-array 0 :element-type '(unsigned-byte 8)))))
:unsigned-byte-8-array)
The sharpsign-dot reader macro evaluates the form at read-time, determining the class of the array. The method will be specialized on the class the particular Common Lisp implementation uses for the array.
Notice that the :ELEMENT-TYPE
argument to MAKE-ARRAY
does something special and its exact behavior might be a bit surprising.
By using it, you are telling Common Lisp that the ARRAY should be able to store items of that element type or some of its subtypes.
The Common Lisp system then will return an array that can store these elements. It may be a specialized array or an array that can also store more general elements.
Notice: it is not a type declaration and it will not necessarily be checked at compile or runtime.
The function UPGRADED-ARRAY-ELEMENT-TYPE
tells you what element an array may actually be upgraded to.
LispWorks 64bit:
CL-USER 10 > (upgraded-array-element-type '(unsigned-byte 8))
(UNSIGNED-BYTE 8)
CL-USER 11 > (upgraded-array-element-type '(unsigned-byte 4))
(UNSIGNED-BYTE 4)
CL-USER 12 > (upgraded-array-element-type '(unsigned-byte 12))
(UNSIGNED-BYTE 16)
So, Lispworks 64bit has special arrays for 4 and 8 bit elements. For 12 bit elements it allocates an array which can store up to 16bit elements.
We generate an array which can store ten numbers of upto 12 bits:
CL-USER 13 > (make-array 10
:element-type '(unsigned-byte 12)
:initial-element 0)
#(0 0 0 0 0 0 0 0 0 0)
Let's check its type:
CL-USER 14 > (type-of *)
(SIMPLE-ARRAY (UNSIGNED-BYTE 16) (10))
It is a simple array (non-adjustable, no fill pointer).
It can store elements of type (UNSIGNED-BYTE 16)
and its subtypes.
It is of length 10 and has one dimension.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With