추론된 링킹(Inferred Linking)

추론된 링킹(Inferred Linking)

compound-unit/infer는 유닛을 연결할 때 시그니처를 추론해서 compound-unit의 번거로운 선언을 줄여주는 형태예요. define-unit이 만든 정적 정보를 활용합니다.

출처: Racket Reference

본문

define-unit

syntax

(define-unit unit-id
  (import tagged-sig-spec ...)
  (export tagged-sig-spec ...)
  init-depends-decl
  unit-body-expr-or-defn ...)

unit-id를 유닛과 그 유닛에 대한 정적 정보 둘 다에 바인딩합니다.

define-unit이 바인딩한 unit-id에 대한 참조를 평가하면 유닛을 만들어냅니다. 이는 (define id (unit ...))로 바인딩된 id를 평가하는 것과 같습니다. 게다가 unit-idcompound-unit/infer에서 사용할 수 있습니다. tagged-sig-spec, init-depends-decl, unit-body-expr-or-defn에 대한 정보는 unit을 참고하세요.

compound-unit/infer

syntax

(compound-unit/infer
  (import tagged-infer-link-import ...)
  (export tagged-infer-link-export ...)
  (link infer-linkage-decl ...))

tagged-infer-link-import = tagged-sig-id
                          | (link-id : tagged-sig-id)
tagged-infer-link-export = (tag id infer-link-export)
                          | infer-link-export
infer-link-export = link-id
                  | sig-id
infer-linkage-decl = ((link-binding ...) unit-id tagged-link-id ...)
                   | unit-id

compound-unit과 같습니다. 문법적으로 compound-unitcompound-unit/infer의 차이는, 링크된 유닛의 unit-exprunit-id로 대체된다는 점입니다. 여기서 unit-iddefine-unit(또는 이 절에서 나중에 소개할 다른 유닛 바인딩 형태 중 하나)이 바인딩합니다. 게다가 import는 link-id를 지역적으로 바인딩하지 않고 sig-id만 이름 지을 수 있고, export는 link-id 대신 sig-id에 기반할 수 있으며, link 절의 선언은 지정된 export나 import 없이 단순히 unit-id일 수 있습니다.

compound-unit/infer 폼은 import 절에 필요한 대로 sig-id를 더하고, export 절의 sig-idlink-id로 대체하며, link 절의 선언을 완성함으로써 compound-unit으로 확장됩니다. 이 완성은 각 unit-id와 연관된 정적 정보에 기반합니다. 링크된 유닛들이 내보내는 모든 시그니처가 서로 그리고 모든 가져온 시그니처와 구별될 때, 그리고 모든 가져온 시그니처가 서로 구별될 때 링크와 export를 추론할 수 있습니다. 두 시그니처는 extends를 통해 공유하는 조상이 없을 때에만 구별됩니다.

링크 선언의 긴 형태는 유닛의 export 중 일부에 이름을 주고 유닛의 import 중 일부에 특정 바인딩을 제공함으로써 모호성을 해결하는 데 사용할 수 있습니다. 긴 형태가 나머지 부분을 추론할 수 있다면 유닛의 모든 export에 이름을 주거나 모든 import를 제공할 필요는 없습니다.

유닛이 초기화 의존성(initialization dependencies)을 선언하면, compound-unit/infer는 link 선언이 그 의존성과 일관적인지 확인하고, 그렇지 않으면 문법 오류를 보고합니다.

compound-unit과 마찬가지로 compound-unit/infer 폼은 결과 유닛의 import와 export에 대한 정적 정보를 바인딩하지 않고 (복합) 유닛을 만들어냅니다. 즉, compound-unit/infer는 정적 정보를 소비하지만 생성하지는 않습니다. 정적 정보를 생성하는 두 추가 형태인 define-compound-unitdefine-compound-unit/infer가 있습니다(전자는 정적 정보를 소비하지 않습니다).

package base의 6.1.1.8 버전에서 변경: 선언된 초기화 의존성과 관련한 link 절의 정적 검사가 추가되었습니다.

