Полезная программа различает код и данные и выбирает один результат. В Лиспексе обе операции видимы: цитирование сохраняет данные, условие выбирает вычисляемое выражение.
Цитирование сохраняет форму как данные
Без апострофа непустой список вычисляется:
(+ 1 2)С апострофом та же форма возвращается как данные:
'(+ 1 2)Результат
(+ 1 2)Новый список можно построить из вычисленных значений:
(list 'decision 'allow)Результат
(decision allow)Цитируйте фиксированные данные. Используйте list, если элементы нужно
вычислить.
if делает один двусторонний выбор
У if есть тест, результат для истины и результат для лжи:
(if (>= 62 50)
'(decision free-shipping)
'(decision standard-shipping))Вычисляется только выбранная ветвь. Ложен только #f; 0, "" и () истинны.
Если нужен смысл «непусто» или «положительно», используйте явный предикат.
and и or останавливаются раньше
and идёт слева направо и останавливается на #f. or останавливается на
первом истинном значении:
(and (<= 9 14)
(not #f))Результат
#tВыражение справа не вычисляется, если ответ уже известен. Короткое замыкание — часть порядка вычисления.
cond называет несколько случаев
(define (shipping-decision total member?)
(cond
((>= total 50) '(decision free-shipping))
(member? '(decision discounted-shipping))
(else '(decision standard-shipping))))
(shipping-decision 42 #t)Результат
(decision discounted-shipping)Условия проверяются сверху вниз. Большая сумма выигрывает до проверки
участника. else — запасной исход. Подписанный список объясняет ответ даже без
знания процедуры.
При необходимости разберите список
Для правильного списка car возвращает первое значение, cdr — оставшийся
список:
(define answer '(decision allow))
(list (car answer) (car (cdr answer)))Результат
(decision allow)В обычном правиле прямое построение и именованные помощники часто понятнее.
Цепочки car/cdr полезны для обучения и низкоуровневого доступа.
Упражнение
Напишите age-decision: возраст 18 и выше возвращает (decision allow),
меньший — (decision deny under-age).
Показать один ответ
(define (age-decision age)
(if (>= age 18)
'(decision allow)
'(decision deny under-age)))
(age-decision 17)Результат: (decision deny under-age).
Готовы к шагу 4?
Объясните разницу между '(decision allow) и (decision allow), назовите три
позиции if и скажите, почему 0 не ложь. Далее:
Первое решающее правило.