Reputation: 1330
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))
.
Upvotes: 1
Views: 349
Reputation: 60014
You declare
that rowlist
is a vector
(but treat it is a list
— using last
and first
).
This means that the compiler assumes that the object you pass to it is a vector
, so, when you pass it a list
, you get undefined behavior.
The most important thing to know about declarations in Lisp is: do not lie to the compiler. I.e., if you violate your declarations (like you just did), you will get burned.
(Additionally, you do not need to eval
nil
, and there is no need for the let*
since you are using the variables it binds just once).
Upvotes: 2
Reputation: 139261
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.
Upvotes: 3