Emacs Lisp: Lisp Symbol
Lisp has symbols concept. Lisp's concept of “symbols” is somewhat like identifiers in other languages, except that:
- lisp symbol can be held unevaluated, simply as itself, a inert name. In this sense, it's like a string.
- lisp symbol stores more than one value.
The Concept of Symbols in Lisp
LISP differs from most programing languages such as C, Java, Ruby, Python, in that it deals with symbols, as opposed to just identifiers and values.
For example, in most languages, once you defined
x=3, you cannot manipulate the variable “x” because it gets evaluated to 3 right away. If you want, you have to build a string
"x" and manipulate this string, then use
eval(lots string join here)
to achieve the effect. (for example, you have a variable x, and it has integer 3 as value. you want to rename the variable so the new name is var_name + var_value.)
In lisp, after
(setq x 3)
x would evaluate to 3, but
(quote x) evaluates to the symbol x itself.
In practice, having a language dealing with “symbols” directly means that transformation of expressions is possible. (In lisp, this is the lisp macro feature, which is a limited form of term rewriting languages such as Wolfram Language.) (info "(elisp) Macros")
Each lisp symbol has the following “cells” to store things:
- “print name” cell → a string, the same as the symbol. Automatically set, cannot be changed.
- “value” cell → stores the symbol's value. When value cell is not void, the symbol is considered as a variable.
- “function” cell → stores function definition object, lisp macros, or other objects that can act as function.
- “property list” cell → hold a list of name/value pairs. Used for storing meta info about the symbol, such as function state, font face spec (for syntax coloring), deprecation flag, etc.
A symbol's value cell or function cell may be empty. If so, it's said to be “void”. When you try to get a cell's value that's void, it's a lisp error. (a empty cell is not the same as having value of
In normal coding, you don't need to worry about any of these. The only thing that's useful for most elisp code is property list, but many other higher-level functions do it for you. (i.e. add, remove, properties.)
〔►see Emacs Lisp: Property List〕
Understanding Lisp Symbol is important when you do advanced lisp programing. For example: macros, create and calling functions at run-time, function inside functions, manipulate evaluation, implementing a language, or any sort of meta-programing. If you don't have a need, you should not exploit these facilities in your program. Keep your code simple.
A symbol, typically gets evaluated to its value. But you can stop this, by quoting the symbol, using
the special form
quote. For example,
You can think of
as “hold evaluation”.
What's macro and special form?
Normally, arguments passed to a function are evaluated, in order. In elisp, this is called standard evaluation strategy.
However, for some function, evaluating arguments in order does not make sense. For example, conditional construct
if, or local variable construct
let. These functions, are said to have non-standard evaluation strategy.
Of functions that are non-standard evaluation, they are either macro or special form.
Macros are defined by lisp expressions with
defmacro. User can define them.
Special Forms are written in C.
The special form
quote has a convenient read syntax.
is syntactically equivalent to
When do you need to quote a symbol?
Some functions, automatically quote the argument for you, as a convenience.
There's no systematic way to tell if a function needs its argument quoted.
The best thing is to check with the function's doc string
to see if a argument needs to be a symbol.
setq always automatically quotes its first argument.
Because you basically always want the argument passed as a symbol.
So, you write
(setq x 3).
set is almost the same as
setq, the major difference is that
set does not automatically quote the first argument.
So, you write
(set 'x 3).
(info "(elisp) Setting Variables")
Some functions, require you to quote the argument yourself. Because sometimes you may want a symbol's value cell to be passed, but sometimes the symbol itself.
mapcar's arguments are not automatically quoted. You may or may not want to quote them, depending on your use.
Here's two examples of using mapcar, where in one example we want to quote the argument, and in the other example we do not want to quote the argument.
;; suppose we have many functions (setq f '1+) (setq f 'cos) (setq f 'sqrt) ;; we use f as a wrapper because we are not sure which function we want until run time ;; here's our data (setq mylist '(1 2 3)) ;; normally, when using mapcar, we want first arg quoted (mapcar '1+ mylist) ; (2 3 4) ;; here, we don't want first arg quoted (mapcar f mylist) ; (1.0 1.4142135623730951 1.7320508075688772)
Check If a Value is Symbol
;; check if a variable eval to a lisp symbol ;; make symbol x1's value cell to be 123 (setq x1 123 ) (symbolp x1) ; nil ;; nil, because x1 is evaluated, and that value is 123, not a symbol (symbolp 'x1) ; t
Get the Value of Symbol's Cells
Here's how to to get various cell's values.
Here's a example of getting cell values, with symbol “sin” (
sin is a builtin math function).
;; get symbol's name cell value (symbol-name 'sin) ; "sin" ;; get symbol's value cell value (symbol-value 'sin) ; void-variable error ;; because the value cell of the symbol sin is void ;; or, we just say that sin isn't a variable ;; get symbol's function cell value (symbol-function 'sin) ;#<subr sin> ;; the value is a primitive function (written in C), and has print form of #<subr sin> ;; get symbol's property list cell value (symbol-plist 'sin) ; (side-effect-free t)
Here's another example with a user defined symbol.
;; get symbol cell values ;; this makes symbol x1's value cell to contain the number 3 (setq x1 3) ; 3 ;; get symbol's name cell value (symbol-name 'x1) ; "x1" ;; get symbol's value cell value (symbol-value 'x1) ; 3 ;; get symbol's function cell value (symbol-function 'x1) ; nil ;; in emacs 24.3.1, this is a void-function error ;; in emacs 25.1, this returns nil ;; elisp manual 24 and 25.1 say it should be error ;; get symbol's property list cell value (symbol-plist 'x1) ;nil
Set Symbol's Name Cell
Symbol's name cell is automatically set, as a string of the symbol name. Symbol name cell cannot be changed.
Set Symbol's Value Cell
The normal way to set a symbol's value cell is using
;; set a symbol's value cell (setq y "yes yes") ;; get it (symbol-value 'y) ; "yes yes"
You can also check if a symbol's value cell is not empty, by
(we think of it as checking if a variable is defined.)
(boundp 'h) ; nil (setq h 4) (boundp 'h) ; t
Set Symbol's Function Cell
The normal way to set a symbol's function cell is using
;; a function that returns 4 (defun z () 4) ;; Note: return value of defun is not defined ;; get a symbol's function cell value (symbol-function 'z) ; (lambda nil 4)
You can check if a symbol's function cell is not empty, by
(fboundp 'f) ; nil ;; define a function that return 3 (defun f () 3) ;; now the fuction cell is filled (fboundp 'f) ; t
Because a symbol can both hold a value and a function, a symbol can be both a variable and function. For example, the symbol
buffer-file-name is both a variable and function.
(you can try
describe-variable on it.)
Set Symbol's Property List Cell
How to convert a symbol to string?
;; convert a symbol to string (symbol-name 'defun)
How to convert a string to symbol?
;; convert a string to symbol ;; if the symbol does not already exist obarray, create it, put it in obarray (intern "something") ;; if the symbol does not already exist obarray, return nil (intern-soft "something")