최상위 레벨 폼 확장
최상위 레벨 폼 확장 (Expanding Top-Level Forms)
매크로를 프로그래밍 방식으로 확장하려면 expand 계열의 함수를 사용해요. 이 문서에서는 expand, expand-once, expand-to-top-form과 syntax 객체용 변형들, 그리고 확장된 모듈 정보에 대해 설명합니다.
출처: Racket Reference
본문
procedure
(expand top-level-form [insp]) → syntax?
top-level-form : any/c
insp : inspector? = (current-code-inspector)
top-level-form의 모든 비-기본(non-primitive) 구문을 확장하고, "Fully Expanded Programs"에 의해 지정된 문법을 만족하는 핵심 폼만 포함하는 확장된 폼에 대한 구문 객체를 반환합니다.
top-level-form이 확장되기 전에, 그 어휘적 컨텍스트는 eval에서처럼 namespace-syntax-introduce로 강화됩니다. 반환된 구문 객체를 인쇄 가능한 datum으로 변환하려면 syntax->datum을 사용하세요.
insp가 원래의 코드 인스펙터(즉, Racket이 시작될 때의 (current-code-inspector) 값)가 아니면, 결과 구문 객체는 테인트(taint)됩니다.
모듈에 expand를 사용하는 예시입니다:
(parameterize ([current-namespace (make-base-namespace)])
(expand
(datum->syntax
#f
'(module foo scheme
(define a 3)
(+ a 4)))))
최상위 레벨이 아닌 폼에 expand를 사용하는 예시입니다:
(define-namespace-anchor anchor)
(parameterize ([current-namespace
(namespace-anchor->namespace anchor)])
(expand
(datum->syntax
#f
'(delay (+ 1 2)))))
base 패키지의 8.2.0.4 버전에서 변경됨: insp 인자와 테인팅이 추가되었습니다.
procedure
(expand-syntax stx [insp]) → syntax?
stx : syntax?
insp : inspector? = (current-code-inspector)
(expand stx insp)와 같지만, 인자가 구문 객체여야 하고, 확장 전에 어휘적 컨텍스트가 강화되지 않습니다.
base 패키지의 8.2.0.4 버전에서 변경됨: insp 인자와 테인팅이 추가되었습니다.
procedure
(expand-once top-level-form [insp]) → syntax?
top-level-form : any/c
insp : inspector? = (current-code-inspector)
top-level-form을 부분적으로 확장하고, 부분적으로 확장된 표현식에 대한 구문 객체를 반환합니다. 확장 메커니즘의 한계 때문에 일부 컨텍스트 정보가 유실될 수 있습니다. 특히, 결과에 대해 expand-once를 호출하면 expand를 통한 확장과 다른 결과가 나올 수 있습니다.
top-level-form이 확장되기 전에, 그 어휘적 컨텍스트는 eval에서처럼 namespace-syntax-introduce로 강화됩니다.
insp 인자는 expand에서처럼 결과가 테인트될지 여부를 결정합니다.
base 패키지의 8.2.0.4 버전에서 변경됨: insp 인자와 테인팅이 추가되었습니다.
procedure
(expand-syntax-once stx [insp]) → syntax?
stx : syntax?
insp : inspector? = (current-code-inspector)
(expand-once stx)와 같지만, 인자가 구문 객체여야 하고, 확장 전에 어휘적 컨텍스트가 강화되지 않습니다.
base 패키지의 8.2.0.4 버전에서 변경됨: insp 인자와 테인팅이 추가되었습니다.
procedure
(expand-to-top-form top-level-form [insp]) → syntax?
top-level-form : any/c
insp : inspector? = (current-code-inspector)
top-level-form을 부분적으로 확장해서 가장 바깥쪽 구문 폼을 드러냅니다. 이 부분 확장은 주로 begin의 최상위 사용을 탐지하는 데 유용합니다. expand-once의 결과와 달리, expand-to-top-form의 결과를 expand로 확장하면 원래 구문에 expand를 사용한 것과 같은 결과가 나옵니다.
stx-or-sexpr이 확장되기 전에, 그 어휘적 컨텍스트는 eval에서처럼 namespace-syntax-introduce로 강화됩니다.
insp 인자는 expand에서처럼 결과가 테인트될지 여부를 결정합니다.
base 패키지의 8.2.0.4 버전에서 변경됨: insp 인자와 테인팅이 추가되었습니다.
procedure
(expand-syntax-to-top-form stx [insp]) → syntax?
stx : syntax?
insp : inspector? = (current-code-inspector)
(expand-to-top-form stx)와 같지만, 인자가 구문 객체여야 하고, 확장 전에 어휘적 컨텍스트가 강화되지 않습니다.
base 패키지의 8.2.0.4 버전에서 변경됨: insp 인자와 테인팅이 추가되었습니다.
확장된 모듈에 대한 정보 (Information on Expanded Modules)
확장된 모듈 선언에 대한 정보는 구문 객체에 붙는 일련의 구문 속성들("Syntax Object Properties" 참고)에 저장됩니다:
-
'module-body-context— 모듈의 내부에 해당하는 어휘 정보를 가진 구문 객체. 확장의 바깥쪽 가장자리 스코프(outside-edge scope)와 안쪽 가장자리 스코프(inside-edge scope)를 포함하므로, 이 구문 객체는 원래 모듈 본문에 존재하고 어떤 매크로의 조작에도 접근할 수 없는 식별자를 시뮬레이션합니다. 그래서 그 어휘 정보에는 모듈의 임포트와 정의에 대한 바인딩이 포함됩니다.base 패키지의 6.4.0.1 버전에서 추가됨.
-
'module-body-inside-context— 어휘 컨텍스트 없이 시작해서 매크로 안으로 이동된 식별자에 해당하는 어휘 정보를 가진 구문 객체. 그래서 확장의 안쪽 가장자리 스코프만 포함합니다.base 패키지의 6.4.0.1 버전에서 추가됨.
-
'module-body-context-simple?— 불리언.#t는 모듈 본문의 바인딩('module-body-inside-context속성 값의 어휘 정보에 기록된 것)이,for-syntax,for-meta,for-template으로 임포트된 것을 포함해 모듈에 직접 임포트된 모듈들로부터 직접 재구성될 수 있음을 나타냅니다.base 패키지의 6.4.0.1 버전에서 추가됨.
base 패키지의 7.0 버전에서 변경됨:
'module-variable-provides,'module-syntax-provides,'module-indirect-provides,'module-indirect-for-meta-provides속성이 제거되었습니다.
더 알아보기
- 구문 객체 (Syntax Objects) —
syntax->datum,datum->syntax - 이름공간 (Namespaces) —
namespace-syntax-introduce,make-base-namespace - 구문 객체 속성 (Syntax Object Properties)
- 완전히 확장된 프로그램 (Fully Expanded Programs)