#:g1: Lispとエディタ (2)

Posted 2015-06-27 15:58:17 GMT

 前回1960年代の環境について書いたので今回は1970年代のEmacsを書こうと思いましたが、1966年発表のBBN-LISPの環境がどうもエポックメイキングな感じなので、これも調べてみました。

BBN-LISPは、1966年に登場した処理系で後にInterlispへと繋る処理系です。

色々と先進的な所がありますが、エディタ+開発環境という点に関しては、

という点が特長です。

editf、editv、edite (1966)

前回紹介したBinfordエディタは1969年にMacLISPとの統合ということなので、恐らくそれより以前からあるのだろうと思いますが、BBN-LISPのeditfは1966年ということなので、私が確認できた限りでは一番古いLISP内蔵型のS式エディタです。
editfは関数、editvは変数、editeはリストデータの編集のようです。

エディタの機能については上記のマニュアルに詳しいのですが、主なコマンドは下記の通り。

移動

編集

表示

位です。

数値を指定して移動というのがBinfordエディタと違い、また検索がないですが、操作感としてはBinfordエディタより使い易い印象です。

UNDO

エディタでの編集は、内部的には、rplaca/rplacdでリストを破壊的に変更して行くので、保存する機能がないと何か間違いがあっても元に戻せません。
このため、COPYとRESTOREコマンドによってデータの保存を行ないます。
後々は、UNDOまで進化するようですが、UNDOというより手動セーブです。まあ、無いよりはましという所です。

セッション例

BBN-LISPの環境は確認できないのですが、後継のInterlisp-10にeditfが引き継がれているようなので、takを定義しているセッションを例として紹介してみます。
lessp {in tak} -> LESSP ? yesのようなものはInterlispのDWIMが機能して修正されている箇所です。
Interlispは大文字と小文字を区別しますが、Common Lispの標準のようにreadが大文字に畳み込むことはないので、DWIMがlesspという関数がないけれど、LESSPなら存在するので修正するか?という問い合わせが発生しています。
=というのも修正した、という意味です。

以下、;以降はコメントです。

INTERLISP-10  31-Dec-84 ...
Hello.    ;挨拶。ハロウィンやクリスマス等で挨拶が変わったりする 
3_(defineq(tak(x y z)(tak))) ; 大まかに定義してみる
=DEFINEQ
(tak)
4_editf(tak) ; editf起動。evalquote形式も受け付ける。
=EDITF
edit
1*p ;表示
(LAMBDA (x y z)   **COMMENT**   (tak))
1*4 p ;4番目を表示
(tak)
2*(n (tak (sub1 x) y z)) ; nで(tak (sub1 x) y z)を最後に追加
=N
3*p
(tak (tak & y z))
3*(n (tak (sub1 y) z x))
=N
4*(n (tak (sub1 z)x y))
=N
5*0
6*p
(LAMBDA (x y z)   **COMMENT**   (tak & & &))
6*(p 0 10)
=P
(LAMBDA (x y z)   **COMMENT**   (tak (tak (sub1 x) y z) (tak (sub1 y) z x) (tak 
(sub1 z) x y)))
7*(li 4) ;if〜を記述していなかったので、まず括弧を追加
=LI
8*
p
(LAMBDA (x y z)   **COMMENT**   (&))
8*4 p
((tak & & &))
9*(-1 if) ;先頭にifを挿入
10*p
(if (tak & & &))
10*(n then z else##
(-2 (lessp y x) then)
11*p
(if (lessp y x) then (tak & & &))
11*(-4 z)
12*p
(if (lessp y x) then z (tak & & &))
12*(-5 else)
13*p
(if (lessp y x) then z else (tak & & &))
13*0
14*0 p

can't - at top. 14*p (LAMBDA (x y z) **COMMENT** (if & then z else &)) 14*(p 0 100) =P (LAMBDA (x y z) **COMMENT** (if (lessp y x) then z else (tak (tak (sub1 x) y z) (tak (sub1 y) z x) (tak (sub1 z) x y)))) 15* ; エディタを^Dで抜けてtakを実行してみる

5_(tak 18 12 6) lessp {in tak} -> LESSP ? yes ;DWIMがスペル修正 sub1 {in tak} -> SUB1 ? yes sub1 {in tak} -> SUB1 ? ...yes sub1 {in tak} -> SUB1 ? yes 6 ; おや、結果が7でない。LESSPではなくて、(NOT (GREATERP))の間違いだった。 6_redo 4 ; コマンド番号4を再実行 edit 15*(## 4 16*p (if (LESSP y x) then z else (tak & & &)) 16*2 16*p (LESSP y x) 16*(1 greaterp) 17*p (greaterp y x) 18*(LI 1) 18*p ((greaterp y x)) 18*(-1 NOT) ; エディタを^Dで抜けてtakを実行してみる

14_redo 5 greaterp {in tak} -> GREATERP ? yes 7 15_(prettyprint '(tak)) ;prettyprintで定義を表示してみる =PRETTYPRINT

(tak [LAMBDA (x y z) **COMMENT** (if (NOT (GREATERP x y)) then z else (tak (tak (SUB1 x) y z) (tak (SUB1 y) z x) (tak (SUB1 z) x y]) (tak) 15_(prettydef '(tak)) ;prettydefの場合(DEFINEQが付く) =PRETTYDEF (DEFINEQ

(tak [LAMBDA (x y z) **COMMENT** (if (NOT (GREATERP x y)) then z else (tak (tak (SUB1 x) y z) (tak (SUB1 y) z x) (tak (SUB1 z) x y]) ) T

エディタはLispで実装されている

BBN-LISPの文献にはeditのソースが記載されていますが、Lispで実装されています。
Lispで実装されているということは、Lispで拡張することも可能ということで、もしかしたら最初期のユーザーがカスタマイズ可能エディタかもしれません。

ちなみにBinfordエディタですが、こちらはアセンブリ(MIDAS)で記述されていてLispではエディタを拡張できないようです。

Pretty Print

上のセッションでも紹介していますが、prettyprintや、prettydefという整形ツールが標準で装備されています。
これも最初期のものではないでしょうか。
BBN-LISPの文献のLispソースも綺麗に整形された状態で載っていますが、半世紀前の時点で手作業でインデントを調整するようなことはしていなかったようです。

まとめ

以上、BBN-LISPの1966年当時としてはとても先進的な機能を紹介してみました。

という点では、当然ながらメモ帳+REPLより全然強力です。
半世紀前の時点で既に、括弧の対応管理とインデントの調整は人間の仕事ではなくなっていたことが分かるかと思います。

BBN-LISPには、他に特筆すべき事項として、trace関数等もありますが、今回は、エディタの考察なのでまた別の機会にでも考察してみたいと思います。

次回こそは、1970年あたりのEmacsを考察してみたいと思います。


HTML generated by 3bmd in SBCL 1.2.12

comments powered by Disqus