2012-05-20 2 views
11

Lisp eval-when 연산자에 관한 많은 문서를 읽은 후에도 사용법을 이해할 수 없지만이 연산자를 사용하면 표현식의 평가 시간을 제어 할 수 있습니다. 그러나이 경우 적용 할 수있는 예제를 찾을 수 없습니까?Eval-when uses?

최고 감사합니다. utxeee. 리스프 파일의

답변

21

컴파일 예를 들어

걸릴 리스프 파일의 컴파일. 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 매크로를 확장 할 수 없습니다.

  1. 컴파일 별도의 파일을 사용하여 부하 BAR 이전 :

    이 두 가지 솔루션이 있습니다.

  2. 사용 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는 실행 중에 파일

  • 의로드하는 동안 파일
  • 의 컴파일시
    • 를 실행할지 여부를 지정할 수 있습니다 사용자 코드에서 자주 사용되지 않습니다. 당신이 그것을 사용한다면, 당신이 정말로 그것을 필요로하는지 스스로에게 물어야합니다.

  • +0

    안녕 라이너,하지만 왜 우리는 플래그를 사용해야합니다 : 실행 및로드 최상위 수준 의이 사용의 경우? – utxeee

    +0

    Rainer는 이전 답을 편집하여 답신을 보내 주셔서 다시 한번 감사드립니다. D 그러나,로드 - 톱 레벨 및 : 실행과 같은 플래그를 사용해야하는 이유는 여전히 남아 있습니다. 텍스트에서 나중에 함수를 사용하는 경우 load-top-level 플래그를 사용해야 함을 알 수 있습니다. 그렇다면 왜 우리는 eval을 사용할 필요가 없습니다. 나중에 사용할 다른 모든 기능에서 load-top-level입니까? – utxeee

    +0

    @utxeee : 컴파일시 EVAL-WHEN이 없을 때 load-top-level이 기본값입니다. –

    관련 문제