6

sbcl を使用した Emacs + Slime では、ファイルに関数 (またはそれ以上) を定義すると、次の 2 つの選択肢があります。

  • 評価: たとえば、CMx eval-defun を使用
  • コンパイル: 例えば Cc Mk compile-file で

2 番目のものも .fasl ファイルを生成します。

2つの違いは何ですか?

定義/ファイルをコンパイルするとき、フードの下で何が起こっていますか?

それぞれの長所と短所は何ですか?

4

4 に答える 4

8

まず第一に、言語ランタイムで任意の 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しますが、その内容は評価しません。

于 2012-08-03T05:29:41.880 に答える
2

式を評価するときに実際に起こることは、それが sbcl に送られ、そこで式のテキストが解析され、Common Lisp 環境のメモリに格納されるネイティブ コードにコンパイルされることです。

2 番目の方法は同じことを行いますが、すべてのコードをファイルにコンパイルします。コードをコンパイルする理由は、読み込みを速くするためです。コードの構文とセマンティクスを解析してコードを再度生成する必要はありません。コードをメモリにロードするだけですぐに実行できます。

したがって、コンパイルの利点は、ロードの速度だけであり、コンピューターの作業を節約できます。

ただし、既にコンパイルされているファイルを編集する場合は、eval-defun を使用してメモリ内のみで関数を再作成できます。これは、ファイル全体をコンパイルするよりも高速な場合があります。

于 2012-08-02T21:55:05.093 に答える
1

これはあなたの質問に直接答えているわけではありませんが、コメントには長すぎます。

ほとんどの場合、どちらのオプションも使いたくないでしょう。SLIME と Emacs について話すと、, C-c C-c(またはM-x slime-compile-defun) を使用することになります。これにより、(まだ開いていない場合) コンパイル バッファーがポップアップし、コンパイル エラーと警告が表示され、コード内の問題が強調表示されます。これは、Flymake カーソルのようなものでもうまく機能します (問題のある領域に移動すると、問題の正確な内容がミニバッファーに表示されます)。

ファイルをコンパイルすることは、後で実際に使用したい製品が実際にある場合に、まれに発生します。または、ほとんどの場合、設定せずに他のユーザーに使用してもらいたいと考えています。たとえば、Web サーバーがあり、システム管理者が必要に応じてそれを (再) 起動できるようにしたい場合、管理者はソフトウェアがどのように機能するかを知る必要はなく、起動方法を知るだけで済みます。 .

defun の評価はまさにそれです。テキストを SWANK に送信しますが、結果は分析しません。もちろん、Lisp はそれを実行した後に何かを出力しますが、SLIME は脇に置きます。

于 2012-08-02T23:24:16.720 に答える