(define-key mode map symbol)

Normally what you see a quoted value (which means literally that value).

(define-key evil-normal-state-map "i" 'evil-insert-state)

That means when the key is pressed, it actually looks up for that value as a variable and then execute it, a bit like what getattr(Object, 'string') does in Python. The subtle distinction is that 'string' is literally that value however getattr returns the function object with that name.

However I can perfectly replace this with an interactive lambda.

(define-key evil-normal-state-map "i" 
  (lambda () (interactive) (message "%s" major-mode)))

How is it possible that a 'value (which I think is a bit like string in Python) can be replaced with a function object. Is it that (interactive) is doing something special?

Can someone please explain why there is an equivalence between 'string and the lambda in this case is it because the define-key knows to handle both these datatype appropriately?

FYKI: I bumped into this problem because I wanted to conditionally bind some key depending on the major-mode.

  • 2
    If you're asking about the last argument, it is described in the docstring of define-key with great details (much more than for most other functions, in fact). If it is unclear, please add some details explaining which bit is unclear.
    – YoungFrog
    Commented Jul 20, 2015 at 9:12
  • Does that mean I can pass "command" and "string "because it is designed to accept both arguments and not because they are equivalent?
    – Nishant
    Commented Jul 20, 2015 at 9:29
  • 1
    Yes. If you give the argument 'foo (or equivalently (quote foo)), it evaluates to the symbol foo then emacs looks up the function definition of that symbol and uses it. If you give (lambda (...) (interactive) ...), it evaluates to an interactive function, i.e. a command, which is used as is.
    – YoungFrog
    Commented Jul 20, 2015 at 9:45
  • Mind moving this as an answer, I can mark it as selected or I will self-answer this with your comments. It might help folks who suffer from over-thinking syndrome and bumps into these crazy questions from time to time!
    – Nishant
    Commented Jul 20, 2015 at 9:58

2 Answers 2


If you give the argument 'foo (or equivalently (quote foo)), it evaluates to the symbol foo. When you later use the key, emacs will look up the function definition of that symbol and use it. If you instead use (lambda (...) (interactive) ...) as argument, it evaluates to an interactive function, i.e. a command, which will be used as is.


I have slightly different doc-string, it's called DEF there:

(define-key KEYMAP KEY DEF)

And then it's explained:

DEF is anything that can be a key's definition:

  • nil (means key is undefined in this keymap),
  • a command (a Lisp function suitable for interactive calling),
  • a string (treated as a keyboard macro),
  • a keymap (to define a prefix key),
  • a symbol (when the key is looked up, the symbol will stand for its function definition, which should at that time be one of the above, or another symbol whose function definition is used, etc.),
  • a cons (STRING . DEFN), meaning that DEFN is the definition (DEFN should be a valid definition in its own right),
  • or a cons (MAP . CHAR), meaning use definition of CHAR in keymap MAP,
  • or an extended menu item definition.

Lisp is granddaddy of dynamic languages like Python, where variables don't have type, they just "point" to some object that can be everything. So typically functions can interpret different types of arguments differently and many functions take everything that "makes sense" as arguments. (So, functions frequently test type of arguments, this is different in Python, where such testing is not idiomatic, because Python thinks in terms of "interfaces", not types.)

In Emacs Lisp, you have two types of functions, simple functions and commands. Commands must have interactive declaration. This tells Emacs how to get values of arguments when command is called interactively (by user). So it perfectly makes sense that your keybinding should be associated with command, not just a function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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