#:g1: TAOの!

Posted 2018-12-04 17:31:40 GMT

Lisp SETF Advent Calendar 2018 5日目 》

今回は、TAO/ELISの!!!についてです。

実の所、TAO/ELISの!!!は、setfとは挙動は似ているものの実現方法が異なったもので、Common Lispのようにマクロに展開されるものではなく、(!という特別な括弧が作る代入フォームです。

詳しくは、1986年のbit誌のマルチパラダイム言語 TAO 連載で解説されていますので興味のある方は参照してみると良いかと思います。

この!記法は、setf!になった感じですが、上述のように特殊な括弧です。

(!(car x) 42)(setf (car x) 42) 

このフォームは読み書きの場所を返すようになっている(マシンの支援あり)ので、

(!(if pred (car x) x) 42)

のようなものもsetfのような事前のマクロ定義なしに書くことが可能です。

!!の方は自己代入式といって、これも面白くて便利なのですが、フォームの結果を代入する場所を!で指定して書き込むというものです。

これを使うと(setq x (+ x 42))のような良くある代入が、

(!!+ !x 42)

のように書けます。

(!!cdr !x)(pop x)

(!!nconc !(car x) y)(setf (car x) (nconc (car x) y))

(!!delete 'a !x)(setq x (delete 'a x))

等々入り組んだ表現になる程シンプルに書けたりします。

ちなみに、このアイデアは、1979のTAO/60にはあったようで、PDP-11上に実装された初期のTAO/60について書かれた、TAO LISP についての5. 複値形式 (Double valued form)の段落で説明があります。

これによると、

複値形式の概念に思い至ったのは, ALGOL68 や Pascal のプログラムを Lisp に移し替えようとしたとき, どうしてもスムーズにいかなかった悔しい経験があったからである.

とのことなので、やはりAlgol系言語の左辺値の書法が念頭にあったようです。

記法は、TAO/ELISの!ではなく、:を使っています。
TAO/ELISでは、Common Lispに接近したため、キーワードシンボルと記法がぶつかってしまうために!になったようです。 (TAO/ELIS復活祭(2010)で竹内先生が軽く説明していました)

インタプリタの軽快な動作に力を入れていたTAO/ELISでしたが、setfのようにコンパイル前提のマクロでの実現ではない方向で工夫を凝らした代入機構の紹介でした。

ちなみにCommon Lispでも、リーダーマクロで(を再定義すれば、そこそこ似た感じに記述することは可能です。
興味のある方は挑戦されてみてはいかがでしょうか。


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus