6

I'm confused by the interpretation of ' in the context of lists of symbols.

The problem is that I'd like to check whether a buffer is in one a list of modes, and I'll use the scratch buffer as my example.

(with-current-buffer "*scratch*" major-mode) ;; lisp-interaction-mode
(equal (with-current-buffer "*scratch*" major-mode) 'lisp-interaction-mode) ;; t

So far so good.

(member (with-current-buffer "*scratch*" major-mode)
        '('lisp-interaction-mode) ;; nil

Huh? Trying to simplify this, I ended up with

(member 1 '( 1)) ;; (1) - okay, my list syntax seems correct
(member '1 '( '1)) ;; nil - Why doesn't this work? I think this is the issue

So how can I make a list of symbols, and then check whether a symbol is in there?

  • 1
    You may wish to look at eq ["Return t if the two args are the same Lisp object."] as compared to equal. And, also have a look at memq ["Return non-nil if ELT is an element of LIST. Comparison done with ‘eq’. The value is actually the tail of LIST whose car is ELT."] versus member. – lawlist Jul 27 '16 at 16:12
11

Short version: remove the inner quote.

When you quote a list, it leaves the list's contents unevaluated:

'(a-symbol "a string" (+ 1 1)) => (a-symbol "a string" (+ 1 1))

So: if the list includes symbols, a quoted list will return a list of symbols. Here's the rub: because quoting is so common, there's a special reader syntax for it: '. So:

'kittens        => kittens
(quote kittens) => kittens

So, when you quote a list that includes a quoted symbol, what you're actually producing is:

'('kittens) => ((quote kittens))

when what you really want is:

'(kittens)  => kittens

So your comparison looks like:

(memq 'kittens '(puppies kittens otters))    => (kittens otters)
(memq 'kittens '('puppies 'kittens 'otters)) => nil
| improve this answer | |

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.