common-lisp
Логические и обобщенные булевы
Поиск…
Правда и ложь
Специальный символ T
представляет значение true в Common Lisp, а специальный символ NIL
представляет false :
CL-USER> (= 3 3)
T
CL-USER> (= 3 4)
NIL
Они называются «константными переменными» (sic!) В стандарте, поскольку они являются переменными, значение которых не может быть изменено. Как следствие, вы не можете использовать свои имена для обычных переменных, например, в следующем, неверном, например:
CL-USER> (defun my-fun(t)
(+ t 1))
While compiling MY-FUN :
Can't bind or assign to constant T.
Собственно, их можно рассматривать просто как константы или как самооцененные символы. T
и NIL
- это специальные вещи в других смыслах. Например, T
также является типом (супертипом любого другого типа), тогда как NIL
также является пустым списком:
CL-USER> (eql NIL '())
T
CL-USER> (cons 'a (cons 'b nil))
(A B)
Обобщенные булевы
Фактически любое значение, отличное от NIL
, считается истинным значением в Common Lisp. Например:
CL-USER> (let ((a (+ 2 2)))
(if a
a
"Oh my! 2 + 2 is equal to NIL!"))
4
Этот факт можно комбинировать с булевыми операторами, чтобы сделать программы более краткими. Например, приведенный выше пример эквивалентен:
CL-USER> (or (+ 2 2) "Oh my! 2 + 2 is equal to NIL!")
4
Макрос OR
оценивает свои аргументы в порядке слева направо и останавливается, как только он находит значение, отличное от NIL, и возвращает его. Если все они являются NIL
, возвращаемое значение равно NIL
:
CL-USER> (or (= 1 2) (= 3 4) (= 5 6))
NIL
Аналогично, макрос AND
оценивает свои аргументы слева направо и возвращает значение последнего, если все они оцениваются не-NIL, в противном случае останавливает оценку, как только находит NIL
, возвращая его:
CL-USER> (let ((a 2)
(b 3))
(and (/= b 0) (/ a b)))
2/3
CL-USER> (let ((a 2)
(b 0))
(and (/= b 0) (/ a b)))
NIL
По этим причинам AND
и OR
можно считать более похожими на управляющие структуры других языков, а не на логические операторы.