Pascal J. Bourguignon
1/3/2016 9:35:00 AM
TwirlwT <danieltorridoverde@gmail.com> writes:
> Also the swap macro of chapter one be replaced by
>
> (defmacro swap(a b)
> `(psetq ,a ,b ,b ,a))
This swap is very defective.
I don't have the macro of chapter one, but it would have to be at least
this complex:
(defmacro swap (a b &environment env)
(multiple-value-bind (avars avals astore-vars asetter agetter)
(get-setf-expansion a env)
(when (cdr astore-vars)
(error "Can't expand ~S" a))
(multiple-value-bind (bvars bvals bstore-vars bsetter bgetter)
(get-setf-expansion b env)
(when (cdr astore-vars)
(error "Can't expand ~S" b))
(let ((atemp (car astore-vars))
(btemp (car bstore-vars))
(temp (gensym)))
;; ensure a and b subepressions (vals) are evaluated in order, once:
`(let* (,@(mapcar #'list avars avals)
(,btemp ,agetter)
,@(mapcar #'list bvars bvals)
(,atemp ,bgetter))
,asetter
,bsetter)))))
(pprint (macroexpand-1 '(swap (aref v (incf i)) (aref v (incf i)))))
--> (let* ((#1=#:g53144 v)
(#2=#:g53145 (incf i))
(#6=#:g53146 (aref #1# #2#))
(#3=#:g53147 v)
(#4=#:g53148 (incf i))
(#5=#:g53143 (aref #3# #4#)))
(ccl::aset #1# #2# #5#)
(ccl::aset #3# #4# #6#))
(let ((v (vector 1 2 3 4 5))
(i 0))
(swap (aref v (incf i)) (aref v (incf i)))
(values v i))
--> #(1 3 2 4 5)
2
(pprint (macroexpand-1 '(swap a b)))
--> (let* ((#2=#:g53131 a)
(#1=#:g53130 b))
(setq a #1#)
(setq b #2#))
(of course, a CL-isper would just use ROTATEF).
--
__Pascal Bourguignon__
Croire en l'histoire officielle, c'est croire des criminels sur parole.
-- Simone WEIL (1909-1943) philosophe Française.