私はいくつかの単純な関数を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
ますか?
defmacro
またはdefine-inline
解決策を試すことに興味があるので、おそらくそれらを試してみるでしょう。eval-when-compile
結果の式に焼き込んだほうがいいでしょう。