Lisp eval-when
연산자에 관한 많은 문서를 읽은 후에도 사용법을 이해할 수 없지만이 연산자를 사용하면 표현식의 평가 시간을 제어 할 수 있습니다. 그러나이 경우 적용 할 수있는 예제를 찾을 수 없습니까?Eval-when uses?
최고 감사합니다. utxeee. 리스프 파일의
Lisp eval-when
연산자에 관한 많은 문서를 읽은 후에도 사용법을 이해할 수 없지만이 연산자를 사용하면 표현식의 평가 시간을 제어 할 수 있습니다. 그러나이 경우 적용 할 수있는 예제를 찾을 수 없습니까?Eval-when uses?
최고 감사합니다. utxeee. 리스프 파일의
컴파일 예를 들어
걸릴 리스프 파일의 컴파일. Lisp 컴파일러는 최상위 양식을 처리합니다.
: 다음은 임의의 리스프 형태 DEFUNs, DEFMACROS, DEFCLASS, 함수 호출, ... 파일 컴파일러가 어떻게 작동하는지
전체 이야기는 여기에서 설명하기가 너무 복잡하지만 몇 가지 일 수있다 파일 컴파일러는 (DEFUN foo())
형식의 코드를 생성합니다. 그러나 그것은 defun 형식을 실행하지 않습니다. 따라서 컴파일하는 동안 함수가 FOO
인 것으로 알려져 있지만 컴파일 중에 'FOO'코드는 사용할 수 없습니다. 컴파일러는 컴파일 된 파일의 코드를 생성하지만 메모리에 유지하지 않습니다. 이러한 함수는 컴파일 할 때 호출 할 수 없습니다.
매크로의 경우 약간 다릅니다 ((DEFMACRO BAZ ...)
). 파일 컴파일러는 매크로를 컴파일 할뿐만 아니라 매크로도 컴파일하지만 컴파일 타임에 매크로를 사용할 수있게합니다. 컴파일러 환경에로드됩니다. 따라서
파일에 형태의 순서를 상상 :
파일 컴파일러는 매크로BAZ
을 알고는
FOO
에 대한 코드를 컴파일 할 때, 다음 매크로 양식을 확장 할 수 있기 때문에이 작동
(defmacro baz ...)
(defun foo() (baz ...))
.
이제 다음의 예를 살펴 보자 :
(defun bar (form) ...)
(defmacro baz (form) (bar form))
(defun foo() (baz ...))
위가 작동하지 않습니다. 이제 BAZ
매크로는 이것을 호출하여 BAR
함수를 사용합니다. 컴파일러에서 FOO
함수를 컴파일하려고하면 BAR
코드가 컴파일 타임 환경에로드되지 않기 때문에 BAR
을 호출 할 수 없기 때문에 BAZ
매크로를 확장 할 수 없습니다.
BAR
이전 : 이 두 가지 솔루션이 있습니다.
EVAL-WHEN
에 대한 EVAL-WHEN예 :
(eval-when (:compile-toplevel :execute :load-toplevel)
(defun bar (form) ...)
)
(defmacro baz (form) (bar form))
(defun foo() (baz ...))
이제 EVAL-WHEN
실제로 컴파일시 DEFUN 양식을 실행할 수있는 파일 컴파일러에 지시합니다.이것의 효과는 다음과 같습니다. 파일 컴파일러는 BAR
의 정의를 에서 컴파일 시간으로 알고 있습니다. 따라서 파일 컴파일러가 BAZ
의 매크로 확장 중에 BAR
을 호출해야 할 때 나중에 사용할 수 있습니다.
파일을 컴파일 한 후에 기능을 필요로하지 않을 때 :compile-toplevel
만 사용할 수 있습니다. 나중에 사용한다면,로드 될 수 있도록해야합니다.
그래서 EVAL-WHEN
코드의 특정 부분이
EVAL-WHEN
는 실행 중에 파일
안녕 라이너,하지만 왜 우리는 플래그를 사용해야합니다 : 실행 및로드 최상위 수준 의이 사용의 경우? – utxeee
Rainer는 이전 답을 편집하여 답신을 보내 주셔서 다시 한번 감사드립니다. D 그러나,로드 - 톱 레벨 및 : 실행과 같은 플래그를 사용해야하는 이유는 여전히 남아 있습니다. 텍스트에서 나중에 함수를 사용하는 경우 load-top-level 플래그를 사용해야 함을 알 수 있습니다. 그렇다면 왜 우리는 eval을 사용할 필요가 없습니다. 나중에 사용할 다른 모든 기능에서 load-top-level입니까? – utxeee
@utxeee : 컴파일시 EVAL-WHEN이 없을 때 load-top-level이 기본값입니다. –