レトロLisp探検: MLISP — #:g1

Posted 2016-12-07 15:01:00 GMT

方言の系統

主要開発者

Horace J. Enea

登場時期

特徴

ALGOL風の構文を持つLISPの試み

後続への影響

LISPの中置系構文を持つ処理系(INTERLISPのCLISPや、CGOL等)

概要

MLISPはALGOL風の構文をLISPに導入しようという処理系です。
同じ試みには、LISP 2がありますが、完成に至らなかったLISP 2とは違って実際に稼動していた様子。
LISP 2と同じトランスレータ方式ですが、LISP 2がレキシカルスコープの所、MLISPはLISP 1.6へのトランスレートなのでダイナミックスコープです。

MLISPのMが気になりますが、やはりどうもMETAのMのようです。
LISP 1.5でM-S変換が、M式→S式の所を、MLISPでは、ALGOL構文→S式 ということなのかもしれません。

MLISPの初期のコードは下記のような感じです。

% THIS PROGRAM IS AN EXAMPLE %

BEGIN NEW A,B,C,D,,I,J,L,ST; MACRO OFF "VERBOS(NIL)"; C:=(6.7*4)/3 + 2**4; A:=C CONS D; B:=<1,2,3>; B:=C:=CDR(A); B:='B; C:='( B (C.A));

PRINT (ST:="AB// 7"@DBQUOTE); PRINTSTR(ST SUBSTR<3,2>); C:=MAKATOM("ASDF//");

LAST:=#L: IF ¬L THEN NIL ELSE IF ¬CDR(L) THEN CAR(L) ELSE LAST(CDR(L));

REVERSE:=#L: BEGIN NEW I,J; FOR I I IN L DO IF ATOM(I) THEN J:=I ¢ J ELSE J:= REVERSE(I) ¢ J; RETURN(J); END;

¢cons@append¬notとなります。
代入は:=ですが、後にとなったようです。

初期のMLISPには文字列型がLISP 1.5と同様存在しないようで、"ABC"'(A B C)へと展開されるようです。

また、#A,B,C:(lambda (a b c) ...)を表します。
なかなか良いなと思っていたのですが、後期には、lambda(a,b,c);...;と何の変哲もないものに変更されてしまい、ちょっと残念。

begin〜endは、ブロックになっていて途中からの脱出はreturnで抜けます。

繰り返しは、forcollectを使いますが、Common LispのLOOP、INTERLISPのFOR並に高機能で、Common Lispの

(loop :for i :from 0 :to 10 :collect i)
;=> (0 1 2 3 4 5 6 7 8 9 10) 

のようなものは、

for i in 0 to 10 collect fn<i>;

と書けるようです。
INTERLISPのCLISPの参考文献にMLISPがあるので、INTERLISPのCLISPはMLISPのforに影響を受けているらしいです。
そうであるとすると、Common Lispのloopは、MLISP → INTERLISP(CLISP) → Lisp Machine Lisp → Common Lispという流れになります。
LISP 2でもリッチな繰り返し構文が存在しているので、ALGOL → MLISP → INTERLISP(CLISP) → Lisp Machine Lisp → Common Lispという流れなのかもしれません(ALGOLに疎くて詳細不明)
なんにしろloopの構文がALGOLっぽい由来になっていそうです。

コード例

さて、MLISPのコードの見た目ですが、Common Lispで、

(defun fib (n a1 a2)
  (cond ((= 0 n) a2)
        ((= 1 n) a1)
        (T (fib (- n 1) (+ a1 a2) a1))))

のようなものは、

expr fib (n, a1, a2);
   if n=0 then a2
   also n=1 a1
   else fib(n-1, a1+a2, a1);

と書けるようです。
else ifではなくalsoと書く所が面白い。
しかしこれもまた後期には、なんの変哲もない、else ifになってしまうようです。

Decomposition Assignment

MLISPでは、Common Lispの(cadr (caddr (car L))))L[1,3,2]と書くことができたりするのですが、さらに込み入ったことが可能な代入構文があり、MIT系でいうリストのdestructuringが可能です。

パターンマッチというものが盛んに研究されていた時代ということもあるようですが、1969年辺りということを考えるとかなり時代の先を行っていたのではないでしょうか。
例えば、

‘(_ (x y) z _) ←⊗ '(A B (C D) E F)

x ⇒ 'c y ⇒ 'd z ⇒ 'e ※ _はお馴染のプレイスホルダー

のような記法が可能です。
なお変数はダイナミックである必要があります(この時代にはありがち)

現在のCommon Lispのdestructuring-bindのようなものは、MITで1979年辺りに流行しますが、MIT系Lispの先を行くこと10年という所です。

MLISP 2

MLISPは更に進化し続け、1973年にはMLISP2が登場します。
MLISPとの完全な互換性はないものの、更に汎用的な束縛構文、ジェネレータ、さらにはバックトラック機構が追加されていて、モダンだったり謎だったりする機能が山盛りですので、興味のある方は探ってみることをお勧めします!

体験

SAILDARTではウェブブラウザから操作できるエミュレータを公開していますが、MLISP、MLISP2が起動できます。
しかしどうも起動はするものの完全な環境ではないようで機能してはいないように見えます。

simh等を利用したローカル動く環境も準備できそうですが現在調査中です。

まとめ

今回は、MLISPを紹介してみました。
色々あり過ぎて紹介し切れないので、そのうちまた機会があれば、ちょくちょくMLISPについて調べて書いてみたいと思います。
時代を先取りし過ぎた感のある処理系ですが、現在Kotlinや、Swiftあたりで導入され始めた感じの流行りの構文が40年前位にはある程度は実現されていたと思うと面白いですね。

参考文献


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus