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