1721527083
2024-07-21 01:04:02
あ 最近の投稿 アラン・ケイの言葉を引用 声明 Lispを表現すること自体が「ソフトウェアのマクスウェル方程式「:」
はい、大学院生の頃、私にとってそれは大きな発見でした。Lisp 1.5 マニュアルの 13 ページ下部にある半ページのコードが Lisp そのものであることをようやく理解したときです。これらは「ソフトウェアのマクスウェル方程式」だったのです。
この引用文はウェブ上の多くの場所で見かけますが、コードそのものを見つけるのは困難です。 は この驚くべき半ページのコードは何ですか?
1961年にジョン・マッカーシーらによって書かれたLisp 1.5マニュアルは、以下から入手可能です。 ソフトウェア保存.orgその中で、「マクスウェル方程式」は普遍的なLisp関数を定義している。 evalquote 任意の関数を評価できる:
evalquote[fn;x] = apply[fn;x;NIL]
どこ
apply[fn;x;a] =
[atom[fn] -> [eq[fn;CAR] -> caar[x];
eq[fn;CDR] -> cdar[x];
eq[fn;CONS] -> cons[car[x];cadr[x]];
eq[fn;ATOM] -> atom[car[x]];
eq[fn;EQ] -> eq[car[x];cadr[x]];
T -> apply[eval[fn;a];x;a]];
eq[car[fn];LAMBDA] -> eval[caddr[fn];pairlis[cadr[fn];x;a]];
eq[car[fn];LABEL] -> apply[caddr[fn];x;cons[cons[cadr[fn];
caddr[fn]];a]]]
eval[e;a] = [atom[e] -> cdr[assoc[e;a]];
atom[car[e]] ->
[eq[car[e],QUOTE] -> cadr[e];
eq[car[e];COND] -> evcon[cdr[e];a];
T -> apply[car[e];evlis[cdr[e];a];a]];
T -> apply[car[e];evlis[cdr[e];a];a]]
evcon[c;a] = [eval[caar[c];a] -> eval[cadar[c];a];
T -> evcon[cdr[c];a]]
evlis[m;a] = [null[m] -> NIL;
T -> cons[eval[car[m];a];evlis[cdr[m];a]]]
上記のコードはメタ言語(M式)で定義されており、S式に簡単に変換できます。M式の関数は角括弧を使用し、引数はセミコロンで区切られます。M式の条件文は次の形式です。 [predicate -> value; predicate -> value; ...]. M式 label は、 defun または define。
ここで重要なのは、M 式は S 式データを操作するコードであるが、M 式メタ言語と S 式データは実際には一致するということです。したがって、コードとデータは Lisp では同じものであり、Lisp でいくつかのプリミティブ (car, cdr, cons, eq, atom)。このコードは、 メタ循環評価者 Lispについては、(SICP 章 4.1 メタ循環評価器の詳細については、 を参照してください。(残念ながら、これによって Lisp インタープリタが無料で動作するわけではありません。ガベージ コレクタ、リスト プリミティブ、解析などは、どこかで実装する必要があります。また、このメタ循環評価器では、算術演算などの細かい機能は提供されないことに注意してください。))
上記のコードを理解するには、 apply 関数と引数を取りますが、 eval フォームに作用します。これらの最後の引数は環境の連想リストで、バインドされた値と関数名が格納されます。簡単に言うと、 apply 実装する CAR、 CDR、 CONS、 ATOM、 そして EQ プリミティブの観点から。 LAMBDA 変数と引数をペアにして渡すことで eval実装する LABEL (関数を定義する) 関数名と定義を連想リストに追加します。
コードは eval フォームを簡単な方法で処理します。 QUOTE 引用符で囲まれた値を返すことでフォームを処理します。 COND 述語を評価することによって evconそれ以外の場合は、アトムを変数として解釈し、その値を返します。リストが与えられた場合は、これを関数適用として解釈し、引数は次のように評価されます。 evalis そして関数は次のように評価される。 apply。
上記のコードは完全ではありません。マニュアルで以前に定義されたいくつかの単純な関数に依存しています。 equals そして cadr あまり知られていない機能は pairlis[x;y;a] リストをペアにする x そして y それらを関連リストに追加する a。 assoc[x;a] 見上げる x 関連リスト a。 sublis[a;y] 関連リストを扱う a 変数から値へのマッピングとして、S式内の変数を置き換えます y 関連する変数とともに。これらの関数は、プリミティブ関数から直接構築できます。
(ところで、 eq[car[e],QUOTE] (これはタイプミスですが、原文ではそのようになっています。)
#ソフトウェアのマクスウェル方程式の検討