Q:

Autoload function or mode from ELPA

Use case
I run my Emacs config on many machines. Most do not have a Racket installed, and I'd rather not have my Racket related packages installed by default. However, I would like to be able to edit Racket code if I need to.
This is just an example, I'm interested in doing this for a large number of modes, possibly all of the avalible major modes I can find.
Question
Is there any way I can tell Emacs to autoload a package from the package repository? racket-mode won't be installed by default, but if I ever edit a *.rkt file, the config will download, install, load, and run racket-mode?
I'm sure I can do this with ugly hacks (just shadow the functions with a helper)? Is there a cleaner way to do it?

A:

IMO, the best way to handle deferred installation is to use my package manager straight.el together with use-package. This is the only general-purpose deferred-installation mechanism that I know of (others are embedded in a particular Emacs configuration, like Prelude). I don't actually use racket-mode but here are some other examples from my configuration.
Basic usage
(use-package apples-mode
  :defer-install t
  :mode "\\.\\(applescri\\|sc\\)pt\\'")

More modes and interpreters
(use-package haskell-mode
  :defer-install t
  :mode (("\\.[gh]s\\'" . haskell-mode)
         ("\\.l[gh]s\\'" . literate-haskell-mode)
         ("\\.hsc\\'" . haskell-mode))
  :interpreter (("runghc" . haskell-mode)
                ("runhaskell" . haskell-mode)))

Together with configuration (which won't be run until the package is installed)
(use-package web-mode
  :defer-install t
  :commands (web-mode)

  :init
  (add-hook 'html-mode-hook #'web-mode)

  :config
  (setq web-mode-markup-indent-offset 2)
  (setq web-mode-enable-auto-closing t))

Installing an associated package
(use-package company-auctex
  :defer-install t
  :after tex

  :config
  (company-auctex-init))

Note that while use-package has generalized deferred-installation support, the package.el backend is untested AFAIK, while the straight.el backend is fully supported.
For verbose documentation on straight.el, including comparisons to other package managers, see the README.

