3

I'm new to emacs and try to learn elisp. I've read some tutorials and try to build now my own customized emacs. Looking at this blog I want to write a similar script for automatically installing required packages.

In the blog the author defines a variable required-package which binds to a list of required packages. Then he writes (I quote):

; my-packages.el
(require 'cl)

; method to check if all packages are installed
(defun packages-installed-p ()
  (loop for p in required-packages
        when (not (package-installed-p p)) do (return nil)
        finally (return t)))

My goal is to write a similar function which does not depend on the common lisp package (since I would like to learn elisp :)). So I tried:

(defun check-required-packages (list-check)
  "The function check if the packages in LIST-CHECK are installed"
  (let ((return '(t))) ; return list
    (dolist (p list-check return) ; for each p in package execute the body and finally return RERTURN.
      (when (not (package-installed-p p))
    (add-to-list return nil)))
    return))

Having also a variable required-packages binding to such a list leads to the error:

(check-required-packages required-packages)
Wrong type argument: symbolp, (t)

I dont understand this. Since I can define

(setq a '(t)) 

without a problem.

  • Don't use add-to-list for local variables. It'll break if you enable lexical binding. Use push or cl-pushnew instead. – lunaryorn Jan 11 '16 at 10:15
6

The error is (add-to-list return nil). The first argument of add-to-list must be the symbol of the variable holding the list and not the list itself. That means you have to write (add-to-list 'return nil) instead.

You can find such errors easily yourself if you use edebug. I think you have lisp-interaction-mode or emacs-lisp-mode as major mode of the buffer where you try your code. You find edebug in both modes in the major mode menu, either Lisp-Interaction or Emacs-Lisp as menu item Instrument Function For Debugging. Place point on the closing parenthesis of the defun you want to instrument for debugging and click on that menu item. Afterwards call the instrumented function. Emacs will enter the debugger on your function. The buffer will be read-only and the key-bindings are redefined. If you press space you can execute the function form after form and see the effects.

Another way to debug your code is to check the option Options -> Enter Debugger On Error. Then run your code. Emacs will show you the backtrace when the error occurs. That gives you a quite good feeling for the place where the error is.

  • Many thx for the debugging part. I'm really sorry if this was a too basic questions. As I pointed out, just starting with it. Really appreciated your help – user8 Jan 11 '16 at 10:17
2

As documented in the Info for Elisp:

The argument SYMBOL is not implicitly quoted; add-to-list is an ordinary function, like set and unlike setq. Quote the argument yourself if that is what you want.

Here's a scenario showing how to use add-to-list:

(setq foo '(a b))
      => (a b)

(add-to-list 'foo 'c)     ;; Add `c'.
      => (c a b)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.