평가와 컴파일
평가와 컴파일 (Evaluation and Compilation)
eval과 관련 함수들을 통해 Racket 평가를 프로그램적으로 제어하는 방법을 알아봐요. 평가 핸들러·로드 핸들러·컴파일 핸들러와 그걸 조정하는 다양한 매개변수를 다룹니다.
출처: Racket Reference
본문
14.2 평가와 컴파일 (Evaluation and Compilation)
The Racket Guide의 Reflection and Dynamic Evaluation이 동적 평가를 소개합니다.
Racket은 eval과 관련 함수를 통해 평가에 대한 프로그램적 제어를 제공합니다. Racket 컴파일러와 관련된 언어 외적 시설에 대한 정보는 Controlling and Inspecting Compilation를 보세요.
(current-eval) → (any/c . -> . any)
(current-eval proc) → void?
proc : (any/c . -> . any)
현재 평가 핸들러를 결정하는 매개변수입니다. 평가 핸들러는 최상위 폼을 받아 평가하고 결과 값을 반환하는 프로시저입니다. 평가 핸들러는 eval, eval-syntax, 기본 로드 핸들러, read-eval-print-loop가 최상위 폼을 평가하기 위해 호출합니다. 핸들러는 인자를 꼬리 위치에서 평가해야 해요.
핸들러에 주어진 최상위 폼은 syntax object, 컴파일된 폼, syntax object로 감싼 컴파일된 폼, 또는 임의의 datum일 수 있어요.
기본 핸들러는 datum->syntax를 사용해 임의의 datum을 syntax object로 변환한 뒤, eval과 같은 방식으로 그 어휘 정보를 풍부하게 합니다. (top-level-form이 syntax object라면 그 어휘 정보는 풍부하게 되지 않아요.) 기본 평가 핸들러는 최상위 begin 폼의 body를 최상위로 이어 붙이도록 폼을 부분 확장하고( expand-to-top-form 참고), 그런 다음 이후 폼들을 계속 확장·컴파일·평가하기 전에 각 이어 붙여진 폼을 개별적으로 컴파일하고 평가합니다.
(eval top-level-form) → any
top-level-form : any/c
(eval top-level-form namespace) → any
top-level-form : any/c
namespace : namespace?
The Racket Guide의 Namespaces도 참고하세요.
top-level-form을 평가하기 위해 현재 평가 핸들러를 호출합니다. 평가 핸들러는 eval 호출에 대해 꼬리 위치에서 호출됩니다. 평가 핸들러는 현재 네임스페이스를 사용합니다; eval의 두 인자 경우, 평가 핸들러 호출은 current-namespace를 namespace로 설정하도록 parameterize됩니다.
top-level-form이 datum이 컴파일된 폼이 아닌 syntax object라면, 평가 핸들러로 보내지기 전에 그 어휘 정보가 풍부하게 됩니다:
-
top-level-form이 car가 심볼 또는 식별자인 pair이고, namespace-syntax-introduce를 (datum->syntax로 변환된) 식별자에 적용하면 namespace의 base phase에 대응하는 위상 수준에서 module에 바인딩된 식별자가 나온다면, 그 식별자만 풍부하게 됩니다. -
그 외 어떤
top-level-form에 대해서도 namespace-syntax-introduce가 전체 syntax object에 적용됩니다.
read-eval-print-loop와 load 스타일의 대화형 평가를 위해서는, 각 표현식을 eval에 넘기기 전에 보통 #%top-interaction에 바인딩되는 #%top-interaction로 감싸세요.
(eval-syntax stx) → any
stx : syntax?
(eval-syntax stx namespace) → any
stx : syntax?
namespace : namespace?
eval과 같지만, stx는 syntax object여야 하고, 평가 핸들러에 넘기기 전에 그 어휘 문맥이 풍부하게 되지 않습니다.
(current-load) → (path? (or/c #f symbol?
(cons/c (or/c #f symbol?)
(non-empty-listof symbol?))) . -> . any)
(current-load proc) → void?
proc : (path? (or/c #f symbol?
(cons/c (or/c #f symbol?)
(non-empty-listof symbol?))) . -> . any)
파일에서 최상위 폼을 로드하기 위한 현재 로드 핸들러를 결정하는 매개변수입니다. 로드 핸들러는 load, load-relative, load/cd, 기본 컴파일드-로드 핸들러가 호출합니다.
로드 핸들러는 두 인자를 받아요: 경로(경로(Paths) 참고)와 기대되는 모듈 이름입니다. 기대되는 모듈 이름은 require에 대한 응답으로 모듈 선언을 로드하기 위한 호출일 때(그 경우 파일은 모듈 선언을 담아야 해요) 심볼 또는 목록이고, 그 외 어떤 로드에 대해서도 #f입니다.
하위 모듈을 담은 컴파일된 모듈로 시작하는 스트림에서 모듈을 로드할 때, 로드 핸들러는 요청된 모듈만 로드해야 해요. 여기서 로드 핸들러의 인자로 심볼이면 루트 모듈을 나타내고, 목록이면 루트 모듈에 상대적인 경로가 목록의 cdr로 주어지는 하위 모듈을 나타냅니다. 하위 모듈이 독립적으로만(즉 컴파일된 폼에서, 소스에서 절대 아님) 로드되어야 할 때 목록은 #f로 시작해요; 하위 모듈을 독립적으로 로드할 수 없으면 로드 핸들러는 파일에서 로드하지 않고 반환해야 합니다. 기대되는 모듈 이름이 심볼로 시작하는 목록일 때, 루트 모듈과 다른 하위 모듈은 주어진 파일(소스에서일 수도 있음)에서 로드될 수 있고, 기대되는 하위 모듈을 찾지 못해도 로드 핸들러는 불평하지 않아야 해요. 존재하지 않는 소스 파일에서 모듈을 로드할 때, 하위 모듈이 요청되든 아니든 로드 핸들러는 예외를 발생시킬 수 있습니다.
기본 로드 핸들러는 경로에 ".zo" 접미사가 없으면, 파일 포트에 대해 줄 세기가 활성화된 read-syntax 모드로 파일에서 폼을 읽습니다. 또한 각 읽기를 read-accept-compiled, read-accept-reader, read-accept-lang을 #t로 설정하도록 parameterize합니다. 게다가 load-on-demand-enabled가 #t이면, read-syntax 호출 중 read-on-demand-source이 경로의 cleanse된 절대 형태로 설정됩니다. 단일 폼을 읽은 뒤, 그 폼은 기본 컨티뉴에이션 프롬프트 태그에 대한 컨티뉴에이션 프롬프트( call-with-continuation-prompt 참고)로 평가를 감싸고, load 호출의 컨티뉴에이션으로 중단을 전파하는 핸들러로 현재 평가 핸들러에 전달됩니다.
로드 핸들러의 두 번째 인자가 심볼이면:
- 파일의 read-syntax은 추가로 다음과 같이 parameterize됩니다(모듈 소스의 일관된 읽기를 제공하기 위해):
(current-readtable #f)
(read-case-sensitive #t)
(read-square-bracket-as-paren #t)
(read-curly-brace-as-paren #t)
(read-accept-box #t)
(read-accept-compiled #t)
(read-accept-bar-quote #t)
(read-accept-graph #t)
(read-syntax-accept-graph #f)
(read-decimal-as-inexact #t)
(read-accept-dot #t)
(read-accept-infix-dot #t)
(read-accept-quasiquote #t)
(read-accept-reader #t)
(read-accept-lang #t)
-
읽기 결과가 모듈 폼이 아니거나, 두 번째 read-syntax이 파일 끝(end-of-file)을 만들지 않으면, 파일에서 읽은 폼을 평가하지 않고 exn:fail 예외가 발생합니다. (이전 버전에서는 모듈 선언이 로드 핸들러의 두 번째 인자로 주어진 이름과 일치하는지 확인했지만, 이 검사는 더 이상 수행되지 않습니다.)
-
초기 모듈 식별자의 어휘 정보는 module에 대한 바인딩으로 풍부하게 되므로, 그 폼이 현재 네임스페이스의 바인딩과 무관한 모듈 선언에 대응합니다.
로드 핸들러의 두 번째 인자가 #f이면, 파일에서 읽은 각 표현식은 평가 핸들러에 넘기기 전에 보통 #%top-interaction에 바인딩되는 #%top-interaction로 감싸집니다.
기본 로드 핸들러의 반환 값은 로드된 파일의 마지막 폼의 값이거나, 파일에 폼이 없으면 #<void>입니다. 주어진 경로가 상대 경로이면 current-directory의 값을 사용해 해석됩니다.
(load file) → any
file : path-string?
The Racket Guide의 Namespaces도 참고하세요.
현재 로드 핸들러를 꼬리 위치에서 호출합니다. 호출은 current-load-relative-directory를 file의 디렉터리로 설정하도록 parameterize되는데, 이는 current-directory의 값에 상대적으로 해석됩니다.
(load-relative file) → any
file : path-string?
load/use-compiled와 같지만, file이 상대 경로일 때, 전자가 #f가 아니면 current-directory의 값 대신 current-load-relative-directory의 값을 사용해 해석됩니다. 그 외에는 current-directory(Filesystem)가 사용됩니다.
(load/cd file) → any
file : path-string?
load와 같지만, load/cd는 로드 핸들러를 호출하기 전에 current-directory와 current-load-relative-directory 둘 다 설정합니다.
(current-load-extension) → (path? (or/c #f symbol?
(cons/c (or/c #f symbol?)
(non-empty-listof symbol?))) . -> . any)
(current-load-extension proc) → void?
proc : (path? (or/c #f symbol?
(cons/c (or/c #f symbol?)
(non-empty-listof symbol?))) . -> . any)
load-extension과 기본 컴파일드-로드 핸들러가 호출하는 확장-로드 핸들러를 결정하는 매개변수입니다.
확장-로드 핸들러는 로드 핸들러와 같은 인자를 받지만, 파일은 보통 ".so"(Unix), ".dll"(Windows), ".dylib"(Mac OS) 파일 접미사를 가진 플랫폼 특정 동적 확장이어야 해요. 파일은 내부의 OS 특정 기본 요소를 사용해 로드됩니다. 동적 확장에 대한 자세한 내용은 Inside: Racket C API를 보세요.
확장은 (system-type 'vm)이 'racket을 반환할 때만 지원됩니다.
(load-extension file) → any
file : path-string?
load처럼 current-load-relative-directory를 설정하고, 확장-로드 핸들러를 꼬리 위치에서 호출합니다.
확장은 (system-type 'vm)이 'racket을 반환할 때만 지원됩니다.
(load-relative-extension file) → any
file : path-string?
load-extension과 같지만, load-relative처럼 current-load-relative-directory를 사용해 file을 해석합니다.
확장은 (system-type 'vm)이 'racket을 반환할 때만 지원됩니다.
(current-load/use-compiled) → (path? (or/c #f symbol?
(cons/c (or/c #f symbol?)
(non-empty-listof symbol?))) . -> . any)
(current-load/use-compiled proc) → void?
proc : (path? (or/c #f symbol?
(cons/c (or/c #f symbol?)
(non-empty-listof symbol?))) . -> . any)
컴파일된 폼을 가질 수 있는 파일에서 로드하기 위한 현재 컴파일드-로드 핸들러를 결정하는 매개변수입니다. 컴파일드-로드 핸들러는 load/use-compiled가 호출합니다.
컴파일드-로드 핸들러의 프로토콜은 current-load(로드 핸들러)와 같지만, 컴파일드-로드 핸들러는 current-load-relative-directory를 스스로 설정할 것으로 기대됩니다. 추가로 기본 컴파일드-로드 핸들러는 다음을 수행합니다:
-
주어진 경로가 ".rkt"로 끝나고 ".rkt" 파일이 존재하지 않으며, 핸들러의 두 번째 인자가
#f가 아니면, 기본 컴파일드-로드 핸들러는 ".ss" 파일을 확인합니다. -
기본 컴파일드-로드 핸들러는 ".zo"(바이트코드) 파일에서 로드할 기회를 확인하고,
(system-type 'vm)이'racket을 반환하면 ".so"(네이티브 Unix), ".dll"(네이티브 Windows), ".dylib"(네이티브 Mac OS) 파일도 확인합니다. -
기본 컴파일드-로드 핸들러가 주어진 경로에서 로드해야 하는데 주어진 경로가 존재하지 않고, 핸들러의 두 번째 인자가
#f가 아니면, 기본 컴파일드-로드 핸들러는 예외를 발생시키지 않고 반환합니다.
컴파일된 파일에 대한 검사는 주어진 경로 파일이 어떤 확장자(예: ".rkt" 또는 ".scrbl")로 끝날 때마다 일어나고, 그 검사는 current-compiled-file-roots와 use-compiled-file-paths 매개변수가 가리키는 하위 디렉터리를 file에 상대적으로 참조합니다. 여기서 전자는 컴파일된 파일의 "roots"를 제공하고 후자는 하위 디렉터리를 제공합니다. compiler/compilation-path도 참고하세요. "root"는 절대 경로일 수 있는데, 그 경우 file의 디렉터리는 두 번째 인자로 root를 사용해 reroot-path와 결합됩니다; "root"가 상대 경로이면 그 상대 경로가 대신 file의 디렉터리에 접미됩니다. roots는 순서대로 시도되고, 하위 디렉터리는 각 root 안에서 순서대로 확인됩니다. 가리켜진 하위 디렉터리 중 하나에 직접 존재하면 파일의 ".zo" 버전(이름은 file과 #".zo"를 path-add-extension에 넘겨 형성)이 로드되고, 또는 (system-type 'vm)이 'racket을 반환하면, use-compiled-file-paths 디렉터리의 "native" 하위 디렉터리 안, system-library-subpath이 이름을 붙인 더 깊은 하위 디렉터리에 존재하면 파일의 ".so"/".dll"/".dylib" 버전이 로드됩니다. 컴파일된 파일은 use-compiled-file-check에 따라 검사에 합격할 때만 로드됩니다; 기본 매개변수 값 'modify-seconds에서는 컴파일된 파일이 그 수정 날짜가 파일의 날짜보다 오래되지 않을 때만 사용됩니다. (system-type 'vm)이 'racket을 반환하고 ".zo"와 ".so"/".dll"/".dylib" 파일이 모두 사용 가능하면 ".zo" 파일이 사용됩니다.
".zo", ".so", ".dll", ".dylib" 파일이 로드되는 동안, 현재 로드-상대 디렉터리는 원래 파일의 디렉터리로 설정됩니다. 로드될 파일이 ".ss" 접미사를 가지는데 요청된 파일이 ".rkt" 접미사를 가지면, current-module-declare-source 매개변수가 로드된 파일의 전체 경로로 설정되고, 그 외에는 current-module-declare-source 매개변수가 #f로 설정됩니다.
원래 파일이 로드되거나 ".zo" 변형이 로드되면 로드 핸들러가 파일을 로드하도록 호출됩니다. 그 외 어떤 종류의 파일이 로드되면 확장-로드 핸들러가 호출됩니다.
기본 컴파일드-로드 핸들러가 바이트코드(즉 ".zo") 파일에서 모듈을 로드할 때, 핸들러는 현재 네임스페이스의 module registry에 바이트코드 파일 경로를 기록합니다. 더 구체적으로 핸들러는 로드된 모듈의 최상위 모듈(로드된 모듈이 하위 모듈이면 둘러싼 모듈)의 경로를 기록합니다. 그 후 같은 최상위 모듈 안의 모듈을 기본 컴파일드-로드 핸들러로 로드하는 것은, 컴파일드-로드 핸들러가 달리 선택했을 파일과 무관하게(예: use-compiled-file-paths 매개변수 값이 바뀌더라도) 기록된 파일을 사용합니다. 기본 모듈 이름 해석기는 모듈 선언이 새 네임스페이스에 부착될 때 바이트코드-파일 정보를 전송합니다. 이 프로토콜은 하위 모듈을 바이트코드 파일에서 독립적이지만 일관되게 로드하는 것을 지원합니다.
(load/use-compiled file) → any
file : path-string?
현재 컴파일드-로드 핸들러를 꼬리 위치에서 호출합니다.
(current-load-relative-directory) → (or/c (and/c path-string? complete-path?) #f)
(current-load-relative-directory path) → void?
path : (or/c (and/c path-string? complete-path?) #f)
load, load-relative, load-extension, load-relative-extension, 기본 컴파일드-로드 핸들러가 설정하고, load-relative, load-relative-extension, 기본 컴파일드-로드 핸들러가 사용하는 매개변수입니다.
매개변수 값으로 새 경로나 문자열이 제공되면 즉시 확장(경로(Paths) 참고)되고 경로로 변환됩니다. (디렉터리는 존재하지 않아도 됩니다.)
(use-compiled-file-paths) → (listof (and/c path? relative-path?))
(use-compiled-file-paths paths) → void?
paths : (listof (and/c path-string? relative-path?))
기본값이 (list (string->path "compiled"))인 상대 경로 목록입니다. 컴파일드-로드 핸들러(current-load/use-compiled 참고)가 사용합니다.
시작 시 PLT_ZO_PATH 환경 변수가 설정되어 있으면 초기 매개변수 값에 "compiled" 대신 사용할 경로를 제공합니다.
version 7.7.0.9 of package base에서 변경됨: PLT_ZO_PATH 추가.
(current-compiled-file-roots) → (listof (or/c path? 'same))
(current-compiled-file-roots paths) → void?
paths : (listof (or/c path-string? 'same))
기본 컴파일드-로드 핸들러(current-load/use-compiled 참고)가 사용하는 경로와 'same의 목록입니다.
매개변수는 보통 (list 'same)으로 초기화되지만, (find-compiled-file-roots)가 보고하는 설치 구성에 의해 매개변수의 초기 값이 조정될 수 있고, PLTCOMPILEDROOTS 환경 변수나 racket용 --compiled 또는 -R 명령줄 플래그로 더 조정될 수 있어요. 환경 변수가 정의되고 명령줄 플래그로 덮어써지지 않으면, 먼저 (version)의 결과로 어떤 @(version)을 대체한 뒤, (find-compiled-file-roots)가 만든 경로 목록과 함께 path-list-string->path-list을 사용해 파싱하여 매개변수의 초기 값에 도달합니다.
(find-compiled-file-roots) → (listof (or/c path? 'same))
보통 current-compiled-file-roots를 초기화하는 데 사용되는 경로와 'same의 목록을 만듭니다. 목록은 (find-config-dir)가 보고하는 디렉터리의 "config.rtkd" 파일을 조회해 결정되고, 거기에 구성되어 있지 않으면 (list 'same)으로 기본 설정됩니다.
Installation Configuration and Search Paths의 'compiled-file-roots도 참고하세요.
version 8.0.0.9 of package base에서 추가됨.
(use-compiled-file-check) → (or/c 'modify-seconds 'exists)
(use-compiled-file-check check) → void?
check : (or/c 'modify-seconds 'exists)
컴파일된 파일의 사용을 가능하게 하기 위해 컴파일된 파일을 소스에 대해 어떻게 확인하는지 결정하는 매개변수입니다. 기본적으로 파일-확인 모드는 'modify-seconds인데, 파일 시스템 수정 날짜가 소스 파일보다 오래되지 않을 때 컴파일된 파일을 사용합니다. 'exists 모드는 컴파일된 파일이 존재하는 한 소스 대신 컴파일된 파일을 사용하게 합니다.
PLT_COMPILED_FILE_CHECK 환경 변수가 modify-seconds 또는 exists로 설정되어 있으면, Racket이 시작할 때 환경 변수의 값이 매개변수를 구성합니다.
version 6.6.0.3 of package base에서 추가됨.
(read-eval-print-loop) → any
현재 입력·출력·오류 포트를 사용해 새 REPL을 시작합니다. REPL은 각 표현식을 보통 #%top-interaction에 바인딩되는 #%top-interaction로 감싸고, 각 평가를 기본 컨티뉴에이션 프롬프트 태그와 프롬프트 핸들러를 사용한 컨티뉴에이션 프롬프트( call-with-continuation-prompt 참고)로 감쌉니다. REPL은 또한 기본 태그에 대한 프롬프트로 읽기와 출력 연산을 감싸는데, 그 핸들러는 abort 인자를 무시하고 루프를 계속합니다. read-eval-print-loop 프로시저는 eof를 읽을 때까지 반환하지 않고, 그 시점에 #<void>를 반환합니다.
read-eval-print-loop 프로시저는 current-prompt-read, current-eval, current-print 매개변수를 통해 구성될 수 있습니다.
(current-prompt-read) → (-> any)
(current-prompt-read proc) → void?
proc : (-> any)
프롬프트 읽기 핸들러를 결정하는 매개변수입니다. 이는 인자를 받지 않고, 프롬프트 문자열을 표시하며, 평가할 최상위 폼을 반환하는 프로시저입니다. 프롬프트 읽기 핸들러는 read-eval-print-loop이 호출하고, 프롬프트를 출력한 뒤 핸들러는 보통 (current-read-interaction 매개변수가 결정한) 읽기 상호작용 핸들러를 (current-get-interaction-input-port 매개변수가 결정한) 상호작용 포트 핸들러가 만든 포트로 호출해야 합니다.
기본 프롬프트 읽기 핸들러는 >를 출력하고 다음의 결과를 반환합니다:
(let ([in ((current-get-interaction-input-port))])
((current-read-interaction) (object-name in) in))
입력과 출력 포트가 모두 터미널이고(terminal-port?의 의미에서) 출력 포트가 줄을 세고 있는 것으로 보이면(port-next-location이 #f가 아닌 줄과 열을 반환), 읽기 결과를 반환하기 전에 set-port-next-location!를 통해 출력 포트의 줄이 증가하고 열이 0으로 재설정됩니다.
(current-get-interaction-input-port) → (-> input-port?)
(current-get-interaction-input-port proc) → void?
proc : (-> input-port?)
read-eval-print-loop 입력에 사용할 포트를 반환하는 상호작용 포트 핸들러를 결정하는 매개변수입니다.
기본 상호작용 포트 핸들러는 현재 입력 포트를 반환합니다. 게다가 그 포트가 초기 현재 입력 포트이면 초기 현재 출력·오류 포트가 비워집니다.
racket/gui/base 라이브러리는 현재 값을 확장하여 이 매개변수 값을 조정합니다. 확장은 결과 포트를 감싸서, 포트에서 읽기가 차단될 때 GUI 이벤트를 처리할 수 있게 합니다.
(current-get-interaction-evt) → (-> evt?)
(current-get-interaction-evt proc) → void?
proc : (-> evt?)
상호작용 이벤트 핸들러를 결정하는 매개변수입니다. 이는 read-eval-print-loop가 입력을 기다리는 것과 유사한 차단과 함께 사용되어야 하는 동기화 가능한 이벤트를 반환합니다 — 하지만 입력 포트를 직접 읽지 않으므로 current-get-interaction-input-port는 적용되지 않습니다.
상호작용 이벤트 핸들러가 준비된 이벤트를 반환하고, 이벤트의 준비 값이 프로시저일 때, 그 프로시저는 차단이 재개될 때 0개의 인자로 호출되도록 의도됩니다. 기본 상호작용 이벤트 핸들러는 never-evt를 반환합니다.
racket/gui/base 라이브러리는 현재 값을 확장하여 이 매개변수 값을 조정합니다. 확장은 현재 값의 결과를 choice-evt와, GUI 이벤트가 사용 가능할 때 준비되는 이벤트와 결합하며, 이벤트의 값은 하나 이상의 사용 가능한 GUI 이벤트에 양보하는 프로시저입니다.
version 8.3.0.3 of package base에서 추가됨.
(current-read-interaction) → (any/c input-port? . -> . any)
(current-read-interaction proc) → void?
proc : (any/c input-port? . -> . any)
현재 읽기 상호작용 핸들러를 결정하는 매개변수입니다. 이는 임의의 값과 입력 포트를 받아 입력 포트에서 읽은 표현식을 반환하는 프로시저입니다.
기본 읽기 상호작용 핸들러는 src와 in을 받아 반환합니다:
(parameterize ([read-accept-reader #t]
[read-accept-lang #f])
(read-syntax src in))
(current-print) → (any/c . -> . any)
(current-print proc) → void?
proc : (any/c . -> . any)
read-eval-print-loop가 평가 결과를 출력하기 위해 호출하는 출력 핸들러를 결정하는 매개변수입니다(그리고 결과는 무시됩니다).
기본 출력 핸들러는 (current-output-port 매개변수가 결정한) 현재 출력 포트에 값을 print하고 새 줄을 출력합니다. 값이 #<void>일 때는 아무것도 출력하지 않습니다.
(current-compile) → (any/c boolean? . -> . compiled-expression?)
(current-compile proc) → void?
proc : (any/c boolean? . -> . compiled-expression?)
현재 컴파일 핸들러를 결정하는 매개변수입니다. 컴파일 핸들러는 최상위 폼을 받아 컴파일된 폼을 반환하는 프로시저입니다; 컴파일에 대한 자세한 내용은 Compilation을 보세요.
컴파일 핸들러는 compile이 호출하고, 기본 평가 핸들러와 기본 로드 핸들러가 간접적으로 호출합니다.
핸들러의 두 번째 인자는 컴파일된 폼이 즉시 평가에만 사용될 것이면 #t, 나중에 저장될 수 있으면 #f입니다; 기본 컴파일 핸들러는 즉시 평가의 특별한 경우에 대해 최적화됩니다.
컴파일된 폼이 출력 포트에 쓰여질 때, 쓰여진 폼은 #~로 시작합니다. Printing Compiled Code에 대한 자세한 내용을 보세요.
내부 테스트 목적으로, PLT_VALIDATE_COMPILE 환경 변수가 설정되면 기본 컴파일 핸들러는 (컴파일된 바이트코드가 로드될 때의 검증에만 의존하지 않고) 자신의 컴파일 결과에 대해 즉시 바이트코드 검증기를 실행합니다.
current-compile 바인딩은 protect-out의 의미로 protected로 제공됩니다.
version 8.2.0.4 of package base에서 변경됨: 바인딩을 protected로 변경.
(compile top-level-form) → compiled-expression?
top-level-form : any/c
eval과 같지만, top-level-form과 함께 현재 컴파일 핸들러를 꼬리 위치에서 호출합니다.
(compile-syntax stx) → compiled-expression?
stx : syntax?
eval-syntax와 같지만, stx와 함께 현재 컴파일 핸들러를 꼬리 위치에서 호출합니다.
(compiled-expression-recompile ce) → compiled-expression?
ce : compiled-expression?
ce를 다시 컴파일합니다. ce가 머신 독립적으로 컴파일되었고 current-compile-target-machine이 #f로 설정되지 않았다면, 다시 컴파일하는 것은 효과적으로 현재 머신 형식으로 변환합니다. 그 외에는 다시 컴파일하는 것이 효과적으로 최적화 단계를 다시 실행해 잠재적으로 다른 성능 특성을 가진 동등한 컴파일된 폼을 만듭니다.
version 6.3 of package base에서 추가됨.
(compiled-expression-add-target-machine ce other-ce)
→ compiled-expression?
ce : compiled-expression?
other-ce : (or/c compiled-expression? hash?)
ce와 같은 컴파일된 표현식을 반환하지만, ce의 교차 컴파일 정보를 other-ce의 정보로 보강하거나 대체합니다. 의도는 ce와 other-ce가 current-compile-target-machine에 대해 서로 다른 값으로 컴파일되었고, ce가 컴파일 머신에서 모듈을 실행하는 데 사용되며, 모듈의 교차 컴파일 import에 other-ce의 정보가 필요하다는 것입니다.
other-ce 인자는 컴파일된 모듈이거나 compiled-expression-summarize-target-machine이 만든 모듈 정보 요약일 수 있어요.
version 8.12.0.3 of package base에서 추가됨.
version 8.17.0.3에서 변경됨: other-ce를 요약으로 지원 추가.
(compiled-expression-summarize-target-machine other-ce) → hash?
other-ce : compiled-expression?
compiled-expression-add-target-machine을 위해 other-ce와 같은 정보를 가지지만, racket/fasl을 통해 이식 가능하게 직렬화될 수 있는 형태의 값을 반환합니다.
version 8.17.0.3 of package base에서 추가됨.
(compiled-expression? v) → boolean?
v : any/c
v가 컴파일된 폼이면 #t, 아니면 #f를 반환합니다.
(compile-enforce-module-constants) → boolean?
(compile-enforce-module-constants on?) → void?
on? : any/c
모듈 선언이 어떻게 컴파일되는지 결정하는 매개변수입니다.
상수가 강제되고, 모듈의 매크로 확장된 body가 모듈 안에 정의된 특정 변수에 대한 set! 할당을 담지 않을 때, 그 변수는 정의가 평가될 때 상수로 표시됩니다. 그 후 그 변수의 값은 module->namespace를 통해 할당되거나 정의되지 않게 될 수 없고, 모듈을 재선언해 정의할 수도 없습니다.
상수를 강제하면 컴파일러가 일부 변수 값을 인라인할 수 있고, 네이티브 코드 just-in-time 컴파일러가 특정 런타임 검사를 건너뛰는 코드를 생성할 수 있게 해요.
(compile-allow-set!-undefined) → boolean?
(compile-allow-set!-undefined allow?) → void?
allow? : any/c
set! 표현식이 전역 변수를 변형할 때 어떻게 컴파일되는지 결정하는 매개변수입니다. 이 매개변수의 값이 참 값이면, 전역 변수에 대한 set! 표현식은, 전역 변수가 이전에 정의되지 않았더라도 그 변수가 설정되도록 컴파일됩니다. 그 외에는 전역 변수에 대한 set! 표현식은, set!이 수행될 때 전역 변수가 정의되지 않으면 exn:fail:contract:variable 예외를 발생시키도록 컴파일됩니다. 이 매개변수는 표현식이 평가될 때가 아니라 컴파일될 때 사용된다는 점에 주의하세요.
(compile-context-preservation-enabled) → boolean?
(compile-context-preservation-enabled on?) → void?
on? : any/c
함수 호출 인라인과, continuation-mark-set->context가 보고하는 스택 추적에서 정보가 손실될 수 있는 다른 최적화를 컴파일이 피해야 하는지 결정하는 매개변수입니다. 기본값은 #f로, 그러한 최적화를 허용합니다.
(current-compile-target-machine) → (or/c #f (and/c symbol? compile-target-machine?))
(current-compile-target-machine target) → void?
target : (or/c #f (and/c symbol? compile-target-machine?))
새로 컴파일된 표현식의 플랫폼 및/또는 가상 머신 대상을 결정하는 매개변수입니다.
대상이 #f이면 컴파일된 표현식은 머신 독립 형식(보통 ".zo" 파일)으로 쓰여집니다. 머신 독립 컴파일 코드는 어떤 플랫폼과 어떤 Racket 가상 머신에서도 동작합니다. 머신 독립 컴파일 표현식이 다시 읽힐 때, 현재 플랫폼과 가상 머신에 대한 추가 컴파일을 거치는데, 플랫폼과 가상 머신에 완전히 컴파일된 형식을 읽는 것보다 상당히 느릴 수 있어요.
기본값은 #f가 아닌데, 독립 실행 Racket(또는 GRacket)에 대한 -M/--compile-any 명령줄 플래그나 PLT_COMPILE_ANY 환경 변수(어떤 값으로든 설정)를 통해 머신 독립 모드가 활성화되지 않는 한 그렇습니다.
version 7.1.0.6 of package base에서 추가됨.
(compile-target-machine? sym) → boolean?
sym : symbol?
현재 실행 중인 Racket에 대해 sym이 지원되는 컴파일 대상인지 보고합니다.
(system-type 'vm)이 'racket을 보고하면 유일한 대상 심볼은 'racket입니다. (system-type 'vm)이 'chez-scheme을 보고하면 현재 플랫폼에 대응하는 심볼이 대상이고, 다른 대상도 지원될 수 있어요. system-type의 'target-machine 모드는 실행 중인 Racket의 네이티브 대상 머신을 보고합니다.
version 7.1.0.6 of package base에서 추가됨.
(current-compile-realm) → symbol?
(current-compile-realm realm) → void?
realm : symbol?
모듈과 프로시저가 컴파일될 때 할당되는 realm을 결정합니다.
version 8.4.0.2 of package base에서 추가됨.
(eval-jit-enabled) → boolean?
(eval-jit-enabled on?) → void?
on? : any/c
The Racket Guide의 Bytecode, Machine Code, and Just-in-Time (JIT) Compilers도 참고하세요.
기본 평가 핸들러에 넘겨진 (컴파일 여부와 무관한) 코드에 대해 네이티브 코드 just-in-time 컴파일러(JIT)가 활성화되는지 결정하는 매개변수입니다. 참 매개변수 값은 JIT가 지원되는 플랫폼과 JIT에 의존하는 Racket 가상 머신에서만 효과가 있어요.
기본값은 #t인데, 현재 플랫폼이 JIT를 지원하지 않지만 같은 가상 머신에서 다른 플랫폼에서는 지원되는 경우가 아니고, 독립 실행 Racket(또는 GRacket)에 대한 -j/--no-jit 명령줄 플래그로 비활성화되지 않은 경우가 아니고, PLTNOMZJIT 환경 변수(어떤 값으로든 설정)로 비활성화되지 않은 경우가 아니라면 그렇습니다.
(load-on-demand-enabled) → boolean?
(load-on-demand-enabled on?) → void?
on? : any/c
기본 로드 핸들러가 read-on-demand-source을 설정하는지 결정하는 매개변수입니다. 자세한 내용은 current-load를 보세요. 기본값은 #t인데, -d/--no-delay 명령줄 플래그로 비활성화되지 않는 한 그렇습니다.