Posted 2015-06-27 15:58:17 GMT
前回1960年代の環境について書いたので今回は1970年代のEmacsを書こうと思いましたが、1966年発表のBBN-LISPの環境がどうもエポックメイキングな感じなので、これも調べてみました。
BBN-LISPは、1966年に登場した処理系で後にInterlispへと繋る処理系です。
色々と先進的な所がありますが、エディタ+開発環境という点に関しては、
という点が特長です。
前回紹介したBinfordエディタは1969年にMacLISPとの統合ということなので、恐らくそれより以前からあるのだろうと思いますが、BBN-LISPのeditfは1966年ということなので、私が確認できた限りでは一番古いLISP内蔵型のS式エディタです。
editfは関数、editvは変数、editeはリストデータの編集のようです。
エディタの機能については上記のマニュアルに詳しいのですが、主なコマンドは下記の通り。
(n exp)
► listのn番目(1オリジン)を置き換える。-nの場合は、n番目の要素の前に挿入。(n)のみだとn番目の要素を削除(N e1 e2...)
► リストの最後に要素を挿入。要素は複数可(LI n)
► カッコを挿入という意味。動作としては、n番目から最後までを括弧で囲む。(LO n)
► カッコを削除という意味。動作としては、n番目のリストをn-1番目と繋げる (a (b c) d)
は、(a b c)
となり後は消える(RI n m)
► コッカを挿入という意味。動作としては、n番目のリストのコッカをm番目まで移動する。(a b (c d e) f)
を(RI 3 1)
すると(a b (c) f)
となる(RO n)
► コッカを削除という意味。動作としては、n番目のリストのコッカを最後まで移動する。(a b (c d e) f)
を(RO 3)
すると(a b (c d e f))
となる(E exp)
► 式を評価した値を返す。(1 (E (list 1 2 3)))
は1番目の要素を(1 2 3)
で置き換える等、他のコマンドと組み合わせて利用できる。p
、(p n m)
► p
は、(p 0 2)
の略、n番目の要素をm階層まで表示。指定より深い階層は&で表示される位です。
数値を指定して移動というのがBinfordエディタと違い、また検索がないですが、操作感としてはBinfordエディタより使い易い印象です。
エディタでの編集は、内部的には、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 pcan'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
BBN-LISPの文献にはeditのソースが記載されていますが、Lispで実装されています。
Lispで実装されているということは、Lispで拡張することも可能ということで、もしかしたら最初期のユーザーがカスタマイズ可能エディタかもしれません。
ちなみにBinfordエディタですが、こちらはアセンブリ(MIDAS)で記述されていてLispではエディタを拡張できないようです。
上のセッションでも紹介していますが、prettyprint
や、prettydef
という整形ツールが標準で装備されています。
これも最初期のものではないでしょうか。
BBN-LISPの文献のLispソースも綺麗に整形された状態で載っていますが、半世紀前の時点で手作業でインデントを調整するようなことはしていなかったようです。
以上、BBN-LISPの1966年当時としてはとても先進的な機能を紹介してみました。
という点では、当然ながらメモ帳+REPLより全然強力です。
半世紀前の時点で既に、括弧の対応管理とインデントの調整は人間の仕事ではなくなっていたことが分かるかと思います。
BBN-LISPには、他に特筆すべき事項として、trace関数等もありますが、今回は、エディタの考察なのでまた別の機会にでも考察してみたいと思います。
次回こそは、1970年あたりのEmacsを考察してみたいと思います。
■
HTML generated by 3bmd in SBCL 1.2.12