Когда это нужно
Выбирайте условную форму по вопросу. Это может быть один выбор «да/нет», несколько предикатов, сравнение одного значения с фиксированными данными или односторонний эффект. Ложным является только #f.
Проверьте запуском
(case 2 ((1) 'one) ((2) 'two) (else 'other))Наблюдаемый результат
twoРазбор примера
case один раз вычисляет 2, сравнивает его с каждым указанным значением через eqv? и выбирает вторую ветвь. Результатом становится цитированный символ two, а ветвь else не выполняется.
when выполняет тело по порядку только при истинной проверке и отдаёт последнее значение. unless наоборот выполняет тело при ложной проверке. Поэтому (when #t 42) даёт 42, а (unless #f 7) даёт 7. Отвергнутый проверкой путь не даёт ни одного значения.
guard записывается как (guard (переменная ветвь ...) тело ...). Когда тело возбуждает ошибку, объект ошибки связывается с переменной, а ветви перебираются по порядку так же, как их перебирает cond. В голове ветви можно написать else.
Как рассуждать
cond,case,and,or,when,unless,let*, именованныйlet,doи quasiquote сохраняют закреплённый порядок и хвостовые позиции.- Сгенерированные временные имена и скрытые встроенные операции нельзя захватить или затенить пользовательскими именами.
caseсравнивает datum черезeqv?, а ложные путиwhenиunlessдают ноль значений.- У
ifобязательны все три части. Уберите ложную ветвь и напишите(if #t 1), и получите E130. condилиcaseбез ветвиelseне даёт ни одного значения, если ничего не совпало. Поставьте такой результат туда, где нужно значение, и получите E320.elseне является зарезервированным словом. Оно значимо только в голове ветвиcond,caseилиguard, поэтому(define else 5)проходит.- Стрелочная ветвь
=>уcondне поддерживается и даёт E130. Уcaseстрелочной ветви нет даже диагностики, поэтому=>читается как имя и даёт E300.
Быстрый выбор
| Форма | Когда применять | Поведение результата |
|---|---|---|
if | ровно две ветви | возвращает выбранную ветвь |
cond | несколько предикатов описывают случаи | возвращает первую подходящую ветвь |
case | одно значение сравнивается с фиксированными данными | вычисляет ключ один раз |
and / or | нужна короткая остановка цепочки | возвращает значение операнда, а не приведённое булево значение |
when / unless | нужен односторонний эффект | ложный путь даёт ноль значений |
Частая ошибка
Нет define-syntax и пользовательского расширения макросов.
Текущие границы
- Отдельные
unquoteиunquote-splicingвне quasiquote являются статическими ошибками.
Куда дальше
Повседневные формы разбираются в уроке о данных и решениях, а точную нормализацию описывает справочник производных форм.