Когда это нужно
Создайте процедуру, когда преобразованию нужно имя или его требуется передать другой процедуре. Именованная сокращённая форма читается проще. lambda удобна для небольшого локального поведения.
Проверьте запуском
(define (sum first . rest) (apply + first rest))
(sum 1 2 3 4)Наблюдаемый результат
10Разбор примера
sum требует хотя бы один аргумент. first получает 1, а rest получает новый список (2 3 4). apply объединяет явный первый аргумент с этим списком и один раз вызывает +.
Идущие подряд формы define в самом начале тела процедуры создают имена, видимые только внутри неё. Они могут вызывать друг друга.
(define (g)
(define a 1)
(define b 2)
(+ a b))
(g)Наблюдаемый результат
3Так собирается только непрерывный участок в начале. define после какого-нибудь другого выражения значит уже иное, поэтому держите определения вместе наверху.
Как рассуждать
- Несовпадение арности даёт E302 до начала тела процедуры.
- Точечный параметр остатка получает новый правильный список оставшихся аргументов.
- Список параметров
lambdaимеет ровно две формы,(x ...)и(x ... . rest). Голое имя без скобок, как в(lambda args ...), даёт E130. applyпринимает явные начальные аргументы и один последний правильный список, сохраняя хвостовую позицию.
Быстрый выбор
| Форма | Подходящее применение | Арность |
|---|---|---|
(define (f x) body) | именованная повторно используемая процедура | фиксированная |
(lambda (x y) body) | анонимная процедура-значение | фиксированная |
(define (f . xs) body) | именованная процедура собирает свои аргументы | ноль или больше |
(lambda (x . rest) body) | обязательная часть и остаток | не меньше фиксированной части |
(apply f a final-list) | применение аргументов, собранных как данные | проверяет f |
Частая ошибка
Применение непроцедуры даёт E301. Неправильный последний список apply даёт ошибку домена списка.
Текущие границы
- Для выполнения гостевых замыканий не используется
applyсреды.
Куда дальше
Справочник процедур высшего порядка показывает передачу поведения в map, filter и fold, а глава о связываниях объясняет захваченные ячейки.