web-dev-qa-db-ja.com

LISPマシンを構築するには、いくつのプリミティブが必要ですか? 10、7、5?

このサイトには、10個のLISPプリミティブがあると言われています。プリミティブはatom, quote, eq, car, cdr, cons, cond, lambda, label, applyです。

http://hyperpolyglot.wikidot.com/LISP#ten-primitives

スティービーは7つ(または5つ)あると考えています:

LISPのアイデアの純粋さの一部:完全なマシンを構築するには、7つ(または5つ?)のプリミティブのみが必要です。 http://steve-yegge.blogspot.com/2006/04/LISP-is-not-acceptable-LISP.html

LISPマシンを構築するためのプリミティブの最小数はいくつですか(LISPコードでeval/value関数を実行できるものなど)? (そして、それらはどれですか?)

(あなたがatom, label and applyなしで生きることができると理解できます)

77
hawkeye

Paul Grahamの7つのプリミティブのセットからマクロを構築するには、 この他の質問 を参照してください。

8
DomQ

基本述語/ F関数

McCarthy 's基本的なS-Functionと述語は次のとおりです。

  1. atom

    これは、carとcdrがリストに対してのみ定義されているために必要でした。つまり、carにアトムを与えた場合、何が起こっているのかを示すための答えを当てにすることはできません。

  2. eq

    原子間の同等性をテストするため。

  3. car

    コンスセルの前半(アドレス)を返すため。 (アドレスレジスタの内容)。

  4. cdr

    コンスセルの後半(デクリメント)を返すため。 (デクリメントレジスタの内容)。

  5. cons

    新しいコンスセルを作成する場合。アドレスの半分にはconsの最初の引数が含まれ、デクリメントの半分には2番目の引数が含まれます。

結合する:S-Function

次に、基本的な表記法に加えて、S-Functionと呼ばれるものを記述できるようにしました。

  1. quote

    評価せずに式を表すこと。

  2. cond

    前述の述語で使用される基本的な条件。

  3. lambda

    関数を示します。

  4. label

    彼は再帰のためにこれを必要としませんでしたが、 Y-CombinatorPaul Grahamによると )については知らなかったかもしれません。再帰。


したがって、彼が実際にLISPマシン用に9つの基本的な「演算子」を定義したことがわかります。あなたの質問の別の1つに対する以前の回答で、このシステムで 数値を表現して操作する がどのようにできるかを説明しました。

しかし、この質問に対する答えは、実際にLISPマシンに何を求めているかによって異なります。 label関数なしで実装することができます。単純に機能的にすべてを構成し、Yコンビネーターを適用することで再帰を取得できます。

atomを返すようにアトムにcar演算を定義した場合、NILは破棄される可能性があります。

基本的に、これら9つの定義済みプリミティブのうち7つを備えたMcCarthyのLISPマシンを使用できますが、自分に課したい不便さによっては、より簡潔なバージョンを表面的に定義することもできます。私は彼のマシンが非常にすばらしいか、Clojureのような新しい言語の多くのプリミティブが好きです。

58
Isaac

これを確実に知る最良の方法は、実装するかどうかです。私は3つの夏を使用して Zozotez を作成しました Brainfuck で実行されるMcCartyっぽいLISPです。

私は必要なものを見つけようとしました、そしてフォーラムであなたは言うスレッドを見つけます ラムダだけが必要です。 したがって、あなたが望むラムダ計算でLISP全体を作ることができます。面白いと思いましたが、最終的に副作用があり、現実の世界で機能するものが必要な場合は、それが難しい方法です。

チューリング完全なLISPの場合、私は マッカーシーの論文のポールグラハムズの説明 を使用しました。

  • シンボル評価
  • 特別フォーム見積もり
  • if(またはcond)の特別な形式
  • 特別な形式のラムダ(引用と同様)
  • 関数eq
  • 関数アトム
  • 関数の短所
  • 機能車
  • 関数cdr
  • function-dispatch(list-lambda)

