#:g1: 実践SETF定義: defsetf長形式篇

Posted 2018-12-07 18:38:26 GMT

Lisp SETF Advent Calendar 2018 8日目 》

実践編今回は、defsetfの長形式篇です。

前回、defsetfの短形式を紹介しましたが、短形式では、引数の順番等の条件がうまく嵌ればとても簡潔に書けます。
しかし、そうはいかない場合もあるのと、仮引数で&optional&key等々と指定したい場合にdefsetfの長形式を使うことになります。

短形式と同じ例ですが、こんなゲッターとセッターの対があった場合、

(defun kar (list)
  (car list))

(defun set-kar (list val) (rplaca list val))

(let ((u (list 0 1 2))) (set-kar u 42) (list u (kar u)))((42 1 2) 42)

(defsetf kar (list) (val)
  `(set-kar ,list ,val))

のように、普通のマクロ定義のような感じで書けます。

(let ((u (list 0 1 2)))
  (setf (kar u) 42)
  (list u (kar u)))((42 1 2) 42) 

引数宣言の順番も、setfが使われる場合の引数の順番と同じなので迷うこともないでしょう。

短形式では、非常に簡潔に書けました、

(defsetf kar set-kar)

しかし、長形式で明示的に書かれていた方が判り易いですね。

defsetfで定義できるものは基本的にセッターとゲッターが存在し、それが対称に動作しているものになります。

defsetfで扱えないようなイレギュラーなものは、最も汎用的なsetf定義オペレーターである、define-setf-expanderget-setf-expansionを駆使することになります。

アドベントカレンダーの後半ではイレギュラーなsetf定義でも紹介していこうかなと思います。


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus