Q:  How to fix elmo-unintern to use 2 arguments instead of 1, or silence the byte-compiler on this issue.

Here is the macro definition:

(defmacro elmo-unintern (string)
"Delete the symbol named NAME, if any, from OBARRAY.
The value is t if a symbol was found and deleted, nil otherwise.
NAME may be a string or a symbol.  If it is a symbol, that symbol
is deleted, if it belongs to OBARRAY--no other symbol is deleted.
OBARRAY, if nil, defaults to the value of the variable `obarray'."
  (static-if (fboundp 'unintern)
      (list 'unintern string)))

Here is the bye-compile message:

In elmo-imap4-parse-response:

filename.el:92495:45:Warning: unintern called with 1 argument, but requires 2

filename.el:92513:46:Warning: unintern called with 1 argument, but requires 2

filename.el:92516:38:Warning: unintern called with 1 argument, but requires 2

Here is the comment by @Stefan from a previous bug report: https://lists.gnu.org/archive/html/bug-gnu-emacs/2015-04/msg00560.html

> Loading this file works as expected, but compiling it generates the
> warning
>     unintern called with 1 argument, but requires 2
> But `unintern' doesn't require 2 arguments.

That's the `advertized-calling-convention' at work here.  IOW calling
the function with only one argument still works but is deprecated.

  • 1
    I'm not sure why passing a 2nd argument is something you need to ask about. Have you read (elisp) Simple Macro? What exactly is the difficulty?
    – npostavs
    Feb 9 '17 at 19:46
  • @npostavs -- what argument should I pass? nil, obarray, hello-world? One mistake in the Wanderlust related libraries can cost an entire day to track down the error as there are zillion condition-case that hide errors -- yesterday, I had a condition-case-unless-debug that still hid errors and cost me hours of time. I want to do this correctly, please.
    – lawlist
    Feb 9 '17 at 19:48
  • This should be easy to fix by reading what the second argument is. If the docstring of unintern is not clear, please help expanding it by explaining what you understood (or did not).
    – YoungFrog
    Feb 10 '17 at 16:28
  • @YoungFrog -- The answer by npostavs resolved the issue. I had tried using obarray without the ' [single quote], but the Wanderlust related libraries are filled with condition-case clauses that mask errors. I knew that using obarray (without a ' [single quote]) caused email to not function properly. This week, I spent a lot of time tinkering with elmo etc. and I decided to not waste time on this issue by continuing to guess why my attempt was not working. I wanted peace of mind that a wrong choice wouldn't cost me hours of debugging.
    – lawlist
    Feb 11 '17 at 1:14

Note: see Stefan's answer for why using unintern is probably a bad idea.

Omitting an optional argument is equivalent to passing nil, so you can do that explicitly to get the same effect:

(defmacro elmo-unintern (string)
  (static-if (fboundp 'unintern)
      (list 'unintern string nil)))

In the particular case of unintern, it's explained that nil is equivalent to obarray, so you might prefer to be even more explicit and use that instead of nil:

(defmacro elmo-unintern (string)
  (static-if (fboundp 'unintern)
      (list 'unintern string 'obarray)))

More readable version using backquote:

(defmacro elmo-unintern (string)
  (static-if (fboundp 'unintern)
      `(unintern ,string obarray)))

By the way, I'm not sure exactly what static-if is, but assuming it tries to do a "compile time" conditional, that's redundant because it's already compile time by virtue of being called in a macro: you could just use if instead. Although I don't see much point in trying to push things into compile time anyway (uninterning should be rare, so performance is unlikely to be a concern), just use a function:

(defun elmo-unintern (string)
  (if (fboundp 'unintern) ; `unintern' is new in Emacs 19.29
      (unintern string obarray)))
  • Looking at github.com/wanderlust/wanderlust/blob/wl-2_15_9/elmo/… it seems that the lisp reader is being abused to perform some kind of parsing, which is why the uninterning is needed.
    – npostavs
    Feb 9 '17 at 20:20
  • 1
    Passing nil here will just circumvent the warning, without addressing the core problem (e.g. if the string passed to it is "nil", your Emacs session will likely start to behave very strangely).
    – Stefan
    Feb 12 '17 at 0:07

The reason for making the second arg explicit is because in 99.99% of the cases, using unintern with its default 2nd argument (i.e. with the global obarray) is a very bad idea which will occasionally render your Emacs session unusable or cause very odd behavior. IOW you should only use it when you really know what you're doing.

Looking at the code, I don't think any part of the code actually needs those symbols to be uninterned (and I'm not convinced the author really knows what he's getting himself into), so it looks like the uninterning was mostly performed out of fear of excessive resource use. My guess is that the best fix would be to start by removing those calls to elmo-unintern (along with the definition, rendered useless).

  • "looks like the uninterning was mostly performed out of fear of excessive resource use" - yeah it does look like that. It appears to be uninterning symbols interned by parsing some data with read. And as you point out, if the data happens to have some strings that look like important elisp symbols that might effectively break Emacs.
    – npostavs
    Feb 12 '17 at 2:59
  • Yes, some of the elmo code was written by people with little Lisp experience. The Wanderlust maintainers are fairly responsive, I'm sure they'd welcome a patch to clean up the code.
    – jch
    Feb 13 '17 at 18:27

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.