R6RS Scheme: 매크로
R6RS Scheme: 매크로
라이브러리와 최상위 프로그램이 새로운 종류의 파생 표현식과 정의를 만들고 사용하는 매크로(macro)를 설명해요.
출처: 문서
본문
라이브러리와 최상위 프로그램은 문법 추상화(syntactic abstraction) 또는 매크로(macro) 라고 불리는 새로운 종류의 파생 표현식과 정의를 정의하고 사용할 수 있어요. 문법 추상화는 키워드를 매크로 변환기(macro transformer) 또는 간단히 변환기(transformer) 에 바인딩함으로써 만들어져요. 변환기는 매크로의 사용(매크로 사용(macro use)이라 부름)이 어떻게 더 원시적인 형태로 전사(transcribe)되는지를 결정해요.
대부분의 매크로 사용은 다음과 같은 형태를 가져요:
(<keyword> <datum> ...)
여기서 <keyword>는 그 형식의 종류를 유일하게 결정하는 식별자예요. 이 식별자를 매크로의 문법 키워드(syntactic keyword) 또는 간단히 키워드(keyword) 라고 불러요. <datum>의 개수와 각각의 문법은 문법 추상화에 따라 달라져요.
매크로 사용은 부정규 리스트(improper list), 단일 식별자, 또는 set! 형식의 형태를 가질 수도 있는데, 이 경우 set!의 두 번째 부분 형식이 키워드가 돼요(11.19절의 make-variable-transformer 라이브러리 절 참조):
(<keyword> <datum> ... . <datum>)
<keyword>
(set! <keyword> <datum>)
11.2.2절과 11.18절에서 설명하는 define-syntax, let-syntax, letrec-syntax 형식은 키워드를 위한 바인딩을 만들고, 그것들을 매크로 변환기와 연결하며, 그것들이 보이는 범위(scope)를 제어해요.
11.19절에서 설명하는 syntax-rules와 identifier-syntax 형식은 패턴 언어를 통해 변환기를 만들어요. 또한 syntax-case 라이브러리 절에서 설명하는 syntax-case 형식은 임의의 Scheme 코드를 통해 변환기를 만들 수 있게 해요.
키워드는 변수와 같은 이름 공간을 차지해요. 즉, 같은 범위 안에서 식별자는 변수나 키워드 중 하나로 바인딩되거나, 둘 다로는 바인딩되지 않아요 — 그러나 둘 다로는 바인딩될 수 없고, 어느 쪽이든 지역 바인딩은 다른 쪽의 어떤 바인딩도 가릴(shadow) 수 있어요.
syntax-rules와 identifier-syntax로 정의된 매크로는 "위생적(hygienic)"이고 "참조적으로 투명(referentially transparent)"해서 Scheme의 어휘적 유효범위를 보존해요 [16, 15, 2, 6, 9]:
- 매크로 변환기가 매크로 사용에 나타나지 않는 식별자(변수 또는 키워드)에 대한 바인딩을 삽입하면, 그 식별자는 다른 식별자와의 충돌을 피하기 위해 그 유효범위 전체에서 사실상 이름이 바뀌어요.
- 매크로 변환기가 식별자에 대한 자유 참조(free reference)를 삽입하면, 그 참조는 변환기가 명시된 곳에서 보였던 바인딩을 가리켜요. 매크로 사용 주변을 둘러싸는 지역 바인딩과는 무관해요.
syntax-case 도구를 사용해 정의된 매크로 역시 위생적이지만, 그렇지 않은 경우는 datum->syntax(문법 객체와 datum 변환에 관한 라이브러리 절 참조)를 사용할 때예요.
더 알아보기 (Learn more)
출처: Macros - R6RS