eval-when-compile:defsubst vs defmacro vs define-inline


8

私はいくつかの単純な関数をinit.elで定義しました、例えばmy-cache-file

(defconst my-cache-directory
  (expand-file-name ".cache" user-emacs-directory)) ; ~/.emacs/.cache

(defun my-cache-file (x)
  (expand-file-name x my-cache-directory))          ; ~/.emacs/.cache/x

(setq savehist-file
      (my-cache-file "savehist"))

(setq backup-directory-alist
      `(("." . ,(my-cache-file "backups/"))))

これはの良いユースケースのように思われましたdefsubst

(defsubst my-cache-file (x) ...)

その後、コンパイルについて学び始め、さらに最適化したいと思いました。私は単純に試しました:

(defsubst my-cache-file (x)
  (eval-when-compile (expand-file-name x my-cache-directory)))

しかし、コンパイラーは(正しく)フリー変数について不平を言ったxので、代わりに呼び出しコードをラップしました。

(setq savehist-file
      (eval-when-compile (my-cache-file "savehist")))

(setq backup-directory-alist
      `(("." . ,((eval-when-compile (my-cache-file "backups/"))))

その最後の呼び出し元はおそらくコンパイル時に全体のリストを評価しているはずなので、私は引き上げましeval-when-compileた:

(setq backup-directory-alist
      (eval-when-compile `(("." . ,(my-cache-file "backups/")))))

eval-when-compile必要以上の呼び出しでコードが散らかるのを避けたいのですが、マクロやを使用してより良いアプローチがあるかどうか疑問に思いますdefine-inlineドキュメントが作るdefine-inline音が有望:

define-inlineで定義された関数には、defsubstまたはdefmacroで定義されたマクロに関していくつかの利点があります。

  • それらはmapcarに渡すことができます(マッピング関数を参照)。
  • 彼らはより効率的です。
  • これらは、値を格納するためのプレースフォームとして使用できます(一般化変数を参照)。
  • それらはcl-defsubstよりも予測可能な方法で動作します(GNU Emacs LispのCommon Lisp拡張機能の引数リストを参照)。

しかし、構文は扱いにくいように見え、実際に使用されている例は1つもありません。また、defsubstの方が効率が悪いという主張についての説明はありません。

誰かが使用したことdefine-inlineがありますか、それとも私が調べなければならない別のマクロがありますか、それともそのまま使用する必要がありdefsubstますか?

回答:


6

と私は固執すると思いますdefun

define-inline新しい(まだdoc文字列さえもない!)を試してみたい場合は、先に進んでください。

しかし、考えて、あなたが望むどのくらいか、必要性のインライン化。IMOが必要になることはめったにありません(確かに、ここに示すような種類のものではありませんが、問題を解決するためだけのものです)。

絶対に使用しないことをお勧めしますdefsubst。あなたはおそらくそれを必要としないでしょう、そしてそれは邪魔になります。それは1985年にユースケースがあったかもしれないが、私はそれが今どこで役に立つか知りません。 define-inline明らかにdefsubstマイナス面なしで利益を得ようとする試みです。

この質問は、主に意見に基づいている場合があります。いずれにしても、この答えはただの意見です。


良い答え、ありがとう!あなたが正しい、私は主に明確にするために簡単な例を選びました。defmacroまたはdefine-inline解決策を試すことに興味があるので、おそらくそれらを試してみるでしょう。eval-when-compile結果の式に焼き込んだほうがいいでしょう。
ivan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.