define-compound-unit

syntax

(define-compound-unit id
  (import link-binding ...)
  (export tagged-link-id ...)
  (link linkage-decl ...))

compound-unit과 같지만, define-unit처럼 복합 유닛에 대한 정적 정보를 바인딩합니다. 여기에는 링크된 유닛들로부터 (남은 import에 대한) 초기화-의존성 정보의 전파가 포함됩니다.

define-compound-unit/infer

syntax

(define-compound-unit/infer id
  (import link-binding ...)
  (export tagged-infer-link-export ...)
  (link infer-linkage-decl ...))

compound-unit/infer와 같지만, define-compound-unit처럼 복합 유닛에 대한 정적 정보를 바인딩합니다.

define-unit-binding

syntax

(define-unit-binding unit-id
  unit-expr
  (import tagged-sig-spec ...+)
  (export tagged-sig-spec ...+)
  init-depends-decl)

define-unit과 같지만, 유닛 구현이 unit-expr이 만들어내는 기존 유닛에서 결정됩니다. unit-expr이 만들어내는 유닛의 import와 export는 선언된 import와 export와 일관적이어야 하며, 그렇지 않으면 define-unit-binding 폼이 평가될 때 exn:fail:contract 예외가 발생합니다.

invoke-unit/infer

syntax

(invoke-unit/infer unit-spec)

unit-spec = unit-id
          | (link link-unit-id ...)

invoke-unit과 같지만, unit-id와 연관된 정적 정보를 사용해 현재 문맥에서 어떤 import를 조립해야 하는지 추론합니다. 여러 link-unit-id를 가진 link 폼이 주어지면, 유닛들은 먼저 define-compound-unit/infer를 통해 링크됩니다.

현재 문맥에서 import를 조립할 때, 유닛의 import에 대한 시그니처의 어휘 정보(즉 보통 시그니처 참조에서 파생되는 어휘 정보)를 구성하는 데 unit-id의 어휘 정보가 사용됩니다. 자세한 내용은 define-signature를 참고하세요.

define-values/invoke-unit/infer

syntax

(define-values/invoke-unit/infer unit-spec maybe-exports maybe-results-clause)

(define-values/invoke-unit/infer (export tagged-sig-spec ...) unit-spec)

unit-spec = unit-id
          | (link link-unit-id ...)
maybe-exports =
  | (export tagged-sig-spec ...)
maybe-results-clause =
  | (values result-id ...)
  | (values result-id ... . rest-results-id)

define-values/invoke-unit과 같지만, unit-id와 연관된 정적 정보를 사용해 현재 문맥에서 어떤 import를 조립해야 하는지, 그리고 export 절이 없으면 정의가 어떤 export를 바인딩해야 하는지 추론합니다. 여러 link-unit-id를 가진 link 폼이 주어지면, 유닛들은 먼저 define-compound-unit/infer를 통해 링크됩니다.

invoke-unit/infer와 유사하게, 유닛의 추론된 import와 추론된 export의 시그니처에 대한 어휘 정보를 구성하는 데 unit-id의 어휘 정보가 사용됩니다(즉 보통 시그니처 참조에서 파생되는 어휘 정보). 자세한 내용은 define-signature를 참고하세요.

maybe-results-clause가 제공되면 유닛 본문이 반환하는 값들은 define-values/invoke-unit과 같은 방식으로 바인딩됩니다.

역호환성을 위해 export 절이 unit-spec보다 앞에 나타날 수 있습니다(이 경우 maybe-results-clause는 제공될 수 없습니다). 새 프로그램은 unit-spec을 먼저 제공해야 합니다(define-values/invoke-unit과 일관적입니다).

package base의 8.8.0.7 버전에서 변경: define-values/invoke-unit과의 일관성을 위해 unit-specmaybe-exports보다 앞에 나타날 수 있게 하고 maybe-results-clause를 추가했습니다.

더 알아보기