When I run this function from a listener in LispWorks, it either crashes the listener or gives an exception and assembly language data. Can anyone tell me what's wrong with it?
(defun should-flip-block (rowlist)
(declare ((vector number) rowlist))
(if (= (length rowlist) 0) (eval nil)
(let* ((exithigh (= (car (last rowlist)) 2))
(enterhigh (= (first rowlist) 2)))
(and exithigh enterhigh))))
It's called as (should-flip-block '(1 2 1 2 1))
.
Problematic declaration
Note that not all Common Lisp implementations will think that (declare ((vector number)) rowvector)
is a valid declaration.
Write instead (declare (type (vector number) rowvector))
.
Wrong: a list is not a vector
The problems you see is because you lied to the implementation and safety
is set low. You told Lisp that the argument is a vector, but you pass a list (which is not a vector).
The function then use calls to FIRST
and LAST
, which don't work on vectors, but lists.
Run code with higher safety
value
Don't run Common Lisp by default with low safety. Use a default safety value of 2 or 3.
Using LispWorks 6.1.1:
CL-USER 43 > (proclaim '(optimize (safety 2)))
NIL
now I recompile the function and then call it:
CL-USER 44 > (should-flip-block '(1 2 1 2 1))
Error: Variable ROWLIST was declared type (VECTOR NUMBER) but is being
bound to value (1 2 1 2 1)
1 (abort) Return to level 0.
2 Return to top loop level 0.
Now you see an useful error and not a segment violation.
Literal Vectors
#(1 2 1 2 1)
is a vector.
Note: LIST
type has no parameter
Note that a type (list number)
does not exist in Common Lisp and can't be defined. The type list
can't have a parameter. It's also not possible to define such a type based on the type cons
- recursive types don't work.