Когда это нужно
Порядок важен, когда выражение изменяет ячейку, печатает, выдаёт ошибку или может быть пропущено. Лиспекс фиксирует этот порядок, поэтому результат не зависит от соглашений языка-хозяина.
Проверьте запуском
LISPEX
(define x 0)
(list (begin (set! x 1) x) (begin (set! x (+ x 1)) x))Наблюдаемый результат
OUTPUT
(1 2)Разбор примера
Первый begin меняет x с 0 на 1 и возвращает 1. Лишь затем второй операнд читает новое значение, прибавляет единицу, сохраняет 2 и возвращает его. Поэтому list получает сначала 1, затем 2.
Как рассуждать
- Инициализаторы
letвычисляются слева направо во внешнем окружении;let*расширяет по одному связыванию;letrecсначала выделяет все ячейки. - Последовательности вычисляются слева направо и отбрасывают пакеты значений не последних выражений.
andиorвыполняют короткое замыкание слева направо; ложно только#f.
Быстрый выбор
| Контекст | Порядок | Что может не выполняться |
|---|---|---|
| вызов процедуры | оператор, затем операнды слева направо | ничего |
begin | формы слева направо | ничего; ранние значения лишь отбрасываются |
if | условие, затем одна выбранная ветвь | невыбранная ветвь |
and / or | операнды слева направо | остаток после получения ответа |
let | инициализаторы слева направо во внешней области | ничего |
let* | связывание после каждого инициализатора | ничего |
Частая ошибка
Lispex не наследует неопределённый порядок операндов другой реализации Scheme.
Текущие границы
- Ошибка арности возникает после обязательного вычисления оператора и операндов.
Куда дальше
Различия областей let объясняются в главе о связываниях, а ранняя остановка — в главе об условиях.