#:g1: 拡張setf定義を眺める: 解構篇

Posted 2018-12-17 21:05:17 GMT

Lisp SETF Advent Calendar 2018 18日目 》

今回は、処理系拡張のsetfのうち解構destructuring系の拡張を眺めてみたいと思います。

destructuringの邦訳語はいまいち一定しない感がありますが、中華圏では、ほぼ、解構destructuringで通っているようです。

解構destructuringは短くて意味の通りも良い気がするので、本記事では、解構destructuringで通します。
(しかし流行らなそうな言葉の響き……)

解構destructuring拡張のsetfとは

setf場所place解構destructuringを使うという拡張です。
Lisp Machine Lispには標準装備だったみたいですが、Common Lispで実装している処理系はないかもしれません。
ということで、以下は、Lisp Machine Lispでの例の紹介です。
(Common Lispでも定義はできます)

(setf list)

これまで、左辺値についてCPLを調べたりもしましたが、CPLは左辺にリスト構文が取れたりしました。

x, y, z := 0, 1, 2

これをそのままsetfで書いた感じです。

(let (x y z)
  (setf (list x y z) '(0 1 2))
  (list x y z))(0 1 2)

(setf cons) / (setf list*)

conslist*も使えます。

(let (x y)
  (setf (cons x y) '(0 1 2))
  (list x y))(0 (1 2))

(let (x y z) (setf (list* x y z) '(0 1 2)) (list x y))(0 1 (2))

(setf `(,foo ,@bar))

バッククォート式も使えます。
但し、appendの形には対応していないので、,@はリストの最後の部分にしか使えません。

(let (x y)
  (setf `(,x ,@y) '(0 1 2))
  (list x y))(0 (1 2))

(let (x y z) (setf `(,x ,y ,@z) '(0 1 2)) (list x y))(0 1 (2))

appendの形には対応していないものの、入れ子にすることは可能です。

(let (a b c d e f)
  (setf `(,a (,b (,c ,@d) ,e ,@f))
        `(a (b (c d d d) e f f f)))
  (list a b c d e f))(a (b (c (d d d) e (f f f))))

listlist*consも同様

(let (a b c d e f)
  (setf (list (list* (cons c d) e f))
        `(a (b (c d d d) e f f f)))
  (list a b c d e f))(a (b (c (d d d) e (f f f))))

まとめ

setfとバッククォートの組み合わせはなかなか良いんじゃないかと思うのですが、実際の所、あってもそんなに利用頻度は高くなさそうですね。


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus