emacs: определение функции символа недействительно: loop
Я тестирую загрузку пакетов в emacs init.el
(Emacs 24.3). Я следил за блогом автора emacs prelude
автоматически загружать пакеты и скопировать код в мой init.el
как внизу. Тем не менее, я получил сообщение об ошибке loop
функция / символ, который говорит:
Symbol's function definition is void: loop
Может кто-нибудь объяснить, пожалуйста, как исправить код?
Я искал в интернете, и кажется, что loop
это макрос в cl-lib
, Я думаю, что определение для loop
отсутствует, и я попытался исправить проблему, добавив (require 'cl-lib)
, как показано в коде, но ошибка остается. Существуют и другие вопросы SO по аналогичным сообщениям об ошибках, например: ELisp: cl-loop для "Значение символа как переменной void", определение функции Symbol - void: Declare-function. Но сообщения об ошибках различаются по тому, чего не хватает, и ответы в основном предлагают альтернативные маршруты, такие как использование более новой версии emacs.
- код -
(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
1 ответ
cl-lib
Пакет был представлен в Emacs 24.3 и предоставляет ряд возможностей Common Lisp, все с cl-
префикс. До этого единственным способом использования этих функций было требование cl
библиотека, и используйте имена без префиксов, например, loop
вместо cl-loop
, Однако это не рекомендуется из-за возможности конфликтов имен, и обычно рекомендуется использовать префиксные имена, если это возможно.
Поскольку вы используете Emacs 24.3, "правильный" способ исправить это - заменить loop
с cl-loop
а также return
с 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)))
(Вам не нужно (require 'cl-lib)
, так как cl-loop
а также cl-return
загружаются автоматически.)
В качестве альтернативы, вы можете добавить (require 'cl)
получить доступ к незафиксированным именам и оставить код как есть. Это также будет работать в более ранних версиях Emacs.
Я не могу не заметить, что эта функция может быть написана более кратко:
(defun prelude-packages-installed-p ()
(cl-every 'package-installed-p prelude-packages))
Тот же вопрос о cl-every
плюс cl-lib
против every
плюс cl
применяется.