In Common Lisp I can check a type like:
(typep #(1 2 3) 'sequence)
;; returns T
And so I can use sequence
in (declaim (ftype ...
to specify a parameter of a function.
Is it possible to make the type even more specific and force a parameter to be a vector
from fixnum
?
Example:
(declaim (ftype (function (fixnum) sequence) abc))
(defun abc (n) #(n))
This function and its type definition works as expected. But can I define the return type more specific? Instead of sequence
something like (vector fixnum)
?
Possible type declarations for vectors
The Common Lisp HyperSpec provides an overview of type specifiers.
We can follow through the table there to the system class vector.
This tells us that we can use vector
as a Compound Type Specifier:
vector [{element-type | *} [{size | *}]]
Above is a syntax definition.
So declarations can use vector
types like:
(vector) ; any vector
(vector *) ; any vector
(vector * *) ; any vector
(vector fixnum *) ; vector of fixnums of any size
(vector * 42) ; vector of length 42
(vector fixnum 42) ; vector of fixnums and vector length 42
If you move the class chain upwards, you can see that the system class sequence does not provide such a syntax.
Note on returning a vector
If you write (defun abc (n) #(n))
, then it won't return the argument, but the symbol n. Elements of a literal vector are not evaluated.
CL-USER 24 > (defun abc (n) #(n))
ABC
Above returns a literal vector of a symbol. literal also means that you should not modify it.
CL-USER 25 > (abc 42)
#(N)
There is a backquote syntax for vectors:
CL-USER 26 > (defun abc (n) `#(,n))
ABC
CL-USER 27 > (abc 42)
#(42)
We can also call the function vector
, which will create a vector with the argument values as its contents.
CL-USER 28 > (defun abc (n) (vector n))
ABC
CL-USER 29 > (abc 42)
#(42)