스플라이싱 본문과 함께하는 지역 바인딩
스플라이싱 본문과 함께하는 지역 바인딩 (Local Binding with Splicing Body)
splicing-let 계열 폼들은 let 계열 폼들과 비슷하지만, 정의 맥락에서는 본문 폼들이 바깥쪽 정의 맥락으로 스플라이스(splice)됩니다. 바인딩 폼이 최상위나 모듈 맥락에서 나타날 때 지역 바인딩이 정의처럼 취급됩니다.
출처: Racket Reference
본문
(require racket/splicing) ; package: base
이 섹션에 문서화된 바인딩은 racket/splicing 라이브러리가 제공하며, racket/base나 racket은 제공하지 않습니다.
syntax
splicing-let
syntax
splicing-letrec
syntax
splicing-let-values
syntax
splicing-letrec-values
syntax
splicing-let-syntax
syntax
splicing-letrec-syntax
syntax
splicing-let-syntaxes
syntax
splicing-letrec-syntaxes
syntax
splicing-letrec-syntaxes+values
syntax
splicing-local
syntax
splicing-parameterize
let(named let는 아님), letrec, let-values, letrec-values, let-syntax, letrec-syntax, let-syntaxes, letrec-syntaxes, letrec-syntaxes+values, local, parameterize와 같습니다. 다만 정의 맥락에서 본문 폼들이 바깥쪽 정의 맥락으로 스플라이스된다는 점이 다릅니다(begin과 같은 방식으로).
예시:
> (splicing-let-syntax ([one (lambda (stx) #'1)])
(define o one))
> o
1
> one
one: undefined;
cannot reference an identifier before its definition
in module: top-level
스플라이싱 바인딩 폼이 최상위 맥락이나 모듈 맥락에서 나타나면, 그 지역 바인딩은 정의처럼 취급됩니다. 특히 구문 바인딩은 let-syntax 등에서처럼 컴파일 동안 단 한 번만 평가되는 대신, 모듈이 방문될 때마다 평가됩니다.
예시:
> (splicing-letrec ([x bad]
[bad 1])
x)
bad.1: undefined;
cannot reference an identifier before its definition
in module: top-level
스플라이싱 폼 안의 정의가 스플라이싱 본문에 지역적이도록 의도된 경우, 그 식별자는 'definition-intended-as-local 구문 속성에 대해 참(true) 값을 가져야 합니다. 예를 들어 splicing-let 자체는 일련의 정의들로 전개되면서 지역적으로 바인딩된 식별자들에 이 속성을 추가하므로, 스플라이싱 폼 안에 splicing-let을 중첩하는 것이 (모호한 바인딩 없이) 예상대로 작동합니다.
base 패키지의 6.12.0.2 버전에서 변경됨: splicing-parameterize 추가.
syntax
splicing-syntax-parameterize
syntax-parameterize와 같지만, 정의 맥락에서 본문 폼들이 바깥쪽 정의 맥락으로 스플라이스된다는 점이 다릅니다(begin과 같은 방식으로). 정의 맥락에서 splicing-syntax-parameterize의 본문은 비어 있을 수 있습니다.
require 트랜스포머와 provide 트랜스포머는 구문 매개변수화(syntax parameterization)의 영향을 받지 않는다는 점에 주의하세요. 모든 require와 provide의 사용은 바깥쪽 맥락으로 스플라이스되지만, 파생된 import/export 명세는 마치 splicing-syntax-parameterize 안에 있지 않았던 것처럼 전개됩니다.
추가로, 모듈 경로 대신 #f를 지정한 module*로 정의된 하위 모듈은 구문 매개변수화의 영향을 받지만, 다른 하위 모듈(모듈 경로가 있는 module이나 module*로 정의된 것들)은 받지 않습니다.
예시:
> (define-syntax-parameter place (lambda (stx) #'"Kansas"))
> (define-syntax-rule (where) `(at ,(place)))
> (where)
'(at "Kansas")
> (splicing-syntax-parameterize ([place (lambda (stx) #'"Oz")])
(define here (where)))
> here
'(at "Oz")
base 패키지의 6.11.0.1 버전에서 변경됨: 모듈 경로 대신 #f를 지정하는 module* 하위 모듈을 구문 매개변수화하도록 수정됨.
더 알아보기
let,letrec,let-values,parameterize,local계열 구문 폼syntax-parameterize관련 문서begin의 스플라이싱 동작