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 можно считать более похожими на управляющие структуры других языков, а не на логические операторы.