sbcl を使用した Emacs + Slime では、ファイルに関数 (またはそれ以上) を定義すると、次の 2 つの選択肢があります。
- 評価: たとえば、CMx eval-defun を使用
- コンパイル: 例えば Cc Mk compile-file で
2 番目のものも .fasl ファイルを生成します。
2つの違いは何ですか?
定義/ファイルをコンパイルするとき、フードの下で何が起こっていますか?
それぞれの長所と短所は何ですか?
sbcl を使用した Emacs + Slime では、ファイルに関数 (またはそれ以上) を定義すると、次の 2 つの選択肢があります。
2 番目のものも .fasl ファイルを生成します。
2つの違いは何ですか?
定義/ファイルをコンパイルするとき、フードの下で何が起こっていますか?
それぞれの長所と短所は何ですか?
まず第一に、言語ランタイムで任意の CL フォームを評価 (つまり実行) できる関数eval
[ 1 ] があります。CL 実装には、コンパイル モードと解釈モードという 2 つの異なる操作モードがあります。コンパイルモードは、評価の前にフォームが最初にメモリ内でコンパイルされることを意味します。また、CL では、評価はファイル レベルではなく、個々のフォームのレベルで行われます。したがってeval
、操作のモードに応じて、フォームのコンパイルと解釈の両方が行われる場合があります。(たとえば、SBCL はデフォルトで常にコンパイルされますsb-ext:*evaluator-mode*
が:interpret
、CLISP は常に解釈されます)。
現在、一部のファイルですべてのフォームをコンパイルし、結果を別のファイルに保存できる便利な関数compile-file
[ 2 ] もあります。これは 、これらのフォームの評価をトリガーしません。
また、CL は、プログラム ライフサイクルの 3 つの異なる時間 (コンパイル時、ロード時、および実行時) を定義します。そして、最も (最もではないにしても) 不可解な CL 特殊演算子eval-when
[ 3 ] の 1 つを使用すると、何が起こるかを制御する可能性があります。
要約すると、カーソル下のフォームC-M-x eval-defunを呼び出します。eval
コンパイルする必要はありませんが、実装によっては可能です。C-c M-k compile-fileバッファはcompile-file
しますが、その内容は評価しません。
式を評価するときに実際に起こることは、それが sbcl に送られ、そこで式のテキストが解析され、Common Lisp 環境のメモリに格納されるネイティブ コードにコンパイルされることです。
2 番目の方法は同じことを行いますが、すべてのコードをファイルにコンパイルします。コードをコンパイルする理由は、読み込みを速くするためです。コードの構文とセマンティクスを解析してコードを再度生成する必要はありません。コードをメモリにロードするだけですぐに実行できます。
したがって、コンパイルの利点は、ロードの速度だけであり、コンピューターの作業を節約できます。
ただし、既にコンパイルされているファイルを編集する場合は、eval-defun を使用してメモリ内のみで関数を再作成できます。これは、ファイル全体をコンパイルするよりも高速な場合があります。
これはあなたの質問に直接答えているわけではありませんが、コメントには長すぎます。
ほとんどの場合、どちらのオプションも使いたくないでしょう。SLIME と Emacs について話すと、, C-c C-c(またはM-x slime-compile-defun) を使用することになります。これにより、(まだ開いていない場合) コンパイル バッファーがポップアップし、コンパイル エラーと警告が表示され、コード内の問題が強調表示されます。これは、Flymake カーソルのようなものでもうまく機能します (問題のある領域に移動すると、問題の正確な内容がミニバッファーに表示されます)。
ファイルをコンパイルすることは、後で実際に使用したい製品が実際にある場合に、まれに発生します。または、ほとんどの場合、設定せずに他のユーザーに使用してもらいたいと考えています。たとえば、Web サーバーがあり、システム管理者が必要に応じてそれを (再) 起動できるようにしたい場合、管理者はソフトウェアがどのように機能するかを知る必要はなく、起動方法を知るだけで済みます。 .
defun の評価はまさにそれです。テキストを SWANK に送信しますが、結果は分析しません。もちろん、Lisp はそれを実行した後に何かを出力しますが、SLIME は脇に置きます。