According to Symbol Type

A symbol whose name starts with a colon (‘:’) is called a keyword symbol. These symbols automatically act as constants, and are normally used only by comparing an unknown symbol with a few specific alternatives. See Constant Variables.

I understand they are constants, but I don't know to use them. For example, how to set its value(constants also have a value!), how to get its value, and when should I use them. I tried to use them as follows:

(defun test-func (:test-symbol)
  (print :test-symbol))
(test-func "hello")

I got an error:

Attempt to set a constant symbol: :test-symbol

Could anyone give me an example?


They are usually used as keys ("properties") in a property list. E.g the variable org-publish-project-alist contains one or more property lists with keys like :base-directory, :publishing-directory, :publishing-function etc. The Org mode manual shows a simple example and a more complex example of setting this variable. You should also read the doc string of the variable with C-h v org-publish-project-alist.

The main thing is that you have something that looks like this:

(setq orgfiles-plist
        :base-directory "~/org/"
        :base-extension "org"
        :publishing-directory "/ssh:user@host:~/html/notebook/"
        :publishing-function org-html-publish-to-html
        :exclude "PrivatePage.org" ;; regexp
        :headline-levels 3
        :section-numbers nil
        :with-toc nil
        :html-head "<link rel=\"stylesheet\"
                  href=\"../other/mystyle.css\" type=\"text/css\"/>"
        :html-preamble t))

(note that the first element is a tag and not part of the property list) and you can get the value of a property by saying

(plist-get (cdr orgfiles-plist) :headline-levels)

==> 3

(the cdr gets rid of that initial tag.)

Note that keywords like :headline-levels are self-evaluating constants: no need to quote them. That and the fact that they make the property list look nice and neat (not to mention that it looks a bit like a python or js dict) are some of their attractive points.

  • 1
    A property list can also be constructed without keyword symbols. Like (base-directory "~/org/" base-extension "org"), so what's the advantage of using keyword symbols if both keyword and non-keyword symbols can solve my problem? Being nice an neat isn't convincing enough for me. – Searene Jul 23 '20 at 13:12
  • 1
    That's correct: you can use any symbol as key. Using keyword symbols is a matter of style, not of necessity. – NickD Jul 23 '20 at 13:38
  • Thanks, got it. – Searene Jul 23 '20 at 15:22

I think the documentation you've linked to is comprehensive on the matter of their value:

In Emacs Lisp, certain symbols normally evaluate to themselves. These include nil and t, as well as any symbol whose name starts with ‘:’ (these are called keywords).

=> The value of the keyword :foo is :foo.

These symbols cannot be rebound, nor can their values be changed.

=> The value of the keyword :foo will always be :foo.

Any attempt to set or bind nil or t signals a setting-constant error. The same is true for a keyword (a symbol whose name starts with ‘:’), if it is interned in the standard obarray, except that setting such a symbol to itself is not an error.

=> Attempting to assign :foo any other value will cause an error.

These constants are fundamentally different from the constants defined using the defconst special form (see Defining Variables). A defconst form serves to inform human readers that you do not intend to change the value of a variable, but Emacs does not raise an error if you actually change it.

=> Although (defconst foo 1) can be assigned another value, despite that 'const' label, keywords are "constants" in the traditional sense meaning that, unlike "variables", their value never varies.


To add a tiny bit to what others have said -

Think of keywords as constants like t and nil, whose values are themselves (symbols). That is, like t and nil they are self-evaluating.

The general use case for keywords is that instead of having only the two basic names "t" and "nil" you can use any name you like -- just prefix it with :.

This can make your code more readable/meaningful.

The effect of using :foo is similar to using 'foo, but you always get the same value no matter how many times you evaluate the sexp (unlike (eval 'foo), whose value is typically not the same as that of 'foo).

And keywords are font-lock highlighted specially, so they stand out as such.

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.