8

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?

6

I'd say stick with defun.

If you want to try define-inline, which is new (it doesn't even have a doc string yet!), go ahead.

But think about how much you want or need inlining. It is rare to need it, IMO (certainly not for the kinds of thing you show here, but they are no doubt just to get the question across).

I would definitely recommend not to use defsubst. You likely don't need it, and it just gets in the way. It might have had a use case in 1985, but I know of no place where it is useful now. define-inline is apparently an attempt to get the benefit of defsubst without the downside.

This question might be primarily opinion-based. This answer is just one opinion, in any case.

  • Good answer, thank you! You're right, I chose a simple example mostly for the sake of clarity. I'm curious to try a defmacro or define-inline solution, so I'll probably take a stab at them. It would be nice to have eval-when-compile baked into the resulting expression. – ivan Apr 9 '17 at 19:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.