#:g1: M式の魅力の無さについて

Posted 2021-05-14 01:29:23 GMT

LispといえばS式ですが、S式について語られる際には大抵はM式も一緒に話題にのぼります。
M式は実際の所、正式な仕様は存在しないので処理系製作者が独自に拡張したものをM式としていたことが多いようですが、今回は、そんなM式の魅力の無さについて考えてみましょう。

魅力の無さ その1: 別に中置記法ではない

前置記法のS式を比較対象とするからか、M式は中置記法といわれますが、中置の文法ではっきり決まっていそうなのは関数定義のdefineの=/位と、conldで使われる位で、あとは前置ですし、ユーザー定義の関数は前置です。
後のプログラミング言語のようにユーザーが中置の文法を定義し結合度を定義する、という機構もありません。

M式の構文自体は、当時のFORTRAN I的に書けたら良いのではないか、という程度の構想だったようですが、FORTRAN Iの構文自体がそれ程洗練されたものでもありません。

結局のところ関数名が括弧の外に出ているだけ、という感じです。

fib[n] = [greaterp[2; n] → n;
          T → plus[fib[difference[n; 1]];
                    fib[difference[n; 2]]]]

なお、本格的なプログラミング構文としては、LISP 2でのALGOL構文の採用がありますが、LISP 2は構文としてはALGOLそのものなので中置構文のリッチさに関してはLISP 2が勝るでしょう。

LISP 2

integer function fib(n); integer n;
  if n < 2 
  then n 
  else fib(n - 1) + fib(n - 2);
end;

1960年代当時の次世代LISPであるLISP 2でのALGOL構文の採用が、M式をさらに中途半端な存在にした可能性もなくはないかなと思います。

なお、1960年代に実装されたM式系の構文としては、SDS 930 LISP(1965)のM-languageや中西先生のKLISPがあります。
中西先生の文献にはM言語というのが良く出てきますが、SDS 930 LISP由来なのかもしれません。

SDS 930 LISP

fib [n] : [2 > n # n; 
          T # (fib (n - 1)) + (fib (n - 2))]

ちなみに蛇足ですが、S式はリストで式を表現しているだけなので、リストで中置記法を表現することは可能です。

((fib n) = ((2 > n) → n
            T → ((fib(n - 1)) + (fib(n - 2)))))

魅力の無さ その2: 括弧の数は少ししか減っていない

括弧は外側を囲むことによってグループ化しますが、括弧を減らす記法として、結合する記号を定義して前後を結合する中置記法や、インデントの深さによってグループ化するオフサイドルールや、引数の数を元に括弧を省略する本来のポーランド記法がありますが、上述のようにM式には極僅かしか中置構文が定義されていないので括弧の数は大してかわりません。

数学記号を中置演算子として用意すれば、括弧を減らすことは可能ですが、上述のようにユーザー定義部分は大して変化なしです。

fib[n] = [[2 > n] → n;
          T → fib[n - 1] + fib[n -  2]]]

魅力の無さ その3: 構文の括弧に[]を使っている

LISPの極初期では、構文は()とデリミタの,組み合わせで記述されていたようですが、LISP 1.5の頃には[];の組み合わせになってしまいました。

fib(n) = (greaterp(2, n) → n,
          T → plus(fib(difference(n, 1)),
                    fib(difference(n, 2))))

fib[n] = [greaterp[2; n] → n; T → plus[fib[difference[n; 1]]; fib[difference[n; 2]]]]

(),は、M式内のS式(リスト)の記法に使われることになったようですが、プログラムの記述の方をゴツくしてしまった理由は謎です。

魅力の無さ その4: 構文の記法とデータの記法が未分化

λの仮引数の後に;が必要だったりで構文というよりデータという感じがしてしまいます。
結局M式のこういう中途半端なところがS式へ吸収される原因だったのではないでしょうか。

fib = λ[[n]; 
         [greaterp[2; n] → n
          T → plus[fib[difference[n; 1]];
                    fib[difference[n; 2]]]]]

魅力の無さ その5: データの記法とプログラム構文の記法を覚えないといけない

データからプログラムを作るLispならではの問題ですが、記法が2つあるとどういうルールでどう変換するのか、を覚える必要があります。
この辺りの課題は、M式、ALGOL構文のLISP 2、Dylan、最近だとJuliaにもありますが、プログラム構文としてリッチであれば、データへ変換する際のルールも多くなり直感的でなくなるでしょうし、貧弱であれば、S式で良いじゃんということになってしまいます。

まとめ

結局S式でいいですね。

関連


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus