3 ms·
About the Common Lisp section: Using fresh symbols is not enough. GENSYM creates uninterned symbols - those are not interned in a package. Thus referencing the
by lispm 12y ago
About the Common Lisp section:
Using fresh symbols is not enough. GENSYM creates uninterned symbols - those are not interned in a package. Thus referencing them in user code is not possible.
Shadowing 'SETF' in Common Lisp would be non-conforming. SBCL for example detects it and gives an error. The ANSI CL Standard, Section 11.1.2.1.2.
http://www.lispworks.com/documentation/HyperSpec/Body/11_abab.htm http://www.lispworks.com/documentation/HyperSpec/Body/11_aba...
Still for user code in macro expansions it can be a problem.
If the SWAP macro really should work with places in a semantic compatible way, then it needs to do more. Compare with the built-in ROTATEF macro. It makes sure that place subforms are only evaluated once.
? (let ((a (vector 1 2)))
(swap (aref a (print 0)) (aref a (print 1)))
a)
0
0
1
1
#(2 1)
Note that it prints 0 and 1 twice.
The built-in ROTATEF does it better: it prints them only once. This shows that the subforms are only evaluated once.
? (let ((a (vector 1 2)))
(rotatef (aref a (print 0)) (aref a (print 1)))
a)
0
1
#(2 1)
The EACH-IT macro has a bug: the body needs to be put into a PROGN. Otherwise the LOOP macro might think that parts of the body are LOOP clauses.
(defmacro each-it (list &rest body)
`(loop for it in ,list
do (progn ,@body)))
For the purposes as an example, DOTIMES would be more idiomatic, since it provides the basic stuff like declarations and goto tags. It is also the traditional iteration macro for lists.
An alternative to PROGN would be LOCALLY, which also allows declarations. Thus one could declare IT to be of a certain type, for example.