Ваш вопрос относится к Ракетке. В общем, разные реализации Scheme имеют разные подходы к этой проблеме, но почти во всех случаях вы не получите eval
для обработки локальных привязок, как вы пытаетесь это сделать. Но, что касается случая с Racket, вы должны прочитать раздел оценки *1003* в руководстве по Racket - он объясняет, почему вещи не работают так, как вы этого хотите, и показывает, как заставить работать модуль модуля. .
Точно так же, как краткое резюме - причина, по которой локальные привязки не видны для eval
, заключается в том, что это означает, что (lambda (x) x)
и (lambda (y) y)
не могут быть скомпилированы для одной и той же функции, поскольку имена могут иметь значение. Вы можете утверждать, что компиляция может зависеть от того, используется eval
внутри функции или нет - но это то, что нельзя определить во время компиляции. Например:
(define (foo f) (let ([x 1]) (f 'x)))
(foo eval)
В этом случае компилятор не сможет сказать, что foo
когда-либо будет вызываться с eval
.
Наконец, есть аналогичные трудности в других языках, которые пытаются решить eval
. Например, в JS eval
- это волшебная вещь, которая может влиять на компиляцию функции, поэтому что-то вроде:
function foo(x) { alert("x = " + eval("x")); }
на самом деле будет работать - но для физического присутствия в теле функции требуется eval
. Если этого не сделать, то все может сломаться. Например, этот код:
function foo(x,f) { alert("x = " + f("x")); }
foo(123,eval);
работает для меня в Fx, но не работает в Chrome, говоря, что x is not defined
. И если этого недостаточно, чтобы продемонстрировать беспорядок, подумайте:
function foo(x,f) { alert("x = " + f("x")); }
var x = 456;
foo(123,eval);
показывает 456 в Chrome и в Fx.