2016-09-03 12 views
1

Если eval с (interaction-environment) должен иметь доступ ко всему, что определено в пределах лексической области, когда оно вызывается, то почему я получаю эту ошибку, когда пытаюсь запустить приведенный ниже код?r5rs eval не находит ссылку в пределах своей лексической области

Welcome to DrRacket, version 6.3 [3m]. 
Language: R5RS; memory limit: 128 MB. 
why does this work? object_function: undefined; 
cannot reference undefined identifier 

Код:

(define (disp x) 
    (display x)) 
(eval '(disp "why does this work?") (interaction-environment)) 

;The below doesn't work 

((lambda() 
    (define (object_function x) 
    (display x)) 
    (eval '(object_function "But not this?") (interaction-environment)))) 

(define (object) 
    (define (object_function x) 
    (display x)) 
    (eval '(object_function "And not this?") (interaction-environment))) 
(object) 

Если изменить его следующим образом:

;The below does work 

(define (object_function x) 
    (display x)) 

((lambda() 
    (eval '(object_function "Why does it work now?") (interaction-environment)))) 

(define (object) 
    (eval '(object_function "And now?") (interaction-environment))) 
(object) 

Выход:

Welcome to DrRacket, version 6.3 [3m]. 
Language: R5RS; memory limit: 128 MB. 
Why does it work now?And now? 

С eval сама по себе она работает просто отлично, но обертка он в определенной функции или в ambda, и он не может найти локально определенную функцию, которая находится в той же области действия, что и функция eval.

Возможно, я не понимаю, как eval или interaction-environment дело с лексическим объемом, но если кто-то может пролить свет на это, это было бы полезно.

+3

Ваше предположение неверно; 'eval' не должен иметь доступа к этому. «environment-environment» - это среда взаимодействия, а не локальная среда внутри вашей функции. – molbdnilo

ответ

4

Когда eval оценивает данные, которые он делает на верхнем уровне. Лексическая глубина с того места, где вы звоните eval, не попадает в оценку. Второй аргумент изменяется только между тремя различными глобальными средами, к которым вы можете получить доступ.

define внутри процедуры или пусть это просто фантазия letrec и, следовательно, лексическая привязка. Он не будет доступен с eval. Верхний уровень define делает глобальное связывание и его будет доступен с eval iff interaction-environment.

Реализации не должны реализовывать interaction-environment, так как это необязательно. Требуемые среды: null-environment, которые имеют только специальные формы и scheme-report-environment, что является исходной средой системы.

eval - это мощная функция, которая обычно является неправильным решением. Обычно вы делаете это неправильно, если вам нужно использовать eval.