Нам нужна процедура, которая принимает S-выражение в качестве входных данных и выводит S-выражение с той же структурой, но где каждое целое число удваивается; как правило, процедура для отображения S-выражений:
(define (double x)
(if (number? x)
(* x 2)
x)))
(define (sexp-map op sexp)
...)
(sexp-map double some-sexpression)
Получаемое нами S-выражение (SEXP) будет либо атомом, в этом случае результатом будет (OP SEXP), либо списком S-выражений. В этом случае мы могли бы подумать о том, чтобы отобразить OP через SEXP, но S-выражения вкладываются как можно глубже. На самом деле мы должны отобразить процедуру, которая преобразует каждый элемент в меньшее S-выражение с помощью OP. Хорошо, если вы посмотрите на это, это просто еще один способ описать цель процедуры, которую мы сейчас пытаемся написать. Таким образом, мы можем отобразить SEXP-MAP через SEXP.
Ну, нет, на самом деле мы не можем, потому что SEXP-MAP нужно вызывать с двумя аргументами, а MAP даст ему только один. Чтобы обойти это, мы используем вспомогательную процедуру F с одним аргументом:
(define (sexp-map op sexp)
(define (f x)
(if (list? x)
(map f x)
(op x)))
(f sexp))
Ф завершает всю настоящую работу. SEXP-MAP сводится к тому, чтобы быть фасадом, который проще в использовании для программиста.