Песочница

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

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

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

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

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

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

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