2007-11-12
■ [lisp] M式
最近知ったのだが、Lispの初期にはS式の他にM式という記法が考えられていたらしい。
「コンピュータプログラムの世界において M式 (meta-expressions) は、 Lisp言語の一部として、S式の人間が読むことの出来る形態となることを目的に考えられた。 M式はLispの初期の論文において理論的な言語として使われていたが、実際に実装されることはなかった。 」
S式は人間が読むもんじゃないのかよwとツッコミたくなりますね。
実行前にS式に変換するから「meta-expression」と名づけられた模様。
[1, 2, 3] (quote (1 2 3)) or '(1 2 3) car[X] (car X) car[append[[1,2,3], [4,5,6]]] (car (append '(1 2 3) '(4 5 6))) 1 + [2 * 3] (plus 1 (times 2 3))
こっちの方がだいぶ「普通」なんだけど、LispプログラマはすぐにS式に慣れてしまったので M式は普及しなかったみたいです。 S式はプログラムとデータが同じ構造をしている(ので、マクロが使いやすい)けど、M式はそうじゃないですからね。
ところでこれ、じっと眺めていると関数型言語Rubyのコードに見えてきませんか? *1
*1 「callうざい」とよく言われるのだけど、実はProc#[]でも関数オブジェクトを起動できる
■ [ruby] M式がRubyに見えてしかたがないので
ということで、M式で書かれたLispプログラムを実行するインタプリタをRubyで書いてみた。
require 'mexp' Mexp.eval{ DEFINE[length, LAMBDA[[ls], IF[NULLP[ls], 0, +[1, length[CDR[ls]]] ] ] ] DISPLAY[length[[1,2,3,4,5]]] }
実行すると画面に「5」と出力します。
mexp.rbの実装はこちら:
制限:
- 予約語は大文字で書きます。"if"を小文字で書くとパースエラーになってしまうので、泣く泣く。
- 変数は小文字で書きます。こっちはconst_missingあたりでなんとかなるかも。
- 整数とリストとCARとCDRと+しかありません。あとNULLP。
- プログラムはいくつかのDEFINEと、ひとつの本体から成るものとします。
- いまWikipedia見たら、+は中置記法なんだった。そりゃそうか。しまった。まあいいや。
■ [lisp] L式
http://en.wikipedia.org/wiki/M-expression によると、さらにsrfi-49のインデントベースLispが L式 (l-expression) と呼ばれるらしい。 (検索しても全然出てこないんだけど…)。
define fac x if = x 0 1 * x fac - x 1
この見た目は斬新www
インデントというとpythonぽくなるのかなぁと思ったら、全然そんなことないですね。異形すぎる。
>M式<br>竹内センセの「初めての人のためのLISP」でちょっと取り上げられてました。うろおぼえですけど、「S式プログラム(てかLISP)の定義をS式でやったら、なんか両方S式だからごっちゃになって混乱するしM式っての使わねえ?」という人達もいる、みたいな話だったと思います。
おー、聞いたことがある(けど読んだことはない)書名が。<br>Lisp系の人はそういうメタな操作が得意そうですよね(根拠なし)。いや、メタが得意な人がLisperになるのかな。
Mathematicaはこれ(M式)に似てると思いますが(二重投稿かも)
確かに、角カッコで関数を呼び出すところとか似ていますね。<br>http://documents.wolfram.com/v4-ja/MainBook/2.8.14.html<br>何か関係があるのでしょうか…。
二年前のブログにコメントですが(はてぶで発見)、<br>私が初めて読んだLISPの本 http://www.amazon.co.jp/dp/B000J8WJIO の初版はM式で解説されてました。第二版で全面的にS式に書き直された。その数年間に風向きが変わったんでしょうね。
lispのプログラムを処理するプログラムを記述するとき、<br>M式とS式の記述を両方同時に使うのが非常に解りやすいので<br>個人的には必須なのですが、このようなプログラムを<br>常時書いている人は少ないのかな。