Emacs
はエディターとして起動し(おそらくm
inputsを受け取るn
関数を持っています)、バックグラウンドで実行されているElisp
インタープリター(これを使用して、プログラムの振る舞いを変更します-おそらく、emacsではなくなります:-))。
なぜプログラムにはインタプリタであるextensionが必要なのですか?この背後にある理論はありますか?独自のプロジェクトに同様の決定を下すことができるように、それはどのような基本的な機能を提供しますか?
これが(linux)プログラムがどのようにメモリにあるかを仮定すると、
それは、インタープリターなし(text segment
にある)がないため、プログラムがfiniteマシンであり、有限の命令セットを実行できるためです。 text segment
内に存在するprogram layout
(実際のコード、別名機械命令)内ただし、インタープリターのようなものを追加する場合は、新しい命令を追加して(おそらくheap
に、データと命令は両方とも単なるビットなので?)、無限マシン?
そもそもなぜ通訳が必要なのか(!)と同じだと思いますが、私の質問はEmacs
のようなエディターでのこの特定のシナリオから来ました。ですから、私はこれを両方の観点から理解したいと思います。
あなたのプログラムは、有限の命令セットを実行できる有限のマシンです
厳密な感覚、これは本当ですが、あまり面白くありません。実際、私のデスクトップには3テラバイトのメモリしかありません(RAM、ディスク、レジスタなどを含む)。つまり、「のみ」2(3 * 72057594037927936 * 8) は述べていますが、私のデスクトップをそのような巨大な有限マシンとして見るのはあまり面白くありません。さらにメモリを購入できることを確認します(たとえば、ディスクを追加します)。
多くの物理学者は宇宙全体の量子力学的な見方をしており、宇宙自体が巨大な有限状態機械であることを説明するかもしれません(結局のところ、100Planckの定数 などに関連する量子状態をそれぞれが持つ粒子)
実際には、ラップトップをチューリングマシンとしてよりよく見て、そのメモリが潜在的に「無限」であると考えてください。
(あなたの質問は抽象化のさまざまなレベルを台無しにしています)
なぜプログラムはそれだけでインタプリタであるような拡張機能を必要とするのですか?
インタプリタの埋め込みは、 部分評価 と Turing completeness に関連しています。 practiceでは、very便利です(しかし、 マルウェア 。拡張可能アプリケーションによって解釈される「データ」として提供されます)。 Lua または Guile をアプリケーションに埋め込むことができます(ただし、これは主要な設計上の選択であり、非常に早期に行う必要があるため、特に ガベージコレクション )に関連する アーキテクチャ の影響の plugins を受け入れるようにアプリケーションを設計できます( dlopen(3) および dlsym(3)を参照) ;そして私の manydl.c プログラムは、何十万もの生成されたプラグインを持つことができることを示しています)。 JITコンパイル テクニック( libgccjit 、 を参照)[〜#〜] llvm [〜 #〜] 、 asmjit 、...)
[〜#〜] sicp [〜#〜] を読み取り、次にスコットの プログラミング言語のプラグマティクス 、Quinnec's LISP In Small Pieces 、およびR &A Arpaci-Dusseauの オペレーティングシステム:3つの簡単な部分 とPitratの ブログ 。
[〜#〜] sbcl [〜#〜] (良い Common LISP 実装)で遊んでください。 [〜#〜] repl [〜#〜] の相互作用ごとに(動的に) マシンコード を生成しています。 ホモニコ性 と メタプログラミング と マルチステージプログラミング に注意してください。 Greenspunの10番目の規則 と Gallの法則 と について誤ってturing-complete を読む事。
Turing (および彼の 停止問題 なので、 Rice's theorem )および Gödel (および彼の 不完全性定理 )コードはデータ(そして証明)であり、データはコード( self-reference は関連する概念です。 Richardのパラドックス も参照し、 Curry-Howard対応を参照してください )。ホフスタッターの Gödel、Escher、Bach の本を読んでください。
ところで、いくつかのLinuxプロセスの 仮想アドレススペース の写真は非常に素朴です(前世紀では時々そうでしたが、今日のものははるかに複雑です)。 proc(5) 、 elf(5) 、 execve(2) 、 mmap(2) 、 ld-linux(8) を試して_cat /proc/$$/maps
_、_cat /proc/self/maps
_を試してください、cat /proc/$(pidof emacs)/maps
(Linuxシステムの場合)。
関連する質問への this answer も参照してください(おそらく this one)。
ElispはEmacsに埋め込まれていません。 EmacsはElispで書かれていますです。ある意味では、EmacsはElispに組み込まれています。
Emacsは、ITS上のTECOエディター用のエディターMACroSのセットとして始まりました。その後、Multicsに移植されました。ただし、TECOのマクロ言語はひどい、ひどい言語なので、Multics Emacsの作成者は、Emacsを再実装するためのより良い言語を探していました。MacLispのMulticsポートには、はるかにパフォーマンスの高い関数呼び出しがあり、 Multics、PL/Iの「標準」システムプログラミング言語よりもネイティブなテキスト処理機能。そこで、MacLispにEmacsを実装することにしました。
その後、EmacsがUnixに移植されたとき、LISP実装を記述し、そのLISP実装のみを新しいオペレーティングシステムに移植する方が、Emacsシステム全体を常に新しいLISP実装に移植するよりも簡単であると判断しました。 Emacsを(Unixのように)移植したかったのですが、以前のシステムのように、OSの一部としてプラットフォーム固有のLISPシステムすらありませんでした。
独自の実装を作成することで、テキストエディタの実装専用に言語を適応させることもできました。
Emacsはこの点で本当に特別なものではないことに注意してください。プログラムでアプリケーションを制御できることを「スクリプト」と呼び、多くのスクリプト言語とスクリプトホストがあります。 JavaScriptと呼ばれる言語を聞いたことがありますが、元々はブラウザとWebサーバーのスクリプトを作成するために作成されました。 Luaは、スクリプト言語として特別に設計された言語であり、たとえば、 World of WarcraftおよびAdobe Lightroom。 AutoCADには、AutoLispと呼ばれる独自のスクリプト言語があります。 WindowsにはPowerShell、UnixにはPOSIXシェル、macOSにはAppleScriptがあります。
完全にコンパイルされたツールを使用すると、ツールで実行できることは、ディストリビューターが有用だと考えるものに限定されるためです。
もちろん、理論的には誰もがCで独自の拡張機能を記述し、再コンパイルして楽しく使用できます。しかし、実際には、ツールのコンパイルと再インストールには時間と労力がかかり、実際にソフトウェアをディストリビューターから、またはさらに悪いことにアプリストアから入手するほとんどの人にとって、ほとんど不可能です。したがって、LISPとCでの拡張関数の記述の違いは、数分の労力と数時間、数日、数週間の労力、または不可能の差です-Appleが決定するまで誰も待たないツールの新しいバージョンを神聖なホールに入れることができます。必要なのは、ロボットを節約する機能今を使用するためだけです。
そしてなぜneedパーソナライズ可能な拡張関数なのか? Emacsの「エミュレーション」は本物よりも途方もなく強力ではありませんが、ほとんどのIDEでは完全にうまくプログラムできません。しかし、私はそれを行うのが遅くなり、はるかに満足しなくなります。ソフトウェア開発者などの高価な専門家にしたくないのは、効率を下げることです。 ELispを学ぶのは難しいですが、テキストを真剣に操作すると、文字通り100万回以上の費用がかかります。
プログラムにインタープリターを組み込む必要があるのはなぜですか?
おそらく最も簡単な答えは、プログラムを拡張して、本来は設計されていなかったことを簡単に実行できるようにすることです。
無数の例があります。最も明白なものの1つはWebブラウザーです。埋め込まれたjavascriptインタープリターがあります。それがなければ、私たちが見ることができるすべては静的なウェブページです。しかし、これにより、世界中の開発者は、組み込み言語のない元のWebブラウザーでは絶対にできないことを行うことができます。
私はForthのようなスクリプト言語とREPLをC#開発環境で(多くの理由で)追加しようとしましたが、解釈との違いに多く取り組んできました。長年業界に行った後でも、コンパイルと解釈をすばやく簡単に切り替えることができるとは思っていませんでした。とにかく...コンパイルは、 .NET Framework仮想マシンのbytcodeをMSILに書き込んだ別のテキストコード(通常はテキストコード)をコード化します。ただし、Windowsフォームの開発を行って画面エディターを使用する場合は、GUIエディターを使用してコードを作成しました。カバーの下で、C#を生成します。または、昔のFoxProを覚えているかもしれません。問題はありません。重要なのは、ソースコードの複数の表現と宛先コードの複数の表現があることです。コンパイル部分。
しかし、コンパイルされた部分は通常「凍結された」部分であり、変更することはできず、手元の問題に合わせて彫刻することはできません。特に、解釈されたコードができる方法ではありません。それが、解釈の最初の理由です-使用時に柔軟性を実現します
解釈については、コードを実行するものはすべて解釈します。したがって、ボタンをクリックすると、マウスクリックのアクションが解釈され、そこからコードが実行されます。したがって、すべてのアプリケーションはインタプリタ(より正確には、それらのスイート全体)です。 だから、あなたの質問は、「なぜ彼らは追加のインタープリターを埋め込むのですか?」見方をかなり変えますね?そして、アプリケーションの構成ファイルとして使用されるXMLファイルとYAMLファイルについて考え始めると、それはさらに別のインタープリターのセットです。マシン命令にコンパイルする場合でも、これらの生のバイトはチップ内部のマイクロコードによって解釈されます。
通訳がいたるところにいます。
私が見つけたソフトウェア開発の聖書、コードコンプリート(第2版)は、私たちの開発者は1日あたり同じ数のコード行を書く傾向があると述べています。そのため、アセンブリ言語を書く代わりに、ドメインであるDSLで書くべきです。固有の言語。作成する必要があり、実行する必要のある仕事で最も効果的であることを目標としています。設定については、それはYAML、またはデータベーステーブル、または* .iniファイルです。ゲームの場合、それはそれをスクリプト化するために埋め込まれたLUAである可能性があります。そして、最も表現力のあるDSLを作成し、手元にある抽象化のみを処理してそれらのみに焦点を当て、他のすべてを無視できるようにし、複雑さを制限しようとし、それでも私の私の問題をできるだけ簡単かつ強力に解決します。それがあなたの答えの別の部分です。 ユーザーを有効にして権限を与えるには
私たちはインタープリターを組み込んでボキャブラリーとツールのセットを提供し、その次元(またはドメイン)で当面の問題の解決策を、最大の使いやすさ、シンプルさ、およびパワーで表現できるようにします。 埋め込みインタプリタは、ドメイン固有言語、ツールのセット、およびそれらを使用するための単語です。なぜDSLを埋め込むのですか?より速く、簡単に、またはNEW能力を使用して、これまで解決できなかった問題を解決し、うまくいけばそれらを正しく解決するため。そして、うまくいけば、私がこの答えを表明したよりも簡潔に;-)