3

他の開発者が書いた Commom Lisp コードを読んでいると、戻り値が void または無視できる定義の最後の形式で、引数を指定せずにVALUESアクセサーを呼び出している人がいることに気付きました。

例:

(defun definition-whose-return-values-are-neglectable ()
  ... Some s-expressions ...
  (values))

これらのタイプの定義の最後の式としてこのフォームを追加する利点はありますか (コンパイラにとって、パフォーマンスなど)。

4

3 に答える 3

3

(values)最後の形式の利点、または主な使用例は次のとおりです。

  • 戻り値が定義に対して無意味な場合の自己文書化コード
  • 一般に、開発ツールが無視された結果または不要な結果への参照を処理または保持しないようにするため。
    具体的には:

非利点/非問題:

  • 一部のコンパイラは生成する命令の数が少ない場合もあれば、生成する命令の数が多い場合もありますが、バイトやサイクルを処理していない限り、これは無視できます。
  • 次のような値を返す必要はありません。
    • 呼び出し元が返される値の量を区別することを期待する場合
      これはおそらく定義の設計の悪さも明らかにします
    • 結果が multiple-value-callフォームで使用されることになっている場合
      これはおそらく呼び出し元の設計の悪さを露呈し、フォーム間で効果的に副作用を持っています
      副作用を取り除くか、副作用が発生するのを許可する以外に、ここで行うことはほとんどありません全体の前後multiple-value-call

問題:

  • 一般に、定義から末尾呼び出しの最適化を無効にします。
    ただし、十分にスマートなコンパイラは、通常はs/ s の助けを借りて、値のない定義への末尾呼び出しを検出し、これらの呼び出しに最適化を適用する場合があります。 これには、他の定義が変更されているため、私の推測では、それを行う実装はありませんftype declaredeclaim

1.履歴アウトラインのコンテンツを空のリストに設定することにより、Allegro CL でリスナーの履歴をクリアできます。

(setf (cg:range (cg:find-component
                 :history-outline
                 (first (cg:toolbars ide.base:*listener-window*))))
      '())
于 2013-05-29T18:12:57.183 に答える
3

印刷

Lisp には no があるinvisibleため、関数が返すものは何でもP、REPL の (print) 部分によって出力されます。これは、印刷設定が不適切な場合、システムが多くの画面を印刷する可能性があることを意味します (印刷サークルnilあり、戻り値が循環構造であるため、混乱を招くスタック オーバーフロー エラーが発生することさえあります)。

コンパイル

コンパイラはいくつかの最適化を行うことができます (特定のコンパイラが実際に行う場合と行わない場合があります)。たとえば、関数が興味深いものを何も返さないとしてマークし、(setq var (my-func))toのような式をコンパイルする場合があり(progn (my-func) (setq var nil))ます。

コンパイラーが関数に副作用がないことを証明でき、それを終了する(values)場合、コンパイラーはその呼び出しを完全にドロップできます。

ドキュメンテーション

コンピューター プログラミングの重要な側面は、コードが自分自身を含む他の人間によって読み取られること(values)であり、関数の末尾に追加することで、関数が副作用のためだけに呼び出されることを読者に伝えます。

于 2013-05-29T13:40:59.643 に答える