A superflat vector drawing of a ceramic throne.
Kaka Farm!

The Kaka Farm Blog!

Do Not Use Shorthands For Autoloaded Functions.

Date published:

Also posted on Emacs Stackexchange.

Note: 2024-12-16.

A comment on my MELPA submission for fancy-urls-menu by riscy (aka Chris Rayner) a real elisp boffin who knows much more about actual Emacs development than I do says one should avoid shorthands altogether, and he gives very good reasons:

I'm unsure specifically what issue you refer to, but as a code reviewer I am not currently a huge fan of shorthands. A lot of the tooling is not ready for them yet: not only the linters, but also simple tools for quickly jumping around between definitions, the ability to grep for code using function/variable names, the ability to copy-paste-execute code in other contexts and have it mean the same thing. Or maybe most importantly, the ability to parachute into a particular line of a particular elisp file and comprehend (or at least prove something about) what's going on without a lot of assumed context (which is also a problem with other programming techniques e.g. inheritance and metaprogramming).

I understand where they're useful but I (personally) think it can be selfish for a package author to use them and I'm glad you moved away from them :)

Problem.

I want to write a shorthand for a shorthanded autoloaded function in a package, like so:

;;; super-duper-long-package-name.el --- Provide a cool command -*- lexical-binding: t -*-

;; Version: 0.1.0

;;; Code:

(require 'someone-elses-super-duper-long-package-name)

;;;###autoload
(defun sdlpn-cool-command ()
  "Display a cool message."
  (interactive)
  (message (someone-elses-super-duper-long-package-name-cool-command)))

(provide 'super-duper-long-package-name)

;; Local Variables:
;; read-symbol-shorthands: (("sdlpn-" . "super-duper-long-package-name-")
;;                          ("sesdlpn-" . "someone-elses-super-duper-long-package-name-"))
;; End:
;;; super-duper-long-package-name.el ends here

But when the package is installed, and I try running the command, there are two problems:

  1. The command is still named sdlpn-cool-command.

  2. When I run the command using M-x sdlpn-cool-command RET, Emacs complains in a message:

    execute-extended-command: Autoloading file /home/super-duper-long-user-name/.emacs.d/elpa/super-duper-long-package-name-0.1.0/super-duper-long-package-name.elc failed to define function sdlpn-cool-command

How do you solve it?

Solution.

Just name it super-duper-long-package-name-cool-command.

Shorthands are meant for your own code, either when you use your own package code or when you (require 'someone-elses-extremely-long-package-name) and need to write code using names defined in it, like so:

;;; super-duper-long-package-name.el --- Provide a cool command -*- lexical-binding: t -*-

;; Version: 0.1.1

;;; Code:

(require 'someone-elses-super-duper-long-package-name)

;;;###autoload
(defun super-duper-long-package-name-cool-command ()
  "Display a cool message."
  (interactive)
  (message (someone-elses-super-duper-long-package-name-cool-command)))

(provide 'super-duper-long-package-name)

;; Local Variables:
;; read-symbol-shorthands: (("sdlpn-" . "super-duper-long-package-name-")
;;                          ("sesdlpn-" . "someone-elses-super-duper-long-package-name-"))
;; End:
;;; super-duper-long-package-name.el ends here

someone-elses-extremely-long-package-name may be defined like so, and notice the shorthanded function sesdlpn-cool-command is not defined to be autoloaded, so using a shorthand is okay:

;;; someone-elses-super-duper-long-package-name.el --- Provide a cool string generating functions -*- lexical-binding: t -*-

;; Version: 0.2.3

;;; Code:

(defun sesdlpn-cool-command ()
  "Return a cool string."

  "COOL!")

(provide 'someone-elses-super-duper-long-package-name)

;; Local Variables:
;; read-symbol-shorthands: (("sesdlpn-" . "someone-elses-super-duper-long-package-name-"))
;; End:
;;; someone-elses-super-duper-long-package-name.el ends here
Tag feeds:

Kaka Farm by Yuval Langer is licensed under Attribution-ShareAlike 4.0 International