Introduction
In our last lesson, you successfully connected a custom interactive command to a keybinding, completing the full cycle of creating a personalized Emacs tool. Your my-surround-region command is now instantly accessible, but it follows a single, unchanging path of execution every time you run it.
To create truly powerful and intelligent tools, your code needs the ability to make decisions. This lesson marks our first step into that world by focusing on the most fundamental aspect of decision-making in any programming language: the concept of true and false. We will explore the learning outcome: Evaluate truthiness and falsiness in Elisp (nil vs. everything else).
By the end of this lesson, you'll understand Elisp's unique and simple rule for what it considers "true" and "false," a cornerstone concept that underpins all conditional logic we will build in the upcoming lessons.
1. The Two Meanings of nil
Many programming languages you may have encountered, like Python, have explicit True and False boolean values. Emacs Lisp takes a different, more minimalist approach rooted in Lisp's history. It doesn't have a dedicated boolean type. Instead, it uses two special symbols: t and nil.
tis the canonical symbol for true.nilis the symbol for false.
However, nil plays a double role. It also represents the empty list. As we'll see throughout this course, this is not just a coincidence but a core part of Lisp's design philosophy. For now, the key is to remember that the Lisp interpreter treats nil and an empty list, written as (), as the exact same thing.
This official GNU Emacs Lisp manual page gives a clear and authoritative explanation of this concept.
An explanation of `nil` (Programming in Emacs Lisp)
To start, let's read the official definition of nil from the GNU Emacs manual. It's a short but crucial text that explains the dual nature of nil as both 'false' and the 'empty list'.
Read the first two paragraphs of this section, starting from 'Before illustrating a test...' and ending with '...is returned by evaluating the expression.'. Focus on grasping the two meanings of nil and the core principle of what Elisp considers true.
2. The Golden Rule of Elisp Truthiness
As you just read, Elisp follows one simple, powerful rule for determining truth:
In Elisp,
nilis false. Everything else is true.
This is a critical point to internalize, as it differs from many other languages. Let's break down what "everything else" includes:
- Numbers, including
0and negative numbers. - Strings, including the empty string
"". - The symbol
t. - Any other symbol (e.g.,
'my-symbol). - Any non-empty list (e.g.,
'(1 2 3)).
The fact that 0 and "" are considered true is a common source of bugs for programmers coming from other languages, where such "empty" values often evaluate to false. In Elisp, the logic is cleaner: only nil (and by extension, ()) is false.
The following resource provides a set of clear examples that demonstrate this rule.
Types, Conditionals, and Loops in Emacs Lisp
This article from System Crafters provides a concise summary and practical examples of Elisp's rule for truthiness.
Please read the section titled 'What is true?'. The examples use the if form, which we'll use for testing in the next step. Notice which values result in 'true' and which result in 'false'.
3. Testing Truthiness in Practice
Reading about a concept is one thing; seeing it in action is another. To test the truthiness of different values, we can use the if special form. We will study if in detail in the next lesson, but its basic structure is simple enough for our purposes here:
(if CONDITION THEN-FORM ELSE-FORM)
If CONDITION evaluates to anything other than nil, Elisp will evaluate THEN-FORM. If CONDITION evaluates to nil, it will evaluate ELSE-FORM.
Your Turn: Experiment in the *scratch* buffer
Open your *scratch* buffer (or an ielm session) and evaluate the following expressions one by one using C-x C-e. Observe the result that appears in the echo area at the bottom of your screen.
- The canonical
trueandfalse:(if t "It's true" "It's false") ;; Evaluates to: "It's true" (if nil "It's true" "It's false") ;; Evaluates to: "It's false" - The empty list
():(if '() "It's true" "It's false") ;; Evaluates to: "It's false" (because '() is the same as nil) - Numbers (the surprising case):
(if 1 "It's true" "It's false") ;; Evaluates to: "It's true" (if 0 "It's true" "It's false") ;; Evaluates to: "It's true" - Strings (another surprising case):
(if "hello" "It's true" "It's false") ;; Evaluates to: "It's true" (if "" "It's true" "It's false") ;; Evaluates to: "It's true" - A non-empty list:
(if '(a b c) "It's true" "It's false") ;; Evaluates to: "It's true"
This video from System Crafters demonstrates this exact process, providing a good visual reinforcement of the experiments you just conducted.
Types, Conditionals, and Loops - Learning Emacs Lisp #2
This short clip walks through the concept of truthiness in Elisp, using if to test different values just as we did above. Watching it will help solidify your understanding.
Watch from 00:56:57 to 00:58:02. The speaker explains and demonstrates how values like numbers, strings, nil, and the empty list are evaluated in a conditional context.
4. Predicates: Functions That Answer Questions
Now that you understand what Elisp considers true and false, you can better appreciate a common category of functions called predicates. A predicate is simply a function that tests a condition and returns either t (true) or nil (false).
By convention in Elisp, the names of many (but not all) predicate functions end with the letter p.
For example:
stringpchecks if its argument is a string.numberpchecks if its argument is a number.listpchecks if its argument is a list.
Let's test a few in your *scratch* buffer:
(stringp "I am a string") ;; Returns t
(stringp 42) ;; Returns nil
(numberp 100) ;; Returns t
(numberp "not a number") ;; Returns nil
(> 5 4) ;; Returns t
(< 5 4) ;; Returns nil
When we start building conditional logic, we will use predicates extensively as the CONDITION part of our if statements. For example, (if (stringp my-variable) ...) will allow us to perform an action only if my-variable holds a string.
Conclusion
In this lesson, we've established the fundamental rule of logic in Emacs Lisp. This simple but powerful concept is the bedrock upon which all decision-making in your future Elisp code will be built.
Key Takeaways:
- Elisp does not have a separate boolean type; it uses the symbols
tfor true andnilfor false. nilis unique because it also represents the empty list (()).- The core rule of truthiness is:
nilis false, and every other value is true. - This means values like
0and the empty string"", which are often "falsy" in other languages, are considered true in Elisp. - Predicates are functions, often ending in
-p, that are designed to answer a yes/no question by returningtornil.
Preview of the Next Lesson
Now that you can distinguish between true and false values, you're ready to make your code act on that distinction. In the next lesson, we will formally dive into conditional control flow. You will learn to use if, when, and unless to create branching logic, allowing your functions to execute different code paths based on the outcomes of your tests.