一時変数を使わずに値を交換する


Tag: 制御構造

一時変数を使わずに値を交換する

様々な方法がありますが、主にrotatefを使う方法が一般的でしょう。 下記はそれぞれマクロで結果は大体同じようなものに展開されます。

(let ((x 10) (y 20))
  (rotatef x y)
  (list x y))
;=> (20 10)

(let ((x 10) (y 20))
  (psetq x y y x)
  (list x y))
;=> (20 10)

(let ((x 10) (y 20))
  (setf (values x y) (values y x))
  (list x y))
;=> (20 10)

(let ((x 10) (y 20))
  (multiple-value-setq (x y) (values y x))
  (list x y))
;=> (20 10)

まれにprog2を利用したコードに遭遇することがありますが、Common Lisp以前のイディオムです。

;; 太古のイディオム
(let ((x 10) (y 20))
  ;; 太古にはprog1が存在しなかったためprog2
  (setq x (prog2 nil y (setq y x))) 
  (list x y))
;=> (20 10)