Песочница

Условия и производные формы

Небольшое ядро из if, последовательности, связывания, lambda, применения, присваивания и quote получает производные формы, которые переписываются без захвата выбранных вами имён.

Когда это нужно

Выбирайте условную форму по вопросу. Это может быть один выбор «да/нет», несколько предикатов, сравнение одного значения с фиксированными данными или односторонний эффект. Ложным является только #f.

Проверьте запуском

LISPEX
(case 2 ((1) 'one) ((2) 'two) (else 'other))

Наблюдаемый результат

OUTPUT
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 являются статическими ошибками.

Куда дальше

Повседневные формы разбираются в уроке о данных и решениях, а точную нормализацию описывает справочник производных форм.

Данные и решения · Производные формы