Песочница

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

Различайте значения, имена и вызовы. Создайте процедуру с помощью define, let и lambda.

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

Сначала прочитайте раздел Первая программа. Запускайте каждый пример отдельно на площадке. В результатах ниже площадка автоматически показывает значения выражений верхнего уровня.

В примере ширины к обрезному формату 20 см добавляется суммарный вылет 3 см с двух краёв. Получается 23 см.

Запишите значения напрямую

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

Площадка покажет пять значений.

42
#t
"Lispex"
#\L
ready

Это число, булево значение, строка, знак и символ. Булевы значения обозначают истину или ложь и записываются как #t и #f. #\L обозначает отдельный знак L, а "Lispex" обозначает строку.

Символ обозначает значение, например ready, которое можно использовать как имя в коде. Запись ready велит Лиспексу найти значение этого имени. Запись 'ready возвращает сам символ. Апостроф сохраняет его как данные.

Проследите вложенный вызов

LISPEX
(+ 10 (* 2 3))

Результат

ВЫВОД
16

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

Обычный вызов вычисляет аргументы перед вызовом процедуры. У форм define, lambda, let и if свои правила вычисления. Эти правила также определяют, где можно использовать имя.

Дайте значению имя

LISPEX
(define вылет 3)
(+ 20 вылет)

Результат

ВЫВОД
23

Здесь define даёт значению 3 имя вылет. Следующие выражения в файле могут использовать это имя. Повторный define на верхнем уровне обновляет значение существующего имени.

Само определение не создаёт значения для показа. Площадка показывает 23, полученное при сложении.

Создайте локальное имя

LISPEX
(let ((поле 7))
  (* поле 2))

Результат

ВЫВОД
14

let даёт значению 7 имя поле внутри своего тела, (* поле 2). Это локальное имя доступно только в данном теле. Часть программы, где можно использовать имя, называют его областью видимости.

Создайте процедуру для повторных вызовов

LISPEX
(define (ширина-с-вылетом ширина-обреза вылет)
  (+ ширина-обреза вылет))

(ширина-с-вылетом 20 3)

Результат

ВЫВОД
23

Этот код определяет процедуру с двумя входными именами, ширина-обреза и вылет. Вызов передаёт им значения 20 и 3. Тело складывает эти значения.

То же определение можно записать с помощью lambda.

LISPEX
(define ширина-с-вылетом
  (lambda (ширина-обреза вылет)
    (+ ширина-обреза вылет)))

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

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

LISPEX
(define (ширина-с-вылетом ширина-обреза вылет)
  (+ ширина-обреза вылет))

(list (ширина-с-вылетом 20 3)
      (let ((поле 7))
        (* поле 2)))

Результат

ВЫВОД
(23 14)

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

Упражнение

Определите процедуру triple, которая умножает входное значение на 3. Вызовите её дважды внутри list, чтобы получить (12 21).

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

(list (triple 4) (triple 7))

Результат равен (12 21).

Теперь проследите порядок вложенного вызова и укажите, где доступно имя поле. В разделе Код и есть данные вы сравните вызовы с цитированными списками.