When comparing the last-command against multiple possible strings, it doesn't seem possible to use the member function.

Is there a way to simplify this using something like member?

    (string-equal last-command 'foo)
    (string-equal last-command 'bar)
    (string-equal last-command 'bob)
    (string-equal last-command 'baz))

I tried doing this but it didn't work:

(when (member last-command (list 'foo 'bar 'bob 'baz))
  • 1
    What you're showing here is not strings, but symbols. The only reason this works with string-equal is because it converts symbols to strings first. – wasamasa Dec 6 '19 at 15:09
  • Please don't change the question. If you have a new question, pose that separately. – Drew Dec 6 '19 at 15:21
  • Please specify what you mean by "it didn't work". It works for me. I'm guessing that when you tried to test this last-command changed in the meantime, so it didn't match any of the symbols you expected. – Drew Dec 6 '19 at 15:22
  • I'm setting this-command, later comparing with last-command, using using string-equal succeeds, where as member does't. – ideasman42 Dec 6 '19 at 15:27
  • Sounds to me like you're setting one to a string and the other to a symbol, the only scenario where string-equal behaves differently from equal. – wasamasa Dec 6 '19 at 17:03

Your code works fine, for me.

(when (member last-command (list 'foo 'bar 'bob 'baz)) (do-something))

First, last-command is typically a symbol, not a string. There is no reason to use string-equal for two symbols. It works, but it is slower - it just converts the symbols to strings and then compares those strings.

The best way to compare two symbols is with eq. eq compares two Lisp objects, i.e., they must be the same object to return non-nil. For a list, memq tests membership using eq.

Second, even if the things to compare were strings, member uses the test equal, which uses string-equal for string comparison.

If the question is really about last-command, and not about comparing symbols or strings, then be aware that last-command doesn't always return a symbol - see C-h v last-command.

The last command executed. Normally a symbol with a function definition, but can be whatever was found in the keymap, or whatever the variable `this-command' was set to by that command.

All the more reason to test with member, which uses equal.

(Also, you can just write '(foo bar bob baz) instead of (list 'foo 'bar 'bob 'baz). But this is unimportant.)

| improve this answer | |
  • What would be a better way to compare two symbols? – ideasman42 Dec 6 '19 at 15:12
  • 2
    That is already in the answer, eq is sufficient for this and used by memq. – wasamasa Dec 6 '19 at 16:05
  • Note that member works when all values are strings too. – ideasman42 Jun 21 at 3:27

Assuming you actually intend comparing strings, many cl-lib functions support a :test keyword argument to specify the comparison function:

(cl-member "foo" '(foo bar baz) :test 'string-equal)
| 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.