Lambda как построение процедуры без имени
Сравнивайте именованные и анонимные процедуры, применяйте lambda напрямую и отслеживайте лексические связывания при создании вложенных процедур.
Какое значение создает выражение lambda и какие связывания будет использовать его тело при последующем применении этого значения?
- Чтение lambda как выражения, создающего значение процедуры
- Соотнесение краткой формы define для процедур со связыванием имени и значения lambda
- Применение анонимной процедуры без присвоения ей постоянного имени
- Отслеживание вложенных областей видимости параметров через лексический поиск
- Передача только что созданной процедуры в качестве обычного значения аргумента
Краткая форма определения (define (square x) ...) связывает имя с процедурой. Запись (define square-lambda (lambda (x) ...)) делает два этапа явными: lambda создает значение процедуры, а define связывает с ним имя. Выражение lambda также можно применить немедленно, поэтому процедуре суммы квадратов с двумя аргументами не требуется постоянное имя верхнего уровня.
Во вложенном примере внешняя lambda связывает x со значением 3, а внутренняя lambda связывает y со значением 4. Внутреннее тело находит y в собственном вызове, а x в окружающем лексическом окружении, при этом глобальный x остается равным 100. Последнее выражение передает вновь созданную процедуру square в другую lambda, показывая, что создание, связывание, передача и применение процедур используют обычную модель значений.
- Вывод
- —
- Значение
- —
- Диагностика
- —
Первая программа возвращает (36 36 25). Вторая возвращает (100 7 100).
Отделите каждое вычисление lambda, создающее значение процедуры, от каждого последующего применения. Во вложенной программе найдите внутренний поиск x в объемлющем окружении вызова и y в текущем вызове. Убедитесь, что глобальное связывание x не изменяется.
Измените программу и сравните результат.
Перепишите выражение let с двумя связываниями как немедленное применение lambda с двумя параметрами. Затем передайте выражение lambda, утраивающее свой входной аргумент, в процедуру, которая применяет свой аргумент дважды.
Показать подсказку
Выражение let с параллельными связываниями можно представить как ((lambda (name ...) body) value ...). Отделяйте создание процедуры от каждого применения.