구조체 타입 트랜스포머 바인딩
구조체 타입 트랜스포머 바인딩 (Structure Type Transformer Binding)
struct 폼은 구조체 타입의 이름을 트랜스포머 바인딩으로 바인딩해, 구조체 타입에 바인딩된 다른 식별자들(생성자, 술어, 필드 접근자/변이자)을 기록합니다. 이 정보는 syntax-local-value를 통해 다른 표현식의 전개 중에 사용될 수 있습니다.
출처: Racket Reference
본문
struct 폼은 구조체 타입의 이름을 트랜스포머 바인딩으로 바인딩하는데, 이 바인딩은 구조체 타입에 바인딩된 다른 식별자들(생성자 절차, 술어 절차, 필드 접근자와 변이자 절차)을 기록합니다. 이 정보는 syntax-local-value를 통해 다른 표현식의 전개 중에 사용될 수 있습니다.
예를 들어, 하위 타입을 위한 struct 변형은 기본 타입 이름 t를 사용해 기본 타입의 디스크립터를 담은 변수 struct:t를 찾습니다. 또한 기본 타입의 필드 접근자와 변이자 정보를 하위 타입의 정보에 접습니다(fold). 또 다른 예로, match 폼은 타입 이름을 사용해 구조체 타입의 술어와 필드 접근자를 찾습니다. 유닛(unit)을 위한 가져온 시그니처(signature) 안의 struct 폼은 유닛 트랜스포머가 가져온 구조체 타입에 대한 정보를 생성하게 하여, match와 하위 타입 struct 폼이 유닛 안에서 작동하게 합니다.
구조체 타입의 전개-시간 정보는 여섯 요소로 이루어진 리스트로 직접 표현될 수 있습니다(캡슐화된 절차가 반환해야 하는 것과 같은 종류):
- 구조체 타입의 디스크립터에 바인딩된 식별자, 또는 알려진 것이 없으면
#f; - 구조체 타입의 생성자에 바인딩된 식별자, 또는 알려진 것이 없으면
#f; - 구조체 타입의 술어에 바인딩된 식별자, 또는 알려진 것이 없으면
#f; - 구조체 타입의 필드 접근자에 바인딩된 식별자들의 리스트. 선택적으로 리스트의 마지막 요소로
#f를 가질 수 있음. 마지막 요소로#f가 있으면 구조체 타입이 추가 필드를 가질 수 있음을 나타내고, 그렇지 않으면 리스트가 구조체 타입의 필드 수에 대한 신뢰할 수 있는 지표입니다. 게다가 접근자들은 대응하는 생성자 인자들에 대해 역순으로 나열됩니다(역순은 하위 타입과 그 기본 타입의 리스트에서 공유를 가능하게 합니다). - 구조체 타입의 필드 변이자에 바인딩된 식별자들의 리스트. 알려진 변이자가 없는 각 필드에 대해
#f이며, 선택적으로 (접근자 리스트가 그런#f를 갖는다면) 리스트의 마지막 요소로 추가#f를 가질 수 있음. 리스트의 순서와 끝의#f의 의미는 접근자 식별자와 같고, 변이자 리스트의 길이는 접근자 리스트의 길이와 같습니다. - 구조체 타입에 대한 상위 타입을 결정하는 식별자, 상위 타입(있다면)이 알려지지 않으면
#f, 상위 타입이 없으면#t. 상위 타입이 지정되면 그 식별자도 구조체 타입 전개-시간 정보에 바인딩됩니다.
이 직접 표현 대신, 그 표현은 make-struct-info가 만든 구조체(또는 struct:struct-info의 하위 타입 인스턴스)일 수 있는데, 이것은 인자를 받지 않고 여섯 요소 리스트를 반환하는 절차를 캡슐화합니다. 또는 그 표현은 prop:struct-info 구조체 타입 속성을 가진 타입의 구조체일 수 있습니다. 마지막으로, 그 표현은 struct:struct-info에서 파생되었거나 prop:struct-info 속성을 가지면서 prop:procedure도 구현하는 구조체 타입의 인스턴스일 수 있으며, 그 인스턴스는 make-set!-transformer로 더 감싸집니다. 게다가 그 표현은 prop:struct-auto-info와 prop:struct-field-info 속성을 구현할 수 있습니다.
struct-info?를 사용해 정보의 허용된 모든 형태를 인식하고, extract-struct-info를 사용해 어떤 표현에서든 리스트를 얻으세요.
구문 폼의 구현자는 폼의 사용자가 구조체 타입에 대해 어떤 종류의 정보가 사용 가능한지 알 것이라고 기대할 수 있습니다. 예를 들어 match 구현은 불완전한 접근자 바인딩 집합을 포함하는 구조체 정보로 작동합니다. 사용자가 match 표현식의 맥락에서 어떤 정보를 사용할 수 있는지 알고 있다고 가정하기 때문입니다. 특히, match 표현식은 가져온 구조체 타입을 가진 유닛 폼에 나타날 수 있고, 이 경우 사용자는 구조체 타입의 시그니처에 나열된 필드 집합을 알고 있을 것으로 기대됩니다.
(require racket/struct-info) ; package: base
이 섹션에 문서화된 바인딩은 racket/struct-info 라이브러리가 제공하며, racket/base나 racket은 제공하지 않습니다.
procedure
(struct-info? v) → boolean?
v : any/c
v가 구조체 타입 정보를 나타내는 올바른 형태의 여섯 요소 리스트이거나, make-struct-info가 캡슐화한 절차이거나, prop:struct-info 속성을 가진 구조체이거나, struct:struct-info에서 파생되었거나 prop:struct-info를 가지면서 make-set!-transformer로 감싸진 구조체 타입이면 #t를 반환합니다.
procedure
(checked-struct-info? v) → boolean?
v : any/c
v가 make-struct-info가 캡슐화하고 struct가 생산한 절차인데, 부모 타입이 지정되지 않았거나 부모 타입도 그런 값에 대한 트랜스포머 바인딩을 통해 지정된 경우에만 #t를 반환합니다.
procedure
(make-struct-info thunk) → struct-info?
thunk : (-> (and/c struct-info? list?))
리스트 형태의 구조체 타입 정보를 반환하는 썽크(thunk)를 캡슐화합니다. Structure Type Transformer Binding에서 언급했듯이 접근자들이 역순으로 나열된다는 점에 주의하세요. 이 방법으로 만든 struct-type info에 대해서는 필드 이름이 잘 정의되어 있지 않으므로, struct-copy나 struct* 같은 폼과는 잘 작동하지 않을 가능성이 높습니다.
예시:
> (define (new-pair? x) (displayln "new pair?") (pair? x))
> (define (new-car x) (displayln "new car") (car x))
> (define (new-cdr x) (displayln "new cdr") (cdr x))
> (define-syntax new-list
(make-struct-info
(λ () (list #f
#'cons
#'new-pair?
(list #'new-cdr #'new-car)
(list #f #f)
#t))))
> (match (list 1 2 3)
[(new-list hd tl) (append tl (list hd))])
new pair?
new car
new cdr
'(2 3 1)
예시:
> (struct A (x y))
> (define (new-A-x a) (displayln "A-x") (A-x a))
> (define (new-A-y a) (displayln "A-y") (A-y a))
> (define (new-A? a) (displayln "A?") (A? a))
> (define-syntax A-info
(make-struct-info
(λ () (list #'A
#'A
#'new-A?
(list #'new-A-y #'new-A-x)
(list #f #f)
#t))))
> (define-match-expander B
(syntax-rules () [(_ x ...) (A-info x ...)]))
> (match (A 10 20)
[(B x y) (list y x)])
A?
A-x
A-y
'(20 10)
procedure
(extract-struct-info v) → (and/c struct-info? list?)
v : struct-info?
v가 나타내는 구조체 타입 정보의 리스트 형태를 추출합니다.
value
struct:struct-info : struct-type?
make-struct-info가 반환하는 구조체 타입에 대한 구조체 타입 디스크립터입니다. 이 구조체 타입 디스크립터는 구조체 하위 타입을 만드는 데 주로 유용합니다. 이 구조체 타입은 make-struct-info와 같은 방식으로 인스턴스의 첫 번째 필드를 검사하는 가드(guard)를 포함합니다.
value
prop:struct-info : struct-type-property?
struct:struct-info 같은 새 구조체 타입을 만드는 데 사용하는 구조체 타입 속성입니다. 속성 값은 인스턴스 구조체를 받아 리스트 형태의 구조체 타입 정보를 반환하는 인자 하나짜리 절차여야 합니다.
value
prop:struct-auto-info : struct-type-property?
procedure
(struct-auto-info? v) → boolean?
v : any/c
procedure
(struct-auto-info-lists sai)
→ (list/c (listof identifier?) (listof identifier?))
sai : struct-auto-info?
prop:struct-auto-info 속성은 구조체 타입의 접근자와 변이자 식별자 중 어느 것이 #:auto 필드에 해당하는지(그래서 생성자에 대응하는 인자가 없는지)에 대한 정적 정보를 제공하도록 구현됩니다. 속성 값은 속성이 주어진 인스턴스 구조체를 받는 절차여야 하며, 결과는 struct-auto-info-lists의 결과로 적합한 두 개의 식별자 리스트여야 합니다.
struct-auto-info? 술어는 prop:struct-auto-info 속성을 구현하는 값을 인식합니다.
struct-auto-info-lists 함수는 prop:struct-auto-info 속성을 구현하는 값에서 두 개의 식별자 리스트를 추출합니다. 첫 번째 리스트는 sai가 설명하는 구조체 타입의 접근자 식별자들의 부분 집합이어야 하고, 두 번째 리스트는 변이자 식별자들의 부분 집합이어야 합니다. 두 부분 집합은 #:auto 필드에 해당합니다.
value
prop:struct-field-info : struct-type-property?
procedure
(struct-field-info? v) → boolean?
v : any/c
procedure
(struct-field-info-list sfi) → (listof symbol?)
sfi : struct-field-info?
prop:struct-field-info 속성은 구조체 타입의 필드 이름에 대한 정적 정보를 제공하도록 구현됩니다. 속성 값은 속성이 주어진 인스턴스 구조체를 받는 절차여야 하며, 결과는 struct-field-info-list의 결과로 적합한 기호 리스트여야 합니다.
struct-field-info? 술어는 prop:struct-field-info 속성을 구현하는 값을 인식합니다.
struct-field-info-list 함수는 prop:struct-field-info 속성을 구현하는 값에서 기호 리스트를 추출합니다. 리스트는 상위 struct 타입의 필드를 포함하지 않는 모든 즉시(immediate) 필드 이름을 역순으로 포함해야 합니다.
예시:
> (struct foo (x))
> (struct bar foo (y z))
> (define-syntax (get-bar-field-names stx)
#`'#,(struct-field-info-list (syntax-local-value #'bar)))
> (get-bar-field-names)
'(z y)
base 패키지의 7.7.0.9 버전에서 추가되었습니다.
더 알아보기
struct구조체 타입 정의 폼과 구조체 타입 속성syntax-local-value,make-set!-transformer관련 문서match폼과 유닛(unit)의 시그니처 관련 내용