Песочница

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

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

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

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

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

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*связывание после каждого инициализатораничего

Частая ошибка

Лиспекс не наследует неопределённый порядок операндов другой реализации Scheme.

Текущие границы

  • Ошибка арности возникает после обязательного вычисления оператора и операндов.

Куда дальше

Различия областей let объясняются в главе о связываниях, а раннюю остановку разбирает глава об условиях.

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