eval
는 어휘 변수가 같은 표현에서 만든 모든 않는 한에서 어휘 변수와 함께 작동하지 않습니다 eval
항상 환경의 글로벌 바인딩 최상위 일어나고로
이
#!r7rs
(import (scheme base)
(scheme eval))
(define env (environment '(scheme base)))
(let ((x 10))
(eval 'x env)) ; ERROR! `x` is not defined
당신이 생각 할 수 있습니다 두 번째 인수로 전달하십시오. 당신은 아마이 같이 당신의 어휘 환경에서 값을 전달하여 속일 수 시간으로
(eval '(let ((x 10))
x)
env) ; ==> 10
(let ((x 10))
(eval `(let ((x ,x))
x)
env) ; ==> 10
대부분의 계획 구현 코드 지역 변수는 일반적으로 할당 스택되어 실행합니다.
(define (test v)
(display v)
(newline)
(eval 'v))
런타임에이로 변신 할 수 있음 :
(define (test 1 #f) ; indicates 1 argument, no rest
(display (ref 0)) ; fetches first argument from stack
(newline)
(eval 'v)) ; but what is v?, certainly not the first argument
는 또한이 코너 케이스를 만들 수 있습니다 따라서 무언가가이 코드를 상상한다. 돌연변이하면 어떻게 될까요?이
v
이 많은 컴파일 계획의 구현은 코드가
v
특별한 필요가 있다고 실행하기 전에 알 필요가 있으므로 다른 돌연변이 변수를 처리 할 필요가 돌연변이 도착하지 명백한 것을 그래서
(define (test v)
(eval '(set! v 10))
v)
eval
에 대한 구조는 사용자의 입력에서 올 수도 (set! v 10)
은 데이터베이스 또는 사용자 입력에서 올 수 있으므로 결정할 수는 없습니다. 따라서 로컬 바인딩을 포함시키지 않으면 많은 문제를 해결할 수 있으며 언어를 최적화하고 컴파일하기가 더 쉽습니다.
매크로를 퍼스트 클래스 객체로 전달할 수 있기 때문에 해석 할 수있는 리스프 언어가 있습니다. 이러한 언어는 컴파일 할 때 추론 할 수 없습니다.
이 내용은 [Racket 가이드] (https://docs.racket-lang.org/guide/eval.html)에서 비교적 잘 설명되어 있습니다. – molbdnilo