Skip to main content
Commonmark migration
Source Link

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?

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?

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?

edited tags
Link
Drew
  • 80.9k
  • 10
  • 125
  • 265
Source Link
ivan
  • 2k
  • 12
  • 21

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

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?