Skip to content

Instantly share code, notes, and snippets.

@bowbow99
Created July 15, 2010 12:30
Show Gist options
  • Save bowbow99/476876 to your computer and use it in GitHub Desktop.
Save bowbow99/476876 to your computer and use it in GitHub Desktop.
;;; setf'able な PLACE を一時的に変更して BODY を評価する
(defmacro letf (bindings &body body)
(let ((originals (mapcar (lambda (x) (gensym)) bindings)))
`(let (,@(mapcar (lambda (sym x) `(,sym ,(car x)))
originals
bindings))
(unwind-protect
(progn
(setf ,@(mapcan #'identity bindings))
,@body)
(setf ,@(mapcan (lambda (b o)
`(,(car b) ,o))
bindings
originals))))))
@bowbow99
Copy link
Author

思いついたので作ってみたけどちょっとキモい。

;;; サンプル
(defstruct foo a b)
=> #<structure-definition: foo>

(defun print-foo (foo)
  (format t "#<foo :a ~S :b ~S>" (foo-a foo) (foo-b foo)))
=> print-foo

(setq x (make-foo :a "A" :b "B"))
=> #S(foo a "A" b "B")

(print-foo x)
#<foo :a "A" :b "B">
=> nil

(letf (((foo-a x) "えー")
       ((foo-b x) "びー"))
  (print-foo x))
#<foo :a "えー" :b "びー">
=> nil

(print-foo x)
#<foo :a "A" :b "B">
=> nil

x
=> #S(foo a "A" b "B")

@bowbow99
Copy link
Author

@bowbow99
Copy link
Author

let と let* 的な意味で psetf の方がいいかも
let みたいに値を省略してカッコ外すのはできない。下の (ACC-2 X) が PLACE なのか (PLACE VALUE) なのか判断できないんで。

(letf (((ACC-1 X) VALUE-1)
       (ACC-2 X))
  ...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment