링클릿과 핵심 컴파일러
링클릿과 핵심 컴파일러 (Linklets and the Core Compiler)
*링클릿(linklet)*은 컴파일·바이트코드 마샬링·평가의 원시 요소예요. Racket의 모듈·매크로·최상위 평가 구현이 모두 링클릿 위에 구축되어 있습니다. 일반적인 Racket 프로그래머는 링클릿을 직접 만나지 않지만, racket/linklet 라이브러리가 링클릿 기능에 접근할 수 있게 해 줍니다.
본문
( require racket/linklet ) — 패키지: base
*링클릿(linklet)*은 컴파일, 바이트코드 마샬링, 평가의 원시 요소예요. Racket의 모듈·매크로·최상위 평가 구현이 모두 링클릿 위에 세워져 있습니다. Racket 프로그래머는 일반적으로 링클릿을 직접 만나지 않지만, racket/linklet 라이브러리가 링클릿 기능에 접근할 수 있게 해 줍니다.
단일 Racket 모듈(또는 최상위 형식의 모음)은 전형적으로 여러 링클릿으로 구현됩니다. 예를 들어 모듈에 존재하는 각 평가 페이즈는 별도의 링클릿으로 구현돼요. 모듈의 require에 대한 모듈 경로 인덱스 같은 메타데이터에도 링클릿이 쓰입니다. 이 링클릿들과 몇 가지 다른 메타데이터가 결합되어 *링클릿 번들(linklet bundle)*을 이룹니다. 링클릿 번들의 정보는 심볼이나 fixnum으로 키가 정해져요. 링클릿을 담는 링클릿 번들은 write와(read-accept-compiled가 활성화되어 있을 때)read로 바이트 스트림으로 마샬링하거나 그로부터 복원할 수 있습니다. compiled-expression?의 의미로 컴파일된 형태(compile의 결과 같은 것)는 링클릿 번들일 수 있어요.
Racket 모듈이 서브모듈을 가지면, 그 모듈과 서브모듈의 링클릿 번들이 함께 *링클릿 디렉토리(linklet directory)*로 묶입니다. 링클릿 디렉토리는 중첩 링클릿 디렉토리를 가질 수 있어요. 링클릿 디렉토리의 정보는 #f나 심볼로 키가 정해지는데, #f는(무엇이든 있으면) 링클릿 번들로 매핑되어야 하고 각 심볼은 링클릿 디렉토리로 매핑되어야 합니다. 링클릿 디렉토리는 심볼 리스트에서 링클릿 번들로 가는 매핑으로 동등하게 볼 수도 있어요. 링클릿 번들처럼 링클릿 디렉토리도 write와 read로 바이트 스트림으로 마샬링하거나 그로부터 복원할 수 있어요. 마샬링된 형태는 개별 링클릿 번들을 독립적으로 로드할 수 있게 해 줍니다. compiled-expression?의 의미로 컴파일된 형태(compile의 결과 같은 것)는 링클릿 디렉토리일 수 있습니다.
링클릿은 변수 정의와 표현식의 집합, 정의된 변수 이름의 내보낸 부분집합, 대응되는 정의가 없음에도 링클릿에서 내보낼 변수 집합, 그리고 링클릿이 사용할 다른 변수를 제공하는 import 집합으로 구성됩니다. 링클릿을 실행하려면 링클릿 인스턴스(linklet instance)(줄여서 그냥 인스턴스)로 인스턴스화합니다. 링클릿이 인스턴스화되면 자신의 import에 대해 다른 링클릿 인스턴스들을 받고, 주어진 각 인스턴스에서 내보낸 명시된 변수 집합을 추출해요. 새로 만들어진 링클릿 인스턴스는 자신의 내보낸 변수를 다른 링클릿이 사용하거나 instance-variable-value로 직접 접근할 수 있게 제공합니다. 링클릿 인스턴스는 make-instance로 직접 합성할 수도 있어요.
링클릿은 그 소스의 풍부한 S-표현 표현을 컴파일해서 만들어집니다. 링클릿은 매크로와 문법 객체 층 아래에 존재하므로, 링클릿 컴파일은 문법 객체를 사용하지 않아요. 대신 링클릿 컴파일은 *상관 객체(correlated object)*를 사용하는데, 이는 렉시컬 맥락 정보가 없고 내용이 상관 객체로 강제 변환된다는 제약도 없는 문법 객체와 같습니다. S-표현이나 상관 객체를 사용할 때, compile-linklet이 인식하는 링클릿의 문법은 다음과 같아요:
(linklet [[imported-id/renamed ...] ...]
[exported-id/renamed ...]
defn-or-expr ...)
imported-id/renamed = imported-id
| (external-imported-id internal-imported-id)
exported-id/renamed = exported-id
| (internal-exported-id external-exported-id)
각 import 집합 [imported-id/renamed ...]은 단일 import 인스턴스를 가리키고, 각 import-id/renamed는 그 인스턴스의 변수에 대응합니다. 별도의 external-imported-id와 internal-imported-id를 지정하면, external-imported-id는 인스턴스가 내보내는 변수의 이름이고 internal-imported-id는 defn-or-expr들에서 그 변수를 가리키는 데 쓰는 이름이에요. 내보내기의 경우 별도의 internal-exported-id와 external-exported-id 이름은 각각 defn-or-expr들에서 참조되는 변수 이름과 내보내는 변수 이름에 대응합니다.
defn-or-expr의 문법은 확장기의 완전 확장 표현식 문법(완전 확장 프로그램 참조)과 비슷하지만 몇 가지 예외가 있어요. quote-syntax와 #%top은 허용되지 않고, #%plain-lambda는 lambda로 쓰이며, #%plain-app은 생략되고(즉 적용이 암묵적), lambda, case-lambda, let-values, letrec-values는 단일 본문 표현식만 가질 수 있고, begin-unsafe는 표현식 위치의 begin과 같지만 그 본문이 안전하지 않은 모드로 컴파일되며, #%foreign-inline은 자기 모드에 키워드 대신 심볼을 쓰고, 숫자·불리언·문자열·바이트 문자열은 자기 인용(self-quoting)입니다. 원시(primitive)는 이름으로 직접 접근하며, linklet 형식 안에서 원시 이름(linklet-body-reserved-symbol? 참조), import 변수, 정의 변수, 지역 변수에 대한 셰도잉은 허용되지 않습니다.
exported-id/renamed가 defn-or-expr들 사이에 대응하는 정의가 없으면, 그 변수는 사실상 초기화되지 않은 것으로 정의돼요. 그 변수를 참조하면 정의되기 전에 변수를 참조하는 것처럼 exn:fail:contract:variable이 촉발됩니다. instantiate-linklet에 대상 인스턴스가 제공되면, 같은 이름의 기존 변수가 미정의로 설정되는 대신 그대로 남습니다. 이렇게 초기화되지 않은 변수를 처리하는 방식은 변수가 참조된 다음 컴파일의 별도 요소에서 정의될 수 있는 최상위 평가에 핵심적인 지원을 제공해요.
버전 6.90.0.1 (패키지 base)에서 추가됨.
프로시저
(linklet? v) → boolean?
v : any/c
v가 링클릿이면 #t, 그렇지 않으면 #f를 반환해요.
프로시저
(compile-linklet form [info import-keys get-import options]) → linklet?
form : (or/c correlated? any/c)
info : (or/c hash? any/c) = #f
import-keys : #f = #f
get-import : #f = #f
options : (listof (or/c 'serializable 'unsafe 'static 'quick 'use-prompt 'unlimited-compile 'uninterned-literal)) = '(serializable)
(compile-linklet form info import-keys [get-import options]) → (values linklet? vector?)
form : (or/c correlated? any/c)
info : (or/c hash? any/c)
import-keys : vector?
get-import : (or/c #f (any/c . -> . (values (or/c linklet? instance? #f) (or/c vector? #f)))) = #f
options : (listof (or/c 'serializable 'unsafe 'static 'quick 'use-prompt 'unlimited-compile 'uninterned-literal)) = '(serializable)
linklet 형식의 S-표현 또는 상관 객체를 받아 링클릿을 만들어 내요. options에 'serializable이 포함되어 있는 한, 결과 링클릿은 링클릿 번들(가능하면 링클릿 디렉토리 안)의 일부일 때 바이트 스트림으로 마샬링하거나 그로부터 복원할 수 있습니다.
선택적 info 해시는 링클릿에 대한 다양한 디버깅 세부사항을 제공하는데, 예를 들어 링클릿이 속한 모듈 이름, 링클릿 이름, 본문 링클릿의 페이즈 같은 것이에요. 해시에 'name 값이 있으면 디버깅 목적으로 링클릿에 연관되고 링클릿 인스턴스의 기본 이름이 됩니다. info가 해시가 아니면, 이전 버전 호환을 위해 그 자체가 이름 값이라고 가정합니다.
선택적 import-keys와 get-import 인자는 교차 링클릿 최적화를 지원합니다. import-keys가 벡터이면 form의 import 집합 수만큼 요소를 가져야 해요. 컴파일러가 import 변수에 대한 참조를 최적화하는 데 관심을 가지게 되면, get-import(#f가 아닐 때)에 그 변수의 import 집합에 대응하는 import-keys 요소를 돌려줍니다. get-import 함수는 그런 다음 최종적으로 인스턴스화될 때 컴파일된 링클릿에 제공될 인스턴스를 나타내는 링클릿이나 인스턴스를 반환할 수 있어요. 보고된 링클릿/인스턴스와 최종 인스턴스 사이의 일관성을 보장하는 것은 compile-linklet 호출자의 몫이지만, linklet-add-target-machine-info도 함께 보세요. get-import가 첫 번째 값으로 #f를 반환하면, 컴파일러는 import 인스턴스에 대해 어떤 가정도 하지 못하게 됩니다. get-import의 두 번째 결과는 반환된 링클릿의 import에 대한 전이적 정보를 제공하는 선택적 키 벡터입니다(반환된 인스턴스에는 허용되지 않아요). 반환된 벡터는 링클릿이 가진 import 수와 같은 수의 요소를 가져야 해요. 벡터 요소가 eq?이고 #f가 아니면, 컴파일러는 그것들이 같은 런타임 인스턴스에 대응한다고 가정할 수 있습니다. get-import에 #f 값은 항상 두 #f 결과를 반환하는 함수와 동등해요.
import-keys가 #f가 아니면, 컴파일러는 링클릿의 import 인스턴스 집합을 늘리거나 줄일 수 있습니다. 결과 벡터는 반환된 링클릿의 import 키를 명시해요. 다만 #f이거나 링클릿 인스턴스인 어떤 키든 온전히 보존되어야 합니다.
options에 'unsafe가 포함되면 링클릿이 *안전하지 않은 모드(unsafe mode)*로 컴파일됩니다. 링클릿 안의 안전한 연산 사용은 관련 계약이 충족된다는 가정 하에 안전하지 않은 연산으로 변환될 수 있어요. 예를 들어 car는 unsafe-car로 변환됩니다. 일부 치환된 안전하지 않은 연산은 직접 접근 가능한 이름이 없을 수 있는데, 안전하지 않은 모드에서 치환될 수 있는 in-list의 안전하지 않은 변형이 그 예예요. 안전하지 않은 연산은 (검사되지 않은) 계약이 안전한 연산의 계약에 포함될 때만 치환됩니다. 링클릿이 안전하지 않은 모드로 컴파일되었다는 사실은 모듈 본문 안의 #%variable-reference 형식이 만든 변수 참조를 사용해 variable-reference-from-unsafe?로 드러낼 수 있어요. 링클릿 안에서 개별 표현식은 begin-unsafe로 감싸 안전하지 않은 모드로 컴파일할 수 있습니다. 링클릿 전체가 안전하지 않은 모드로 컴파일되면 begin-unsafe는 중복이라 무시됩니다.
options에 'static이 포함되면 링클릿은 한 번만 인스턴스화되어야 해요. 링클릿이 직렬화되면 직렬화된 형태에서 읽은 어떤 개별 인스턴스도 최대 한 번 인스턴스화되어야 합니다. 'static으로 컴파일하는 것은 링클릿 안의 정의된·import 변수에 대한 참조의 성능을 개선하기 위한 것입니다.
options에 'quick이 포함되면 링클릿 컴파일이 런타임 성능을 컴파일 타임 성능으로 맞바꿀 수 있어요. 즉 링클릿을 컴파일하는 시간을 덜 쓰지만, 결과 링클릿이 더 느리게 실행될 수 있습니다.
options에 'use-prompt가 포함되면 결과 링클릿을 인스턴스화할 때 항상 링클릿의 각 정의와 즉시(immediate) 표현식 주위에 프롬프트를 감쌉니다. 그렇지 않으면 instantiate-linklet에 use-prompt? 인자로 #t를 주는 것은 인스턴스화 전체에만 프롬프트를 감쌀 수 있습니다.
options에 'unlimited-compile이 포함되면 특히 큰 링클릿에 대해 컴파일이 해석 모드로 폴백하지 않습니다. CS Compilation Modes도 함께 보세요.
options에 'uninterned-literal이 포함되면 form의 리터럴이 링클릿을 컴파일하거나 로드할 때 반드시 datum-intern-literal로 인턴되는 것은 아닙니다. datum-intern-literal 사용을 끄는 것은 링클릿이 공유되지 않을 큰 문자열이나 바이트 문자열 상수를 포함할 때 특히 유용할 수 있어요.
options의 심볼들은 서로 구별되어야 하며, 그렇지 않으면 exn:fail:contract 예외가 발생합니다.
버전 7.1.0.8 (패키지 base)에서 변경: 'use-prompt 옵션 추가됨.
버전 7.1.0.10에서 변경: 'uninterned-literal 옵션 추가됨.
버전 7.5.0.14에서 변경: 'quick 옵션 추가됨.
버전 8.11.1.2에서 변경: info가 해시로 변경됨.
버전 8.13.0.9에서 변경: 'unlimited-compile 옵션 추가됨.
프로시저
(recompile-linklet linklet [info import-keys get-import options]) → linklet?
linklet : linklet?
info : (or/c hash? any/c) = #f
import-keys : #f = #f
get-import : #f = #f
options : (listof (or/c 'serializable 'unsafe 'static 'quick 'use-prompt 'uninterned-literal)) = '(serializable)
(recompile-linklet linklet info import-keys [get-import options]) → (values linklet? vector?)
linklet : linklet?
info : (or/c hash? any/c)
import-keys : vector?
get-import : (or/c (any/c . -> . (values (or/c linklet? #f) (or/c vector? #f))) #f) = (lambda (import-key) (values #f #f))
options : (listof (or/c 'serializable 'unsafe 'static 'quick 'use-prompt 'uninterned-literal)) = '(serializable)
compile-linklet과 같지만, 이미 컴파일된 링클릿을 받아 잠재적으로 더 최적화해요.
버전 7.1.0.6 (패키지 base)에서 변경: options 인자 추가됨.
버전 7.1.0.8에서 변경: 'use-prompt 옵션 추가됨.
버전 7.1.0.10에서 변경: 'uninterned-literal 옵션 추가됨.
버전 7.5.0.14에서 변경: 'quick 옵션 추가됨.
버전 8.11.1.2에서 변경: info가 해시로 변경됨.
프로시저
(eval-linklet linklet) → linklet?
linklet : linklet?
JIT 컴파일을 위해 준비된 linklet의 변형을 반환하는데, 결과 링클릿을 instantiate-linklet로 나중에 사용할 때마다 JIT 생성 코드를 공유하게 됩니다. 다만 eval-linklet의 결과는 링클릿 번들의 일부로 바이트 스트림에 마샬링될 수 없고, recompile-linklet과 함께 쓸 수도 없어요.
프로시저
(instantiate-linklet linklet import-instances [target-instance? use-prompt?]) → instance?
linklet : linklet?
import-instances : (listof instance?)
target-instance? : #f = #f
use-prompt? : any/c = #t
(instantiate-linklet linklet import-instances target-instance [use-prompt?]) → any
linklet : linklet?
import-instances : (listof instance?)
target-instance : instance?
use-prompt? : any/c = #t
주어진 import-instances를 자신의 import로 사용해, 정의와 표현식을 실행함으로써 linklet을 인스턴스화해요. import-instances의 인스턴스 수는 linklet의 import 집합 수와 일치해야 합니다.
target-instance가 #f이거나 제공되지 않으면, 결과는 링클릿의 새로운 인스턴스예요. target-instance가 인스턴스이면, 그 인스턴스가 링클릿 정의와 표현식에 사용·수정되고, 결과는 링클릿의 마지막 표현식의 값입니다.
링클릿의 내보낸 변수는 각 내보내기에 대한 링클릿의 외부 이름을 사용해 결과 인스턴스 또는 target-instance에서 접근할 수 있어요. target-instance가 #f가 아닌 값으로 제공되면, 링클릿 정의가 수정하지 않는 한 기존 변수는 그대로 남습니다.
use-prompt?가 참이면 모듈 본문의 표현식과 같은 방식으로 링클릿 인스턴스화 주위에 프롬프트가 감싸집니다. 링클릿이 여러 정의나 즉시 표현식을 포함하면 각 정의·표현식 주위에 프롬프트가 감싸질 수도 있고 아닐 수도 있어요. 'use-prompt를 compile-linklet에 제공하면 각 정의·표현식 주위에 프롬프트가 쓰이도록 보장할 수 있습니다.
프로시저
(linklet-import-variables linklet) → (listof (listof symbol?))
linklet : linklet?
링클릿의 import를 설명하는 값을 반환해요. 결과 리스트의 각 요소는 인스턴스화 시 단일 인스턴스가 충족하는 import 집합에 대응하고, 집합의 각 구성원은 대응하는 import 인스턴스에서 사용되는 변수 이름이에요.
프로시저
(linklet-export-variables linklet) → (listof symbol?)
linklet : linklet?
링클릿의 export를 설명하는 값을 반환해요. 리스트의 각 요소는 링클릿이 자신의 인스턴스에서 사용할 수 있게 만드는 변수에 대응합니다.
프로시저
(linklet-add-target-machine-info linklet from-linklet) → linklet?
linklet : linklet?
from-linklet : (or linklet? hash?)
compile-linklet이나 recompile-linklet이 교차 모듈 정보를 위해 get-import를 통해 링클릿을 요청하면, 그 링클릿은 current-compile-target-machine이 결정하는 현재 컴파일 대상과 호환되는 정보를 가질 것으로 기대됩니다. 교차 컴파일에 쓰고 또 실행할 링클릿의 관리 단순화를 위해, 링클릿 구현이 하나의 링클릿 안에 여러 대상 머신에 대한 정보를 지원할 수 있습니다. 그 경우 linklet-add-target-machine-info는 linklet과 같지만 from-linklet에서 대상별 정보가 추가된 링클릿을 반환해요. 두 링클릿은 호환되는 소스에서 나와야 하지만, linklet-add-target-machine-info는 호환성에 대한 온전성 검사만 수행할 수도 있습니다.
from-linklet은 링클릿이거나 linklet-summarize-target-machine-info가 만든 링클릿 정보의 요약일 수 있어요.
버전 8.12.0.3 (패키지 base)에서 추가됨.
버전 8.17.0.3에서 변경: from-linklet을 요약으로 지원하는 것이 추가됨.
프로시저
(linklet-summarize-target-machine-info from-linklet) → hash?
from-linklet : linklet?
linklet-add-target-machine-info를 위해 from-linklet과 같은 정보를 갖지만, racket/fasl로 이식 가능하게 직렬화할 수 있는 형태의 값을 반환해요.
버전 8.17.0.3 (패키지 base)에서 추가됨.
프로시저
(decompile-linklet linklet) → (or/c #f correlated? any/c)
linklet : linklet?
링클릿을 compile-linklet이 기대하는 S-표현 형태로 다시 컴파일하려고 시도해요. 링클릿을 디컴파일할 수 없으면 결과는 #f예요. current-compile-target-machine이 #f로 설정된 상태(머신 독립 바이트코드용)로 compile을 통해 생성된 링클릿은 항상 디컴파일될 수 있습니다.
버전 8.18.0.19 (패키지 base)에서 추가됨.
프로시저
(linklet-directory? v) → boolean?
v : any/c
v가 링클릿 디렉토리이면 #t, 그렇지 않으면 #f를 반환해요.
프로시저
(hash->linklet-directory content) → linklet-directory?
content : (and/c hash? hash-eq? immutable? (not/c impersonator?))
해시 테이블 형태의 매핑을 받아 링클릿 디렉토리를 구성해요. content의 각 키는 심볼이거나 #f여야 하고, 각 심볼은 링클릿 디렉토리로 매핑되어야 하며, #f는 링클릿 번들로 매핑되거나 매핑되지 않아야 합니다.
프로시저
(linklet-directory->hash linklet-directory) → (and/c hash? hash-eq? immutable? (not/c impersonator?))
linklet-directory : linklet-directory?
링클릿 디렉토리의 내용을 해시 테이블로 추출해요.
프로시저
(linklet-bundle? v) → boolean?
v : any/c
v가 링클릿 번들이면 #t, 그렇지 않으면 #f를 반환해요.
프로시저
(hash->linklet-bundle content) → linklet-bundle?
content : (and/c hash? hash-eq? immutable? (not/c impersonator?))
해시 테이블 형태의 매핑을 받아 링클릿 번들을 구성해요. content의 각 키는 심볼이거나 fixnum이어야 합니다. 해시 테이블의 값은 제약이 없지만, 모두 링클릿이거나 read가 write 출력에서 복구할 수 있는 값이어야 한다는 의도입니다.
프로시저
(linklet-bundle->hash linklet-bundle) → (and/c hash? hash-eq? immutable? (not/c impersonator?))
linklet-bundle : linklet-bundle?
링클릿 번들의 내용을 해시 테이블로 추출해요.
프로시저
(linklet-body-reserved-symbol? sym) → boolean?
sym : symbol?
sym이 링클릿 안의 바인딩으로 허용되지 않는 원시 이름이나 다른 식별자이면 #t, 그렇지 않으면 #f를 반환해요.
버전 8.2.0.1 (패키지 base)에서 추가됨.
프로시저
(instance? v) → boolean?
v : any/c
v가 링클릿 인스턴스이면 #t, 그렇지 않으면 #f를 반환해요.
프로시저
(make-instance name [data mode] variable-name variable-value ... ...) → instance?
name : any/c
data : any/c = #f
mode : (or/c #f 'constant 'consistent) = #f
variable-name : symbol?
variable-value : any/c
링클릿 인스턴스를 직접 구성해요. 임의의 name과 data 값을 인스턴스에 연관시키는 것 외에도, variable-name과 variable-value가 명시하는 변수들로 인스턴스를 채웁니다.
variable-name과 variable-value 인자가 제공되면 선택적 data와 mode 인자도 반드시 제공되어야 해요. mode 인자는 모든 variable-name에 대해 instance-set-variable-value!에서처럼 사용됩니다.
프로시저
(instance-name instance) → any/c
instance : instance?
instance에 그 이름으로 연관된 값을 반환해요. 이는 make-instance에 제공된 첫 번째 값이거나 인스턴스를 만들기 위해 인스턴스화된 링클릿의 이름입니다.
프로시저
(instance-data instance) → any/c
instance : instance?
instance에 그 데이터로 연관된 값을 반환해요. 이는 make-instance에 제공된 두 번째 값이거나 기본 #f입니다.
프로시저
(instance-variable-names instance) → (list symbol?)
instance : instance?
instance에서 접근할 수 있는 모든 변수의 모든 이름 리스트를 반환해요.
프로시저
(instance-variable-value instance name [fail-k]) → any
instance : instance?
name : symbol?
fail-k : any/c = (lambda () (error ....))
instance에서 name으로 내보낸 변수의 값을 반환해요. 그런 변수가 내보내지지 않으면 hash-ref가 하는 것과 같은 방식으로 fail-k가 사용됩니다.
프로시저
(instance-set-variable-value! instance name v [mode]) → void?
instance : instance?
name : symbol?
v : any/c
mode : (or/c #f 'constant 'consistent) = #f
name으로 내보낸 변수가 이미 상수로 존재하지 않는 한, 그 값이 v가 되도록 instance에서 변수를 설정하거나 만들어요. name에 대한 변수가 상수로 존재하면 exn:fail:contract 예외가 발생합니다.
mode가 'constant 또는 'consistent이면 변수가 상수가 되도록 만들어지거나 변경됩니다. 게다가 compile-linklet에 대한 get-import 콜백을 통해 인스턴스가 링클릿의 import로 보고될 때, 컴파일러는 그 변수가 링클릿의 import를 충족하는 데 사용되는 모든 미래 인스턴스에서 상수일 것이라고 가정할 수 있어요.
mode가 'consistent이면, 인스턴스가 compile-linklet에 대한 콜백을 통해 보고될 때 컴파일러는 추가로 그 변수의 값이 미래 인스턴스에서 같을 것이라고 가정할 수 있습니다. 컴파일 목적으로 "같다"는 것은 프로시저 값이 같은 arity와 구현 세부사항을 가지거나, 구조체 타입 값이 같은 설정을 가지거나, 마샬 가능한 상수가 현재 값과 equal? 하거나 하는 등을 뜻할 수 있어요.
프로시저
(instance-unset-variable! instance name) → void?
instance : instance?
name : symbol?
name이 상수 변수로 존재하지 않는 한, name으로 변수를 내보내지 않도록 instance를 변경해요. name에 대한 변수가 상수로 존재하면 exn:fail:contract 예외가 발생합니다.
프로시저
(instance-describe-variable! instance name desc-v) → void?
instance : instance?
name : symbol?
desc-v : any/c
인스턴스가 compile-linklet에 대한 get-import 콜백을 통해 반환되는 링클릿을 컴파일하는 데 유용할 수 있는, instance 안의 name에 대한 정보를 등록해요. desc-v 설명은 어떤 값이든 될 수 있으며, 인식되는 설명은 가상 머신에 따라 다르지만 다음을 포함할 수 있습니다.
`(procedure . ,arity-mask)— 그 값은 항상 임퍼소네이션되지 않고 구조체도 아닌 프로시저이며,procedure-arity-mask스타일의 arity는arity-mask예요.`(procedure/succeeds . ,arity-mask)—`(procedure . ,arity-mask)와 같지만, 호출 맥락을 캡처하거나 이스케이프하는 예외를 결코 일으키지 않는 프로시저를 위한 것입니다.`(procedure/pure . ,arity-mask)—`(procedure/succeeds . ,arity-mask)와 같지만 관찰 가능한 부작용이 없어서, 프로시저 호출을 재배열할 수 있습니다.
버전 7.1.0.8 (패키지 base)에서 추가됨.
프로시저
(variable-reference->instance varref [ref-site?]) → (if ref-site? (or/c instance? #f symbol?) instance?)
varref : variable-reference?
ref-site? : any/c = #f
ref-site?가 #f이면 varref의 변수가 정의된 인스턴스를 추출하고, ref-site?가 참이면 varref 자신이 있는 인스턴스를 반환해요. 이 변수 참조의 개념은 모듈 수준에서와 같으며, 모듈 인스턴스의 특정 페이즈를 구현하는 링클릿 인스턴스를 반영할 수 있습니다.
ref-site?가 #f일 때 varref가 식별자 없는 (#%variable-reference)에서 온 것이면 결과는 #f예요. varref가 원시를 가리키면 결과는 심볼입니다.
프로시저
(correlated? v) → boolean?
v : any/c
(correlated-source crlt) → any
crlt : correlated?
(correlated-line crlt) → (or/c exact-positive-integer? #f)
crlt : correlated?
(correlated-column crlt) → (or/c exact-nonnegative-integer? #f)
crlt : correlated?
(correlated-position crlt) → (or/c exact-positive-integer? #f)
crlt : correlated?
(correlated-span crlt) → (or/c exact-nonnegative-integer? #f)
crlt : correlated?
(correlated-e crlt) → any
crlt : correlated?
(correlated->datum crlt) → any
crlt : (or/c correlated? any/c)
(datum->correlated v [srcloc prop]) → correlated?
v : any/c
srcloc : (or/c correlated? #f (list/c any/c (or/c exact-positive-integer? #f) (or/c exact-nonnegative-integer? #f) (or/c exact-positive-integer? #f) (or/c exact-nonnegative-integer? #f)) (vector/c any/c (or/c exact-positive-integer? #f) (or/c exact-nonnegative-integer? #f) (or/c exact-positive-integer? #f) (or/c exact-nonnegative-integer? #f))) = #f
prop : (or/c correlated? #f) = #f
(correlated-property crlt key val) → correlated?
crlt : correlated?
key : any/c
val : any/c
(correlated-property crlt key) → any/c
crlt : correlated?
key : any/c
(correlated-property-symbol-keys crlt) → list?
crlt : correlated?
syntax?, syntax-source, syntax-line, syntax-column, syntax-position, syntax-span, syntax-e, syntax->datum, datum->syntax, syntax-property, syntax-property-symbol-keys와 같지만, 상관 객체(correlated object)를 대상으로 합니다.
datum->syntax와 달리 datum->correlated는 주어진 S-표현을 재귀적으로 지나가며 조각을 상관 객체로 변환하지 않아요. 대신 상관 객체는 단순히 즉시 값 주위에 감싸집니다. 반대로 correlated->datum은 그 인자(반드시 상관 객체일 필요는 없음)를 재귀적으로 지나가 상관 객체를 찾아 일반 S-표현으로 변환해요.
버전 7.6.0.6 (패키지 base)에서 변경: datum->correlated에 prop 인자 추가됨.