Emacs Lisp is a dialect of Lisp used in Emacs.

  • Everything in Lisp are represented as lists (made of “atoms” and nested lists).
  • Function call: (print "Hello World!")
  • To evaluate something means to “process it and find out its value.”
  • A quoted list looks like this: '(a b c d () (lavender aster tulip) e)
    • Lisp won’t evaluate anything within a quoted list (' or (quote (...))). The quoted list (and nested ones) will not be treated as a function call. Symbols that are not the first element will not be evaluated as variables either.
    • a, b, c, d, and e are “symbols”
    • Empty lists (()) (and only empty ones) are atoms as well.
    • Printed expressions of both lists and atoms are symbolic expressions or sexps. Expressions are sometimes also called “forms.”
  • Types of valid atoms:
    • numbers (85, 642, 79)
    • symbols (+, next-line, previous-line)
    • strings (“hey”, "", “This is a short sentence.“)
  • All elements are whitespace-delimitted and Lisp doesn’t care about how much whitespaces is between elements of the list.
  • Use C-x C-e to evaluate a Lisp expression at point (on or after the closing parenthesis)
  • Multiple symbols may refer to the same (function) definition. Likewise, a symbol may have one or two (function or variable) definitions.
  • Emacs Lisp does not support namespaces, so prepend the variable to identify where the variable comes from (e.g. org-agenda-type)
  • Expressions (forms) that evaluated in an unusual manner are called “special forms,” like function definitions.
  • A macro translates itself into another expression to be evaluated in its place.
  • The innermost lists get evaluated first, otherwise everything is evaluated left to right. For example, (+ 2 (+ 3 3)) evaluates to 8.
  • Lisp code (.el files) can be byte-compiled (into .elc files) to improve performance.
  • When an expression is evaluated, the Lisp interpreter returns a value and carry out its side effects (like printing text, or moving files).
  • A symbol can be bound to any value: to a number, to a string, to a list, or to a function definition.
  • Error void-function xxx: symbol xxx does not have a function definition
  • Error void-variable xxx: symbol xxx does not have a variable definition
  • (concat "abc" "def") = "abcdef"
  • (substring "aaabbb" 1 5) = "aabb"
  • (number-to-string 42) = "42" (same thing for (string-to-number))
  • Arithmetic: (+ ...), (- ...), (* ...), (/ ...)
  • Error (wrong-type-argument number-or-marker-p hello) = “Argument with incorrect type: expected a number or marker, found symbol ‘hello‘“
  • Functions with -p or p suffix are predicate functions (e.g. they test if the argument satisfies a condition, like belonging to a type).
  • (message FORMAT-STRING &rest ARGS) prints stuff to the echo area (area below the modeline used for output)
  • (set 'var-name value), or more conveniently, (setq var-name value)
    • (setq var-a value-a var-b value-b ...); the number of arguments must be even
  • Increment variable: (setq num (+ num 1)) or (1+ num) or (incf num)
  • Increment variable: (setq num (- num 1)) or (1- num) or (decf num)
  • incf and decf also accepts a number argument. (incf num 2) increases num by 2.
  • (buffer-name), (buffer-file-name), (current-buffer), (other-buffer), (switch-to-buffer), (set-buffer), (point)
(defun func-name (reqd-args... &optional opt-args... &rest rest-args)
  "optional documentation..."
  (interactive ...) ; optional
  func-body...)
  • To return a value, simply place the expression at the end of the function

let expression: local variables

(let ((var1 value1)
      (var2 value2)
      var3 ; default value nil
      ...)
  body...)

if statement

(if condition
    if-clause
  else-clause-body...)