I defined some simple functions in init.el, for example 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/"))))
This seemed like a good use-case for defsubst
:
(defsubst my-cache-file (x) ...)
Then I started learning about compilation, and wanted to further optimize. I naively tried:
(defsubst my-cache-file (x)
(eval-when-compile (expand-file-name x my-cache-directory)))
but the compiler complained (rightly) about the free variable x
, so instead I wrapped the calling code:
(setq savehist-file
(eval-when-compile (my-cache-file "savehist")))
(setq backup-directory-alist
`(("." . ,((eval-when-compile (my-cache-file "backups/"))))
That last caller should probably be evaluating the whole alist at compile time, though, so I pulled the eval-when-compile
up:
(setq backup-directory-alist
(eval-when-compile `(("." . ,(my-cache-file "backups/")))))
I'd like to avoid littering my code with more eval-when-compile
calls than necessary, and I wonder if there's a better approach I could take using macros or define-inline
. The documentation makes define-inline
sound promising:
Functions defined via define-inline have several advantages with respect to macros defined by defsubst or defmacro:
- They can be passed to mapcar (see Mapping Functions).
- They are more efficient.
- They can be used as place forms to store values (see Generalized Variables).
- They behave in a more predictable way than cl-defsubst (see Argument Lists in Common Lisp Extensions for GNU Emacs Lisp).
But the syntax looks cumbersome, and I can't find a single example of it being used in the wild. Nor can I find any explanation of it's claim that defsubst is less efficient.
Has anyone used define-inline
, or is there a different macro I should look into, or should I just stick with defsubst
?