11.3 Конструкции для комбинирования условий

В этом разделе описываются конструкции, которые часто используются вместе с if и cond для выражения сложных условий. Конструкции and и or также могут использоваться по отдельности как виды множественных условных конструкций.

Функция: not condition

Эта функция проверяет ложность condition. Она возвращает t, если condition равна nil, и nil в противном случае. Функция not идентична null, и мы рекомендуем использовать имя null, если вы проверяете пустой список или значение nil.

Специальная форма: and conditions…

Специальная форма and проверяет, истинны ли все conditions. Она работает путем поочередной оценки conditions в порядке их написания.

Если какое-либо из conditions оценивается как nil, то результат and должен быть nil, независимо от оставшихся conditions; поэтому and немедленно возвращает nil, игнорируя оставшиеся conditions.

Если все conditions оказываются не-nil, то значение последнего из них становится значением формы and. Просто (and), без conditions, возвращает t, что подходит, поскольку все conditions оказались не-nil. (Подумайте об этом; какой из них не был?)

Вот пример. Первое условие возвращает целое число 1, которое не равно nil. Аналогично, второе условие возвращает целое число 2, которое не равно nil. Третье условие равно nil, поэтому оставшиеся условия никогда не оцениваются.

(and (print 1) (print 2) nil (print 3))
     -| 1
     -| 2
⇒ nil

Вот более реалистичный пример использования and:

(if (and (consp foo) (eq (car foo) 'x))
    (message "foo is a list starting with x"))

Обратите внимание, что (car foo) не выполняется, если (consp foo) возвращает nil, тем самым избегая ошибки.

Выражения and также могут быть записаны с использованием if или cond. Вот как это сделать:

(and arg1 arg2 arg3)
≡
(if arg1 (if arg2 arg3))
≡
(cond (arg1 (cond (arg2 arg3))))
Специальная форма: or conditions…

Специальная форма or проверяет, истинно ли хотя бы одно из conditions. Она работает путем поочередной оценки всех conditions в порядке их написания.

Если какое-либо из conditions оценивается как не-nil, то результат or должен быть не-nil; поэтому or немедленно возвращает значение, игнорируя оставшиеся conditions. Возвращаемое им значение — это не-nil значение только что оцененного условия.

Если все conditions оказываются nil, то выражение or возвращает nil. Просто (or), без conditions, возвращает nil, что подходит, поскольку все conditions оказались nil. (Подумайте об этом; какой из них не был?)

Например, это выражение проверяет, является ли x либо nil, либо целым числом ноль:

(or (eq x nil) (eq x 0))

Подобно конструкции and, or может быть записана с использованием cond. Например:

(or arg1 arg2 arg3)
≡
(cond (arg1)
      (arg2)
      (arg3))

Вы почти можете записать or с использованием if, но не совсем:

(if arg1 arg1
  (if arg2 arg2
    arg3))

Это не совсем эквивалентно, потому что оно может оценить arg1 или arg2 дважды. В отличие от этого, (or arg1 arg2 arg3) никогда не оценивает аргумент более одного раза.

Функция: xor condition1 condition2

Эта функция возвращает булево исключающее ИЛИ (exclusive-or) condition1 и condition2. То есть, xor возвращает nil, если оба аргумента равны nil, или оба не равны nil. В противном случае, она возвращает значение того аргумента, который не равен nil.

Обратите внимание, что в отличие от or, оба аргумента всегда оцениваются.