#:g1: 実践SETF定義:ローカルなsetf

Posted 2018-12-15 19:31:30 GMT

Lisp SETF Advent Calendar 2018 16日目 》

今回は、ローカルスコープでのsetf定義について考えてみます(ネタがないから)

ローカルスコープでsetfとは

ANSI Common Lispでは、(setf fn)という関数名が使えるということは以前解説したのですが、これはflet/labelsでも勿論使えます。
つまり、ローカルスコープ限定でsetfフォームが書けるということになります。

#'(setf fn)

(let ((u (list 0 1 2 3 4)))
  (flet (((setf kar) (val cons)
           (rplaca cons val)))
    (setf (kar u) 42)
    u))(42 1 2 3 4) 

Macro Forms as Placesのローカル版

macroletはローカルスコープのマクロを作りますが、Macro Forms as Placesもまたローカルで成立することになります。

(let ((u (list 0 1 2 3 4)))
  (macrolet ((kar (list)
               `(car ,list)))
    (setf (kar u) 42)
    u))(42 1 2 3 4) 

defsetfdefine-setf-expanderで定義するもののローカル版

setfletや、setf-expander-bindのような、そのボディ内でsetfフォームが書けるような構文を定義しない限り、無理ではないかなと思います。
特にdefine-setf-expanderの方はmacroletにちょっと細工する位では実現が無理に思えるので、コードウォーカーを駆使する他なさそうです。

まとめ

まあ、ローカルのsetfは、ほぼ使うこともないのですが、setfletや、setf-expander-bindのようなものを作ってみるのは、上級マクロ学習の良い題材になりそうな気はします。
興味のある方は試してみては如何でしょうか。


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus