Песочница

Значения, имена и процедуры

Научитесь читать литералы и вызовы Лиспекса, связывать имена через `define` и `let` и создавать повторно используемые процедуры через `lambda`.

На первом шаге вы запустили целую программу. Теперь разделим её на несколько форм. Когда значение, имя значения и вызов процедуры различаются, скобки читаются в устойчивом порядке.

Значения могут стоять сами

Числа, boolean, строки, characters и цитированные данные — значения:

LISPEX
42
#t
"Lispex"
#\L
'ready

Голый symbol ready отличается: Лиспекс ищет его как имя. 'ready сохраняет symbol как данные.

Список в позиции вызова просит выполнить работу

Читайте изнутри наружу:

LISPEX
(+ 10 (* 2 3))

Лиспекс находит +, вычисляет 10, затем слева направо вычисляет (* 2 3). Внутренний вызов даёт 6, поэтому внешний эквивалентен (+ 10 6).

Результат

OUTPUT
16

Не каждые скобки — обычный вызов. define, lambda, let и if управляют тем, что вычисляется и где видны имена.

Свяжите значение с именем

define создаёт или обновляет верхнеуровневое связывание:

LISPEX
(define fee 3)
(+ 20 fee)

Результат

OUTPUT
23

Определение ничего не печатает, последнее сложение печатает одно значение.

Для имени внутри одного тела используйте let:

LISPEX
(let ((base 7))
  (* base 2))

Результат

OUTPUT
14

base видно только в теле. Узкая область делает временное вычисление понятнее.

Создайте повторно используемую процедуру

Сокращение определения называет процедуру и её входы:

LISPEX
(define (price-with-fee price fee)
  (+ price fee))

(price-with-fee 20 3)

Результат

OUTPUT
23

Длинная форма явно показывает, что процедура — значение:

LISPEX
(define price-with-fee
  (lambda (price fee)
    (+ price fee)))

Процедура проверяет арность. Один или три аргумента для price-with-fee приведут к ошибке выполнения, а не к неявному значению по умолчанию.

Соедините части

LISPEX
(define (price-with-fee price fee)
  (+ price fee))

(list (price-with-fee 20 3)
      (let ((base 7))
        (* base 2)))

Результат

OUTPUT
(23 14)

Сначала вычисляется первый элемент списка, затем второй. list получает два готовых значения и создаёт (23 14).

Упражнение

Определите triple, умножающий вход на 3, и вызовите его дважды внутри list, чтобы получить (12 21).

Показать один ответ
LISPEX
(define (triple n)
  (* n 3))

(list (triple 4) (triple 7))

Готовы к шагу 3?

Переходите дальше, если можете объяснить, почему цитированный symbol — данные, почему (* 2 3) заканчивается до внешнего сложения и где видно имя let. Далее: Данные, условия и решения.