dfan is right, this isn't going to swap the two values.
The reason you are getting that error though is that this:
(progn
((setf tmp a)
(setf a b)
(setf b tmp)))
should be this:
(progn
(setf tmp a)
(setf a b)
(setf b tmp))
The first progn has one s-expression in the body, and it's treated
as an application of the function (setf tmp a). In Common Lisp, I
think that only variables or lambda forms can be in the function
position of an application. I could be wrong about the details here,
but I know there are restrictions in CL that aren't in Scheme. That's
why it's an illegal call.
For instance, this is illegal in CL and results in the same error:
CL-USER> ((if (< 1 2) #'+ #'*) 2 3)
; in: LAMBDA NIL
; ((IF (< 1 2) #'+ #'*) 2 3)
;
; caught ERROR:
; illegal function call
;
; compilation unit finished
; caught 1 ERROR condition
You COULD write a swap as a macro (WARNING: I'm a Lisp noob, this
might be a terrible reason for a macro and a poorly written one!)
(defmacro swap (a b)
(let ((tmp (gensym)))
`(progn
(setf ,tmp ,a)
(setf ,a ,b)
(setf ,b ,tmp))))
Nope! Don't do this. Use rotatef as Terje Norderhaug points out.
swap-valueare passed by value, so they won't affect the bindings outside the call;(swap-value x y)will pass in the values of x and y, having no effect on whatxis bound to. To get the effect you want, you will have to write a macro.setfis the Lisp way to do value assignment, but it's not the way to introduce global variable. You should usedefvarordefparameterfor introducing global (and special, aka dynamic variables). This is a bit too complicated to explain in a comment, but check out Practical Common Lisp: gigamonkeys.com/book/variables.htmlsetffor assignments. I suggest taking a moment when usingsetfto consider whether there are more idiomatic ways to implement the same functionality. Like usingletto bind a local variable.