Why does logically negating an unused optional argument throw an error?

40 Views Asked by At

I am attempting to solve exercise 5.5 of the tutorial

Write an interactive function with an optional argument that tests whether its argument, a number, is greater than or equal to, or else, less than the value of fill-column, and tells you which, in a message. However, if you do not pass an argument to the function, use 56 as a default value.

To do so, I wrote this.

(defun foo (&optional x)
  (interactive "P")
  (if (not x) (setq x 59))
  (message (cond ((>= x fill-column) "bigger or equal")
    ((< x fill-column) "smaller"))))

When passed no argument (C-u M-x foo), it throws the error

Wrong type argument: number-or-marker-p. (4).

What I've been able to gather from experimentation, reasoning, and the debugger is that this function fails on its third line. Clearly, not and an optional-but-not-used argument don't agree. I've checked the documentation for not, but it did not help. This gives me my question: Why does negating an unused argument throw an error?

I've not yet fully grasped the debugger in Emacs, so I'm sorry that I was unable to solve this myself. I'm a total beginner with both Emacs and Emacs Lisp. I am not a new programmer or even a new Lisper. I already know Scheme. Feel free to teach me how to fish.

1

There are 1 best solutions below

3
J. Mini On

(4) is referring to what caused the error. It's the list containing four. Recall what the tutorial says about C-u.

If you don’t type a number, C-u defaults to a cons cell with a 4

Presumably, not's error is referring to this.