10

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?

5 Answers 5

14

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
      '("orgfiles"
        :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.

3
  • 2
    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, 2020 at 13:12
  • 2
    That's correct: you can use any symbol as key. Using keyword symbols is a matter of style, not of necessity.
    – NickD
    Jul 23, 2020 at 13:38
  • Thanks, got it.
    – Searene
    Jul 23, 2020 at 15:22
7

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.

7

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.

0

It is in my eyes worth to add a bit to what others already said here especially considering the comment:

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 and neat isn't convincing enough for me. –  Searene Jul 23, 2020 at 13:12

@Searene : as good as any programming language is "Turing complete". In other words you can do the same in any language using different means.

What makes the difference between for example Assembler or C and Lisp or Python is the ease of usage of the means the language comes with (usually the more "batteries included" the better).

Another aspect to consider is how good the required and necessary programming style of a programming language plays together with own intuition. The less you need to learn because the things are as you intuitively expect them to be the better.

That said the statement Being nice and neat isn't convincing enough for me. conveys a message about how much your own way of thinking fits to the programming language and the means it comes with.

In other words if your own current intuition plays against accepting that "being nice and neat" (given along with providing examples of usage), there can't be any explanation able to convince you that a feature is useful and makes sense.

But ... what can maybe happen over time is that what you yourself consider as useful and making sense will change and all of the sudden what didn't make much sense before starts to be really meaningful.

All this comes down to "compatibility" of a programming language with own thought patterns.

Finally consider that YOU ARE who gives the existence of a programming language its sense and meaning by using it to achieve this or other effect. Maybe you will find an own making sense use case for these constants playing well with YOUR OWN intuition? And because obvious to YOU but not necessarily to others, having hard time to explain that they are really nice and neat.

4
  • This isn't an answer to the question. To be an answer you should address at least some of what was asked (e.g. how to use keyword symbols, how to set their value, how to get their value, when to use them). You shouldn't use answers to enter into debates over tangential points.
    – JBentley
    May 30, 2023 at 13:15
  • @JBentley sorry for confusing you with my answer which is in my eyes more on the question topic than what you are currently might be able to accept as helpful. In other words what is probably more true is that "you shouldn't use comments to enter into debates about how valuable and on topic an answer is.". Let the OP the room to react (up-vote, down-vote, ignore or comment) instead of trying to judge yourself about the usefulness of an answer.
    – Claudio
    May 30, 2023 at 13:42
  • @JBentley : see my other answer which might better suit to what you consider as an answer to the question.
    – Claudio
    May 30, 2023 at 13:59
  • The whole point of comments is to "ask for information or suggest improvements". It's literally written in the comment box. My intention, as I set out, was to suggest that you incorporate elements of the question into your answer. I would have downvoted as well, but I lack the reputation on this sub-stack. A good clue that you weren't answering the question is the fact that you used your answer to respond to a comment rather than the actual question.
    – JBentley
    May 31, 2023 at 15:30
0

In Emacs Lisp, keyword symbols are used as constants and are typically used for comparing values or specifying options in functions and variables. Here are a few examples to help you understand their usage:

  • Comparisons: Keyword symbols are often used in conditional statements for value comparisons. Here's an example:

(defun test-func (symbol)
  (if (eq symbol :test-symbol)
      (message "Symbol is :test-symbol")
    (message "Symbol is not :test-symbol")))

(test-func :test-symbol)    ; Outputs "Symbol is :test-symbol"
(test-func :other-symbol)   ; Outputs "Symbol is not :test-symbol"

In the example above, the eq function is used to compare the symbol parameter with the :test-symbol. If they are equal, a specific action is taken.

  • Function/Variable Options: Keyword symbols can be used as options for specifying behavior or configuration in functions or variables. Here's an example:

    (defun perform-action (option)
      (cond ((eq option :option-1)
             (message "Performing action for option 1"))
            ((eq option :option-2)
             (message "Performing action for option 2"))
            (t
             (message "Unknown option"))))

    (perform-action :option-1)    ; Outputs "Performing action for option 1"
    (perform-action :option-2)    ; Outputs "Performing action for option 2"
    (perform-action :unknown)     ; Outputs "Unknown option"

In this example, the perform-action function takes an option parameter and performs different actions based on the value of the parameter. Keyword symbols are used to represent the different options.

Regarding your code snippet, the error you encountered occurs because you're trying to define a function with :test-symbol as a parameter, which is not valid syntax. Instead, you should use a regular symbol as the parameter name:


(defun test-func (test-symbol)
  (print test-symbol))
(test-func "hello")    ; Outputs "hello"

Remember, keyword symbols are primarily used for comparisons and specifying options rather than being assigned values directly.

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.