DECLARE 선언

DECLARE 선언 (declare)

declare는 Common Lisp에서 **선언(declaration)**으로 불리는 표현식이에요. 특수 연산자도 매크로도 아니고, 실행해서 값을 얻는 폼이 아니라 특정 폼의 몸체 맨 앞에서 컴파일러에 타입이나 최적화 같은 정보를 알려주는 역할을 해요. 실제로는 평가되지 않기 때문에, 존재하는 걸 확인해서 처리하는 폼이랍니다.

출처: CLHS: Symbol DECLARE

문법 (Syntax)

declare declaration-specifier*

인자 (Arguments)

  • declaration-specifier — 선언 지정자(declaration specifier)이며, 평가되지 않아요.

설명 (Description)

declare 표현식은 가끔 선언(declaration)이라고도 하는데, 특정 폼의 몸체 맨 앞에서만 나타날 수 있어요. 즉 앞에는 다른 declare 표현식이나, 맥락이 허락한다면 문서 문자열(docstring)만 올 수 있어요.

declare 표현식은 람다 표현식(lambda expression)이나 아래 그림에 나열된 폼들 중 어떤 것에서든 나타날 수 있어요.

defgeneric do-external-symbols prog 
define-compiler-macro do-symbols prog* 
define-method-combination dolist restart-case 
define-setf-expander dotimes symbol-macrolet 
defmacro flet with-accessors 
defmethod handler-case with-hash-table-iterator 
defsetf labels with-input-from-string 
deftype let with-open-file 
defun let* with-open-stream 
destructuring-bind locally with-output-to-string 
do macrolet with-package-iterator 
do* multiple-value-bind with-slots 
do-all-symbols pprint-logical-block 

Figure 3-23. 선언이 나타날 수 있는 표준 폼들

declare 표현식은 이 폼들의 문법이 정한 위치에서만 나타날 수 있어요. declare 표현식을 평가하려고 시도한 결과는 정의되어 있지 않은데요, 이 표현식이 나타날 수 있는 위치에서는 그 존재를 명시적으로 확인하고 실제로는 절대 평가하지 않기 때문이에요. 그래서 declare 폼(form)이 아니라 declare 표현식(expression)이라고 부르는 거예요.

매크로 폼(macro form)은 선언으로 확장(expand)될 수 없어요. declare 표현식은 자기 자신이 가리키는 폼의 실제 하위 표현식으로 나타나야 해요.

declare와 함께 쓸 수 있는 선언 식별자(declaration identifier) 목록은 다음 그림과 같아요.

dynamic-extent ignore optimize 
ftype inline special 
ignorable notinline type 

Figure 3-24. 로컬 선언 지정자들

구현체는 그 밖에도 고유한(구현 정의된) 선언 식별자를 지원할 자유가 있어요.

예제 (Examples)

 (defun nonsense (k x z)
   (foo z x)              ;First call to foo
   (let ((j (foo k x))    ;Second call to foo
         (x (* k k)))
     (declare (inline foo) (special x z))
     (foo x j z)))        ;Third call to foo

이 예시에서 inline 선언은 foo에 대한 세 번째 호출에만 적용돼요. 첫 번째나 두 번째 호출에는 적용되지 않아요. x에 대한 special 선언은 letx를 동적 바인딩(dynamic binding)하게 만들고, let 몸체 안의 x 참조를 동적 참조가 되게 해요. 두 번째 호출에서 참조하는 xnonsense의 두 번째 매개변수에 대한 로컬 참조예요. 첫 번째 호출의 x 참조 역시 로컬 참조이며 special 참조가 아니에요. z에 대한 special 선언은 세 번째 호출에서 z 참조를 동적 참조로 만들어요. 다만 nonsensez라는 매개변수를 가리키지는 않는데, 그 매개변수의 바인딩은 special로 선언되지 않았기 때문이에요. (zspecial 선언은 defun 몸체에 있는 게 아니라 안쪽 폼에 있어서, 그 매개변수의 바인딩에는 영향이 없어요.)

영향 (Affected By)

없음.

예외 상황 (Exceptional Situations)

declare 표현식을 평가할 폼으로 쓰려고 하면 결과가 정의되어 있지 않아요.

함께 보기 (See Also)

  • proclaim
  • Section 4.2.3 (Type Specifiers)
  • declaration, dynamic-extent, ftype, ignorable, ignore, inline, notinline, optimize, type

참고 (Notes)

없음.

더 알아보기 (Learn more)