その10。これに加えて、単なる描画ボードだけでなく、テストできる実装が必要です。

  • 関数の読み取り
  • 関数書き込み

Thats 12.私の Zozotez では、setとflambda(ラムダのような匿名マクロ)も実装しました。ファイルI/Oを除いて、動的にバインドされたLISP(Elisp、picoLisp)を実装するライブラリをフィードできます(基になるBFがstdin/stdout以外をサポートしていないため)。

言語の実装方法を完全に理解するには、LISPと(LISPではなく)の両方にLISP1インタープリターを実装することをお勧めします。 LISPは非常に単純な構文を持っているため、パーサーの出発点として適しています。私は現在、さまざまなターゲット(スターリンはターゲットC用)などのスキームで記述されたスキームコンパイラーに取り組んでいます。

14
Sylwester

マッカーシーは7つの演算子を使用して元のLISPを定義しました:quoteatomeqcarcdrconsおよびcondこの記事 は彼のステップをたどります。

10
Vijay Mathew

これ よくある質問:

単一の「最良の」最小限のプリミティブのセットはありません。それはすべて実装に依存します。たとえば、数値のように基本的なものでも、プリミティブである必要はなく、リストとして表すことができます。プリミティブの可能なセットの1つには、S式の操作用のCAR、CDR、およびCONS、S式の入出力用のREADおよびPRINT、およびインタープリターの根性用のAPPLYおよびEVALが含まれる場合があります。ただし、関数にはLAMBDA、等価にはEQ、条件にはCOND、割り当てにはSET、定義にはDEFUNを追加することをお勧めします。 QUOTEも役に立ちます。

これは、コンピュータサイエンス学部のカーネギーメロンのウェブサイトからのものです。

8
bennybdbc

Paul Grahamは seven を使用してevalを実装します。

マッカーシーのLISPのマイクロマニュアルで、彼は ten を使用してevalを実装しています。

2
hawkeye

あなたは x86 MOV命令が必要 です。

"M/o/Vfuscator(短い 'o'、" mobfuscator "のように聞こえる)は、プログラムを" mov "命令にコンパイルし、" mov "命令のみにします。算術、比較、ジャンプ、関数呼び出し、およびプログラムに必要なその他すべてすべてがmovオペレーションを通じて実行されます。自己変更コード、トランスポートによってトリガーされる計算、およびその他の形式のnon-movチートはありません。」

しかし真剣に、これらのプリミティブはLISPマシンを実装しません。マシンには、I/Oやガベージコレクションなどの機能が必要です。関数呼び出しメカニズムは言うまでもありません!さて、あなたは関数である7つのプリミティブを持っています。マシンはどのように関数を呼び出しますか?

これらのプリミティブが可能にすることの適切な理解は、それらがexposeUniversal Turing Machine。これらの説明は「Lispy」であるため、舌を滑らせて(LISPと話す)、こっそりこれを「LISPマシン」と呼びます。 「ユニバーサル」とは、マシンがプログラム可能であることを意味します。ユニバーサルチューリングマシンにいくつかの組み合わせ命令を適用すると、任意のチューリングマシンをインスタンス化できます。しかし、これまでのところ、これらはすべて純粋に数学的な構成要素です。

このUTMを実際にシミュレートするには、それを物理的に実現してコンピューターで探索するには、これらの7つのLISP命令の組み合わせからチューリングマシンを作成するフォームを実際に入力する方法を提供するマシンが必要です。また、何らかの形の出力も必要です。少なくとも「はい」、「いいえ」、または「待っている、私はまだ動いている」と言うことができるマシン。

つまり、これらの7つの命令が実際に機能する唯一の方法は、環境を提供するより大きなマシンでホストされている場合です。

また、グラハムの7つのプリミティブは数値を明示的にサポートしていないため、関数から構築する必要があることに注意してください(「チャーチ数値」手法)。プロダクションLISPの実装では、このような奇妙なことを行いません。

1
Kaz