I am testing on loading packages in emacs init.el
(Emacs 24.3). I followed a blog by the author of emacs prelude
to automatically load packages, and copied the code there into my init.el
as in the bottom. However, I got an error message about the loop
function/symbol, which says:
Symbol's function definition is void: loop
Can someone please explain how to fix the code?
I've searched around on the internet, and it seems that loop
is a macro in cl-lib
. My guess is that the definition for loop
is missing, and I attempted to fix the problem by adding (require 'cl-lib)
, as shown in the code, but the error remains. There are other SO questions on similar error messages, e.g.: ELisp: cl-loop for "Symbol's value as variable is void", Symbol's function definition is void: declare-function. But the error messages are different on what's missing, and the answers mostly suggest alternative routes, such as using newer version of emacs.
-- code --
(require 'package)
(add-to-list 'package-archives
'("melpa-stable" . "http://stable.melpa.org/packages/") t)
(package-initialize)
;;; check & load packages
(defvar prelude-packages
'( haskell-mode )
"A list of packages to ensure are installed at launch.")
;;(require 'cl-lib) ;debug
(defun prelude-packages-installed-p ()
(loop for p in prelude-packages
when (not (package-installed-p p)) do (return nil)
finally (return t)))
(unless (prelude-packages-installed-p)
;; check for new packages (package versions)
(message "%s" "Emacs Prelude is now refreshing its package database...")
(package-refresh-contents)
(message "%s" " done.")
;; install the missing packages
(dolist (p prelude-packages)
(when (not (package-installed-p p))
(package-install p))))
(provide 'prelude-packages)
;;; end load packages
The cl-lib
package was introduced in Emacs 24.3, and provides a number of Common Lisp features, all with the cl-
prefix. Before that, the only way to use those features was to require the cl
library, and use unprefixed names, e.g. loop
instead of cl-loop
. However, that was discouraged because of the possibility for name conflicts, and it's usually recommended to use the prefixed names if possible.
Since you are using Emacs 24.3, the "correct" way to fix this would be to replace loop
with cl-loop
and return
with cl-return
:
(defun prelude-packages-installed-p ()
(cl-loop for p in prelude-packages
when (not (package-installed-p p)) do (cl-return nil)
finally (cl-return t)))
(You don't need (require 'cl-lib)
, because cl-loop
and cl-return
are autoloaded.)
Alternatively, you could add (require 'cl)
to get access to the unprefixed names, and leave the code as it is. This will also work on earlier Emacs versions.
I can't help noticing that this function could be written more succinctly:
(defun prelude-packages-installed-p ()
(cl-every 'package-installed-p prelude-packages))
The same issue about cl-every
plus cl-lib
vs every
plus cl
applies.