Песочница

Выражения и порядок вычисления

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

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

Порядок важен, когда выражение изменяет ячейку, печатает, выдаёт ошибку или может быть пропущено. Лиспекс фиксирует этот порядок, поэтому результат не зависит от соглашений языка-хозяина.

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

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 объясняются в главе о связываниях, а ранняя остановка — в главе об условиях.

Связывания и область · Условия