Unsafe Operations
Unsafe Operations
racket/base와 racket이 제공하는 모든 함수와 폼은 인자가 계약 및 기타 제약과 일치하는지 확인해요. 예를 들어 vector-ref는 첫 번째 인자가 벡터인지, 두 번째 인자가 정확한 정수인지, 두 번째 인자가 0과 벡터 길이보다 하나 작은 값 사이(포함)인지 확인해요.
racket/unsafe/ops가 제공하는 함수는 안전하지 않아요(unsafe). 그것들은 특정 제약이 있지만 그 제약이 검사되지 않으며, 이 덕분에 시스템이 더 빠른 코드를 생성하고 실행할 수 있어요. 인자가 안전하지 않은 함수의 제약을 위반하면 그 함수의 동작과 결과는 예측할 수 없고, 전체 시스템이 충돌하거나 손상될 수 있어요.
racket/unsafe/ops의 내보낸 바인딩은 모두 protect-out의 의미에서 보호되므로, 코드 인스펙터(Code Inspectors 문서 참고)를 조정하여 안전하지 않은 연산에 대한 접근을 막을 수 있어요.
출처: Racket Reference
본문
(require racket/unsafe/ops) ; package: base
Unsafe Numeric Operations
(unsafe-fx+ a ...) → fixnum?
a : fixnum?
procedure
(unsafe-fx- a b ...) → fixnum?
a : fixnum?
b : fixnum?
procedure
(unsafe-fx* a ...) → fixnum?
a : fixnum?
procedure
(unsafe-fxquotient a b) → fixnum?
a : fixnum?
b : fixnum?
procedure
(unsafe-fxremainder a b) → fixnum?
a : fixnum?
b : fixnum?
procedure
(unsafe-fxmodulo a b) → fixnum?
a : fixnum?
b : fixnum?
procedure
(unsafe-fxabs a) → fixnum?
a : fixnum?
fixnum에 대해: fx+, fx-, fx*, fxquotient, fxremainder, fxmodulo, fxabs의 비검사 버전이에요.
base 패키지 7.0.0.13 버전에서 변경됨: unsafe-fx+와 unsafe-fx*에 0개 이상의 인자를, unsafe-fx-에 1개 이상의 인자를 허용해요.
(unsafe-fxand a ...) → fixnum?
a : fixnum?
procedure
(unsafe-fxior a ...) → fixnum?
a : fixnum?
procedure
(unsafe-fxxor a ...) → fixnum?
a : fixnum?
procedure
(unsafe-fxnot a) → fixnum?
a : fixnum?
procedure
(unsafe-fxlshift a b) → fixnum?
a : fixnum?
b : fixnum?
procedure
(unsafe-fxrshift a b) → fixnum?
a : fixnum?
b : fixnum?
procedure
(unsafe-fxrshift/logical a b) → fixnum?
a : fixnum?
b : fixnum?
fixnum에 대해: fxand, fxior, fxxor, fxnot, fxlshift, fxrshift, fxrshift/logical의 비검사 버전이에요.
base 패키지 7.0.0.13 버전에서 변경됨: unsafe-fxand, unsafe-fxior, unsafe-fxxor에 0개 이상의 인자를 허용해요. 8.8.0.5 버전에서 변경됨: unsafe-fxrshift/logical이 추가되었어요.
(unsafe-fxpopcount a) → fixnum?
a : (and/c fixnum? (not/c negative?))
procedure
(unsafe-fxpopcount32 a) → fixnum?
a : (and/c fixnum? (integer-in 0 #xFFFFFFFF))
procedure
(unsafe-fxpopcount16 a) → fixnum?
a : (and/c fixnum? (integer-in 0 #xFFFF))
fixnum에 대해: fxpopcount, fxpopcount32, fxpopcount16의 비검사 버전이에요.
base 패키지 8.5.0.6 버전에서 추가되었어요.
(unsafe-fx+/wraparound a b) → fixnum?
a : fixnum?
b : fixnum?
procedure
(unsafe-fx-/wraparound [a] b) → fixnum?
a : fixnum? = 0
b : fixnum?
procedure
(unsafe-fx*/wraparound a b) → fixnum?
a : fixnum?
b : fixnum?
procedure
(unsafe-fxlshift/wraparound a b) → fixnum?
a : fixnum?
b : fixnum?
fixnum에 대해: fx+/wraparound, fx-/wraparound, fx*/wraparound, fxlshift/wraparound의 비검사 버전이에요.
base 패키지 7.9.0.6 버전에서 추가되었어요. 8.15.0.12 버전에서 변경됨: unsafe-fx-/wraparound가 단일 인자를 받아들이도록 변경되었어요.
(unsafe-fx= a b ...) → boolean?
a : fixnum?
b : fixnum?
procedure
(unsafe-fx< a b ...) → boolean?
a : fixnum?
b : fixnum?
procedure
(unsafe-fx> a b ...) → boolean?
a : fixnum?
b : fixnum?
procedure
(unsafe-fx<= a b ...) → boolean?
a : fixnum?
b : fixnum?
procedure
(unsafe-fx>= a b ...) → boolean?
a : fixnum?
b : fixnum?
procedure
(unsafe-fxmin a b ...) → fixnum?
a : fixnum?
b : fixnum?
procedure
(unsafe-fxmax a b ...) → fixnum?
a : fixnum?
b : fixnum?
fixnum에 대해: fx=, fx<, fx>, fx<=, fx>=, fxmin, fxmax의 비검사 버전이에요.
base 패키지 7.0.0.13 버전에서 변경됨: 두 개만 허용하는 대신 하나 이상의 인자를 허용해요.
(unsafe-fl+ a ...) → flonum?
a : flonum?
procedure
(unsafe-fl- a b ...) → flonum?
a : flonum?
b : flonum?
procedure
(unsafe-fl* a ...) → flonum?
a : flonum?
procedure
(unsafe-fl/ a b ...) → flonum?
a : flonum?
b : flonum?
procedure
(unsafe-flabs a) → flonum?
a : flonum?
flonum에 대해: fl+, fl-, fl*, fl/, flabs의 비검사 버전이에요.
base 패키지 7.0.0.13 버전에서 변경됨: unsafe-fl+와 unsafe-fl*에 0개 이상의 인자를, unsafe-fl-와 unsafe-fl/에 하나 이상의 인자를 허용해요.
(unsafe-fl= a b ...) → boolean?
a : flonum?
b : flonum?
procedure
(unsafe-fl< a b ...) → boolean?
a : flonum?
b : flonum?
procedure
(unsafe-fl> a b ...) → boolean?
a : flonum?
b : flonum?
procedure
(unsafe-fl<= a b ...) → boolean?
a : flonum?
b : flonum?
procedure
(unsafe-fl>= a b ...) → boolean?
a : flonum?
b : flonum?
procedure
(unsafe-flmin a b ...) → flonum?
a : flonum?
b : flonum?
procedure
(unsafe-flmax a b ...) → flonum?
a : flonum?
b : flonum?
flonum에 대해: fl=, fl<, fl>, fl<=, fl>=, flmin, flmax의 비검사 버전이에요.
base 패키지 7.0.0.13 버전에서 변경됨: 두 개만 허용하는 대신 하나 이상의 인자를 허용해요.
(unsafe-flround a) → flonum?
a : flonum?
procedure
(unsafe-flfloor a) → flonum?
a : flonum?
procedure
(unsafe-flceiling a) → flonum?
a : flonum?
procedure
(unsafe-fltruncate a) → flonum?
a : flonum?
flonum에 대해: flround, flfloor, flceiling, fltruncate의 비검사(잠재적으로) 버전이에요. 현재 이 바인딩들은 단순히 대응하는 안전한 바인딩의 별칭이에요.
(unsafe-flsingle a) → flonum?
a : flonum?
flonum에 대해: flsingle의 비검사(잠재적으로) 버전이에요.
base 패키지 7.8.0.7 버전에서 추가되었어요.
(unsafe-flbit-field a start end) → exact-nonnegative-integer?
a : flonum?
start : (integer-in 0 64)
end : (integer-in 0 64)
flonum에 대해: flbit-field의 비검사 버전이에요.
base 패키지 8.15.0.3 버전에서 추가되었어요.
(unsafe-flsin a) → flonum?
a : flonum?
procedure
(unsafe-flcos a) → flonum?
a : flonum?
procedure
(unsafe-fltan a) → flonum?
a : flonum?
procedure
(unsafe-flasin a) → flonum?
a : flonum?
procedure
(unsafe-flacos a) → flonum?
a : flonum?
procedure
(unsafe-flatan a) → flonum?
a : flonum?
procedure
(unsafe-fllog a) → flonum?
a : flonum?
procedure
(unsafe-flexp a) → flonum?
a : flonum?
procedure
(unsafe-flsqrt a) → flonum?
a : flonum?
procedure
(unsafe-flexpt a b) → flonum?
a : flonum?
b : flonum?
flonum에 대해: flsin, flcos, fltan, flasin, flacos, flatan, fllog, flexp, flsqrt, flexpt의 비검사(잠재적으로) 버전이에요. 현재 이 바인딩들 중 일부는 단순히 대응하는 안전한 바인딩의 별칭이에요.
(unsafe-make-flrectangular a b)
→ (and/c complex?
(lambda (c) (flonum? (real-part c)))
(lambda (c) (flonum? (imag-part c))))
a : flonum?
b : flonum?
procedure
(unsafe-flreal-part a)
→ (and/c complex?
(lambda (c) (flonum? (real-part c)))
(lambda (c) (flonum? (imag-part c))))
procedure
(unsafe-flimag-part a)
→ (and/c complex?
(lambda (c) (flonum? (real-part c)))
(lambda (c) (flonum? (imag-part c))))
flonum에 대해: make-flrectangular, flreal-part, flimag-part의 비검사 버전이에요.
(unsafe-fx->fl a) → flonum?
a : fixnum?
procedure
(unsafe-fl->fx a) → fixnum?
a : flonum?
fx->fl과 fl->fx의 비검사 버전이에요.
base 패키지 7.7.0.8 버전에서 변경됨: unsafe-fl->fx가 절삭(truncate)하도록 변경되었어요.
(unsafe-flrandom rand-gen) → (and flonum? (>/c 0) (</c 1))
rand-gen : pseudo-random-generator?
flrandom의 비검사 버전이에요.
Unsafe Character Operations
(unsafe-char=? a b ...) → boolean?
a : char?
b : char?
procedure
(unsafe-char<? a b ...) → boolean?
a : char?
b : char?
procedure
(unsafe-char>? a b ...) → boolean?
a : char?
b : char?
procedure
(unsafe-char<=? a b ...) → boolean?
a : char?
b : char?
procedure
(unsafe-char>=? a b ...) → boolean?
a : char?
b : char?
procedure
(unsafe-char->integer a) → fixnum?
a : char?
char=?, char<?, char>?, char<=?, char>=?, char->integer의 비검사 버전이에요.
base 패키지 7.0.0.14 버전에서 추가되었어요.
Unsafe Compound-Data Operations
(unsafe-car p) → any/c
p : pair?
procedure
(unsafe-cdr p) → any/c
p : pair?
procedure
(unsafe-mcar p) → any/c
p : mpair?
procedure
(unsafe-mcdr p) → any/c
p : mpair?
procedure
(unsafe-set-mcar! p v) → void?
p : mpair?
v : any/c
procedure
(unsafe-set-mcdr! p v) → void?
p : mpair?
v : any/c
car, cdr, mcar, mcdr, set-mcar!, set-mcdr!의 안전하지 않은 변형이에요.
(unsafe-cons-list v rest) → (and/c pair? list?)
v : any/c
rest : list?
rest가 리스트인지 확인하지 않고, 리스트라고 주장하는 페어를 만드는 cons의 안전하지 않은 변형이에요.
(unsafe-list-ref lst pos) → any/c
lst : pair?
pos : (and/c exact-nonnegative-integer? fixnum?)
procedure
(unsafe-list-tail lst pos) → any/c
lst : any/c
pos : (and/c exact-nonnegative-integer? fixnum?)
list-ref와 list-tail의 안전하지 않은 변형으로, pos는 fixnum이어야 하고 lst는 (unsafe-list-ref의 경우) (add1 pos) 또는 (unsafe-list-tail의 경우) pos만큼의 페어로 시작해야 해요.
(unsafe-set-immutable-car! p v) → void?
p : pair?
v : any/c
procedure
(unsafe-set-immutable-cdr! p v) → void?
p : pair?
v : any/c
이 함수들의 어불성설(oxymoronic) 같은 이름이 암시하듯, 이 함수들을 사용하는 일반적으로 올바른 방법은 없어요. 그럼에도 페어가 제한된 방식으로 사용되고 Racket 구현(컴파일러 최적화의 한계 포함)에 대해 올바른 가정을 할 수 있는 설정에서, 마지막 수단으로 유용할 수 있어요.
unsafe-set-immutable-car!와 unsafe-set-immutable-cdr! 사용의 몇 가지 함정:
- 페어를 소비하는 함수는 불변성을 이용할 수 있어요. 예를 들어 리스트의 길이를 한 번 계산하고 그 리스트가 그 길이를 유지할 것으로 기대하거나, 리스트를 계약에 검사한 후 그 계약이 이후에도 성립할 것으로 기대하는 경우가 있죠.
- 페어에 대한
list?의 결과가 내부적으로 캐시될 수 있어서, 페어의cdr를 리스트에서 비리스트로 또는 그 반대로 바꾸면list?가 잘못된 값을 만들어낼 수 있어요 — 변경된 페어에 대해 또는 변경된 페어에 도달하는 다른 페어에 대해요. - 컴파일러는 페어가 불변이라는 근거로
car나cdr호출을 재정렬하거나 심지어 최적화로 제거할 수 있어요. 그 경우unsafe-set-immutable-car!나unsafe-set-immutable-cdr!가car나cdr의 사용에 효과가 없을 수 있어요.
base 패키지 7.9.0.18 버전에서 추가되었어요.
(unsafe-unbox b) → any/c
b : box?
procedure
(unsafe-set-box! b k) → void?
b : box?
k : any/c
procedure
(unsafe-unbox* v) → any/c
v : (and/c box? (not/c impersonator?))
procedure
(unsafe-set-box*! v val) → void?
v : (and/c box? (not/c impersonator?))
val : any/c
unbox와 set-box!의 안전하지 않은 버전으로, box* 변형은 더 빠를 수 있지만 impersonator에서는 동작하지 않아요.
(unsafe-box*-cas! loc old new) → boolean?
loc : box?
old : any/c
new : any/c
box-cas!의 안전하지 않은 버전이에요. unsafe-set-box*!처럼 impersonator에서는 동작하지 않아요.
(unsafe-vector-length v) → fixnum?
v : vector?
procedure
(unsafe-vector-ref v k) → any/c
v : vector?
k : fixnum?
procedure
(unsafe-vector-set! v k val) → void?
v : vector?
k : fixnum?
val : any/c
procedure
(unsafe-vector-copy v [start end]) → vector?
v : vector?
start : fixnum? = 0
end : fixnum? = (vector-length v)
procedure
(unsafe-vector-set/copy v [pos] val) → vector?
v : vector?
pos : fixnum? = 0
val : any/c
procedure
(unsafe-vector-append v ...) → vector?
v : vector?
procedure
(unsafe-vector*-length v) → fixnum?
v : (and/c vector? (not/c impersonator?))
procedure
(unsafe-vector*-ref v k) → any/c
v : (and/c vector? (not/c impersonator?))
k : fixnum?
procedure
(unsafe-vector*-set! v k val) → void?
v : (and/c vector? (not/c impersonator?))
k : fixnum?
val : any/c
procedure
(unsafe-vector*-cas! v k old-val new-val) → boolean?
v : (and/c vector? (not/c impersonator?))
k : fixnum?
old-val : any/c
new-val : any/c
procedure
(unsafe-vector*-copy v [start end]) → vector?
v : vector?
start : fixnum? = 0
end : fixnum? = (vector-length v)
procedure
(unsafe-vector*-set/copy v pos val) → vector?
v : vector?
pos : fixnum?
val : any/c
procedure
(unsafe-vector*-append v ...) → vector?
v : vector?
vector-length, vector-ref, vector-set!, vector-cas!, vector-copy, vector-set/copy, vector-append의 안전하지 않은 버전으로, vector* 변형은 더 빠를 수 있지만 impersonator에서는 동작하지 않아요.
벡터의 크기는 결코 fixnum보다 클 수 없으므로 vector-length조차 항상 fixnum을 돌려줘요.
base 패키지 6.11.0.2 버전에서 변경됨: unsafe-vector*-cas!가 추가되었어요. 8.11.1.9 버전에서 변경됨: unsafe-vector-copy, unsafe-vector*-copy, unsafe-vector-set/copy, unsafe-vector*-set/copy, unsafe-vector-append, unsafe-vector*-append가 추가되었어요.
(unsafe-vector*->immutable-vector! v) → (and/c vector? immutable?)
v : (and/c vector? (not/c impersonator?))
vector->immutable-vector와 비슷하지만 v를 잠재적으로 파괴하고 그 공간을 재사용하므로, unsafe-vector*->immutable-vector!를 호출한 후에는 v를 사용해서는 안 돼요.
base 패키지 7.7.0.6 버전에서 추가되었어요.
(unsafe-string-length str) → fixnum?
str : string?
procedure
(unsafe-string-ref str k) → (and/c char? (lambda (ch) (<= 0 (char->integer ch) 255)))
str : string?
k : fixnum?
procedure
(unsafe-string-set! str k ch) → void?
str : (and/c string? (not/c immutable?))
k : fixnum?
ch : char?
string-length, string-ref, string-set!의 안전하지 않은 버전이에요. unsafe-string-ref 프로시저는 결과가 Latin-1 문자일 때만 사용할 수 있어요. 문자열의 크기는 결코 fixnum보다 클 수 없어요 (string-length조차 항상 fixnum을 돌려줘요).
(unsafe-string->immutable-string! str) → (and/c string? immutable?)
str : string?
string->immutable-string과 비슷하지만 str을 잠재적으로 파괴하고 그 공간을 재사용하므로, unsafe-string->immutable-string!을 호출한 후에는 str을 사용해서는 안 돼요.
base 패키지 7.7.0.6 버전에서 추가되었어요.
(unsafe-bytes-length bstr) → fixnum?
bstr : bytes?
procedure
(unsafe-bytes-ref bstr k) → byte?
bstr : bytes?
k : fixnum?
procedure
(unsafe-bytes-set! bstr k b) → void?
bstr : (and/c bytes? (not/c immutable?))
k : fixnum?
b : byte?
procedure
(unsafe-bytes-copy! dest dest-start src [src-start src-end]) → void?
dest : (and/c bytes? (not/c immutable?))
dest-start : fixnum?
src : bytes?
src-start : fixnum? = 0
src-end : fixnum? = (bytes-length src)
procedure
bytes-length, bytes-ref, bytes-set!, bytes-copy!의 안전하지 않은 버전이에요. bytes의 크기는 결코 fixnum보다 클 수 없어요 (bytes-length조차 항상 fixnum을 돌려줘요).
base 패키지 7.5.0.15 버전에서 변경됨: unsafe-bytes-copy!가 추가되었어요.
(unsafe-bytes->immutable-bytes! bstr) → (and/c bytes? immutable?)
bstr : bytes?
bytes->immutable-bytes와 비슷하지만 bstr을 잠재적으로 파괴하고 그 공간을 재사용하므로, unsafe-bytes->immutable-bytes!를 호출한 후에는 bstr을 사용해서는 안 돼요.
base 패키지 7.7.0.6 버전에서 추가되었어요.
(unsafe-fxvector-length v) → fixnum?
v : fxvector?
procedure
(unsafe-fxvector-ref v k) → fixnum?
v : fxvector?
k : fixnum?
procedure
(unsafe-fxvector-set! v k x) → void?
v : fxvector?
k : fixnum?
x : fixnum?
fxvector-length, fxvector-ref, fxvector-set!의 안전하지 않은 버전이에요. fxvector의 크기는 결코 fixnum보다 클 수 없어요 (fxvector-length조차 항상 fixnum을 돌려줘요).
(unsafe-flvector-length v) → fixnum?
v : flvector?
procedure
(unsafe-flvector-ref v k) → flonum?
v : flvector?
k : fixnum?
procedure
(unsafe-flvector-set! v k x) → void?
v : flvector?
k : fixnum?
x : flonum?
flvector-length, flvector-ref, flvector-set!의 안전하지 않은 버전이에요. flvector의 크기는 결코 fixnum보다 클 수 없어요 (flvector-length조차 항상 fixnum을 돌려줘요).
(unsafe-f64vector-ref vec k) → flonum?
vec : f64vector?
k : fixnum?
procedure
(unsafe-f64vector-set! vec k n) → void?
vec : f64vector?
k : fixnum?
n : flonum?
f64vector-ref와 f64vector-set!의 안전하지 않은 버전이에요.
(unsafe-s16vector-ref vec k) → (integer-in -32768 32767)
vec : s16vector?
k : fixnum?
procedure
(unsafe-s16vector-set! vec k n) → void?
vec : s16vector?
k : fixnum?
n : (integer-in -32768 32767)
s16vector-ref와 s16vector-set!의 안전하지 않은 버전이에요.
(unsafe-u16vector-ref vec k) → (integer-in 0 65535)
vec : u16vector?
k : fixnum?
procedure
(unsafe-u16vector-set! vec k n) → void?
vec : u16vector?
k : fixnum?
n : (integer-in 0 65535)
u16vector-ref와 u16vector-set!의 안전하지 않은 버전이에요.
(unsafe-stencil-vector mask v ...) → stencil-vector?
mask : (integer-in 0 (sub1 (expt 2 (stencil-vector-mask-width))))
v : any/c
procedure
(unsafe-stencil-vector-mask vec) → (integer-in 0 (sub1 (expt 2 (stencil-vector-mask-width))))
vec : stencil-vector?
procedure
(unsafe-stencil-vector-length vec) → (integer-in 0 (sub1 (stencil-vector-mask-width)))
vec : stencil-vector?
procedure
(unsafe-stencil-vector-ref vec pos) → any/c
vec : stencil-vector?
pos : exact-nonnegative-integer?
procedure
(unsafe-stencil-vector-set! vec pos v) → void?
vec : stencil-vector?
pos : exact-nonnegative-integer?
v : any/c
procedure
(unsafe-stencil-vector-update vec remove-mask add-mask v ...) → stencil-vector?
vec : stencil-vector?
remove-mask : (integer-in 0 (sub1 (expt 2 (stencil-vector-mask-width))))
add-mask : (integer-in 0 (sub1 (expt 2 (stencil-vector-mask-width))))
v : any/c
procedure
stencil-vector, stencil-vector-mask, stencil-vector-length, stencil-vector-ref, stencil-vector-set!, stencil-vector-update의 안전하지 않은 변형이에요.
base 패키지 8.5.0.7 버전에서 추가되었어요.
(unsafe-struct-ref v k) → any/c
v : any/c
k : fixnum?
procedure
(unsafe-struct-set! v k val) → void?
v : any/c
k : fixnum?
val : any/c
procedure
(unsafe-struct*-ref v k) → any/c
v : (not/c impersonator?)
k : fixnum?
procedure
(unsafe-struct*-set! v k val) → void?
v : (not/c impersonator?)
k : fixnum?
val : any/c
procedure
(unsafe-struct*-cas! v k old-val new-val) → boolean?
v : (not/c impersonator?)
k : fixnum?
old-val : any/c
new-val : any/c
구조체 타입의 인스턴스에 대한 안전하지 않은 필드 접근과 갱신으로, struct* 변형은 더 빠를 수 있지만 impersonator에서는 동작하지 않아요. 인덱스 k는 0(포함)과 구조체의 필드 수(제외) 사이여야 해요. unsafe-struct-set!, unsafe-struct*-set!, unsafe-struct*-cas!의 경우 필드는 가변이어야 해요. unsafe-struct*-cas! 연산은 원자적 비교-설정을 수행하는 box-cas!와 유사해요.
base 패키지 6.11.0.2 버전에서 변경됨: unsafe-struct*-cas!가 추가되었어요.
(unsafe-struct*-type v) → struct-type?
v : any/c
struct-info와 비슷하지만 인스펙터 검사 없이, 첫 번째 결과만 돌려주고, impersonator를 지원하지 않아요.
base 패키지 8.8.0.3 버전에서 추가되었어요.
해시 테이블 순회를 위한 안전하지 않은 프로시저들(다음 절 참고)은 해시를 반복하는 더 빠른 방법을 제공해요.
(unsafe-mutable-hash-iterate-first hash) → (or/c #f any/c)
hash : (and/c hash? (not/c immutable?) hash-strong?)
procedure
(unsafe-mutable-hash-iterate-next hash pos) → (or/c #f any/c)
hash : (and/c hash? (not/c immutable?) hash-strong?)
pos : any/c
procedure
(unsafe-mutable-hash-iterate-key hash pos) → any/c
hash : (and/c hash? (not/c immutable?) hash-strong?)
pos : any/c
procedure
(unsafe-mutable-hash-iterate-key hash pos bad-index-v) → any/c
hash : (and/c hash? (not/c immutable?) hash-strong?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-mutable-hash-iterate-value hash pos) → any/c
hash : (and/c hash? (not/c immutable?) hash-strong?)
pos : any/c
procedure
(unsafe-mutable-hash-iterate-value hash pos bad-index-v) → any/c
hash : (and/c hash? (not/c immutable?) hash-strong?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-mutable-hash-iterate-key+value hash pos) → any/c any/c
hash : (and/c hash? (not/c immutable?) hash-strong?)
pos : any/c
procedure
(unsafe-mutable-hash-iterate-key+value hash pos bad-index-v)
→ any/c any/c
hash : (and/c hash? (not/c immutable?) hash-strong?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-mutable-hash-iterate-pair hash pos) → pair?
hash : (and/c hash? (not/c immutable?) hash-strong?)
pos : any/c
procedure
(unsafe-mutable-hash-iterate-pair hash pos bad-index-v) → pair?
hash : (and/c hash? (not/c immutable?) hash-strong?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-immutable-hash-iterate-first hash) → (or/c #f any/c)
hash : (and/c hash? immutable?)
procedure
(unsafe-immutable-hash-iterate-next hash pos) → (or/c #f any/c)
hash : (and/c hash? immutable?)
pos : any/c
procedure
(unsafe-immutable-hash-iterate-key hash pos) → any/c
hash : (and/c hash? immutable?)
pos : any/c
procedure
(unsafe-immutable-hash-iterate-key hash pos bad-index-v) → any/c
hash : (and/c hash? immutable?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-immutable-hash-iterate-value hash pos) → any/c
hash : (and/c hash? immutable?)
pos : any/c
procedure
(unsafe-immutable-hash-iterate-value hash pos bad-index-v) → any/c
hash : (and/c hash? immutable?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-immutable-hash-iterate-key+value hash pos) → any/c any/c
hash : (and/c hash? immutable?)
pos : any/c
procedure
(unsafe-immutable-hash-iterate-key+value hash pos bad-index-v) → any/c any/c
hash : (and/c hash? immutable?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-immutable-hash-iterate-pair hash pos) → pair?
hash : (and/c hash? immutable?)
pos : any/c
procedure
(unsafe-immutable-hash-iterate-pair hash pos bad-index-v) → pair?
hash : (and/c hash? immutable?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-weak-hash-iterate-first hash) → (or/c #f any/c)
hash : (and/c hash? hash-weak?)
procedure
(unsafe-weak-hash-iterate-next hash pos) → (or/c #f any/c)
hash : (and/c hash? hash-weak?)
pos : any/c
procedure
(unsafe-weak-hash-iterate-key hash pos) → any/c
hash : (and/c hash? hash-weak?)
pos : any/c
procedure
(unsafe-weak-hash-iterate-key hash pos bad-index-v) → any/c
hash : (and/c hash? hash-weak?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-weak-hash-iterate-value hash pos) → any/c
hash : (and/c hash? hash-weak?)
pos : any/c
procedure
(unsafe-weak-hash-iterate-value hash pos bad-index-v) → any/c
hash : (and/c hash? hash-weak?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-weak-hash-iterate-key+value hash pos) → any/c any/c
hash : (and/c hash? hash-weak?)
pos : any/c
procedure
(unsafe-weak-hash-iterate-key+value hash pos bad-index-v) → any/c any/c
hash : (and/c hash? hash-weak?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-weak-hash-iterate-pair hash pos) → pair?
hash : (and/c hash? hash-weak?)
pos : any/c
procedure
(unsafe-weak-hash-iterate-pair hash pos bad-index-v) → pair?
hash : (and/c hash? hash-weak?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-ephemeron-hash-iterate-first hash) → (or/c #f any/c)
hash : (and/c hash? hash-ephemeron?)
procedure
(unsafe-ephemeron-hash-iterate-next hash pos) → (or/c #f any/c)
hash : (and/c hash? hash-ephemeron?)
pos : any/c
procedure
(unsafe-ephemeron-hash-iterate-key hash pos) → any/c
hash : (and/c hash? hash-ephemeron?)
pos : any/c
procedure
(unsafe-ephemeron-hash-iterate-key hash pos bad-index-v) → any/c
hash : (and/c hash? hash-ephemeron?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-ephemeron-hash-iterate-value hash pos) → any/c
hash : (and/c hash? hash-ephemeron?)
pos : any/c
procedure
(unsafe-ephemeron-hash-iterate-value hash pos bad-index-v) → any/c
hash : (and/c hash? hash-ephemeron?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-ephemeron-hash-iterate-key+value hash pos) → any/c any/c
hash : (and/c hash? hash-ephemeron?)
pos : any/c
procedure
(unsafe-ephemeron-hash-iterate-key+value hash pos bad-index-v) → any/c any/c
hash : (and/c hash? hash-ephemeron?)
pos : any/c
bad-index-v : any/c
procedure
(unsafe-ephemeron-hash-iterate-pair hash pos) → pair?
hash : (and/c hash? hash-ephemeron?)
pos : any/c
procedure
(unsafe-ephemeron-hash-iterate-pair hash pos bad-index-v) → pair?
hash : (and/c hash? hash-ephemeron?)
pos : any/c
bad-index-v : any/c
procedure
hash-iterate-key 및 유사 프로시저들의 안전하지 않은 버전이에요. 이 연산들은 chaperone과 impersonator를 지원해요.
각 unsafe ...-first와 ...-next 프로시저는 숫자 인덱스 대신 해시 구조에 대한 뷰의 내부 표현을 돌려줄 수 있어 더 빠른 순회를 가능하게 해요. 이 ...-first와 ...-next 함수들의 결과는 해당 안전하지 않은 접근자 함수들에 pos로 주어져야 해요.
가변 해시에 대한 접근자 함수에 제공된 pos가 이전에는 유효한 해시 인덱스였지만 더 이상 hash에 대한 유효한 해시 인덱스가 아니고, bad-index-v가 제공되지 않았다면 exn:fail:contract 예외가 일어나요. hash에 대해 유효한 해시 인덱스였던 적이 없는 pos에 대해서는 어떤 동작도 지정되지 않아요. unsafe-immutable-hash-iterate- 함수들에 대해 bad-index-v 인자는 기술적으로 쓸모가 없는데, 불변 해시에서는 인덱스가 무효가 될 수 없기 때문이에요.
base 패키지 6.4.0.6 버전에서 추가되었어요. 7.0.0.10 버전에서 변경됨: 선택적 bad-index-v 인자가 추가되었어요. 8.0.0.10 버전에서 변경됨: ephemeron 변형이 추가되었어요.
(unsafe-make-srcloc source line column position span) → srcloc?
source : any/c
line : (or/c exact-positive-integer? #f)
column : (or/c exact-nonnegative-integer? #f)
position : (or/c exact-positive-integer? #f)
span : (or/c exact-nonnegative-integer? #f)
procedure
srcloc의 안전하지 않은 버전이에요.
base 패키지 7.2.0.10 버전에서 추가되었어요.
Unsafe Extflonum Operations
(unsafe-extfl+ a b) → extflonum?
a : extflonum?
b : extflonum?
procedure
(unsafe-extfl- a b) → extflonum?
a : extflonum?
b : extflonum?
procedure
(unsafe-extfl* a b) → extflonum?
a : extflonum?
b : extflonum?
procedure
(unsafe-extfl/ a b) → extflonum?
a : extflonum?
b : extflonum?
procedure
(unsafe-extflabs a) → extflonum?
a : extflonum?
extfl+, extfl-, extfl*, extfl/, extflabs의 비검사 버전이에요.
(unsafe-extfl= a b) → boolean?
a : extflonum?
b : extflonum?
procedure
(unsafe-extfl< a b) → boolean?
a : extflonum?
b : extflonum?
procedure
(unsafe-extfl> a b) → boolean?
a : extflonum?
b : extflonum?
procedure
(unsafe-extfl<= a b) → boolean?
a : extflonum?
b : extflonum?
procedure
(unsafe-extfl>= a b) → boolean?
a : extflonum?
b : extflonum?
procedure
(unsafe-extflmin a b) → extflonum?
a : extflonum?
b : extflonum?
procedure
(unsafe-extflmax a b) → extflonum?
a : extflonum?
b : extflonum?
extfl=, extfl<, extfl>, extfl<=, extfl>=, extflmin, extflmax의 비검사 버전이에요.
(unsafe-extflround a) → extflonum?
a : extflonum?
procedure
(unsafe-extflfloor a) → extflonum?
a : extflonum?
procedure
(unsafe-extflceiling a) → extflonum?
a : extflonum?
procedure
(unsafe-extfltruncate a) → extflonum?
a : extflonum?
extflround, extflfloor, extflceiling, extfltruncate의 비검사(잠재적으로) 버전이에요. 현재 이 바인딩들은 단순히 대응하는 안전한 바인딩의 별칭이에요.
(unsafe-extflsin a) → extflonum?
a : extflonum?
procedure
(unsafe-extflcos a) → extflonum?
a : extflonum?
procedure
(unsafe-extfltan a) → extflonum?
a : extflonum?
procedure
(unsafe-extflasin a) → extflonum?
a : extflonum?
procedure
(unsafe-extflacos a) → extflonum?
a : extflonum?
procedure
(unsafe-extflatan a) → extflonum?
a : extflonum?
procedure
(unsafe-extfllog a) → extflonum?
a : extflonum?
procedure
(unsafe-extflexp a) → extflonum?
a : extflonum?
procedure
(unsafe-extflsqrt a) → extflonum?
a : extflonum?
procedure
(unsafe-extflexpt a b) → extflonum?
a : extflonum?
b : extflonum?
extflsin, extflcos, extfltan, extflasin, extflacos, extflatan, extfllog, extflexp, extflsqrt, extflexpt의 비검사(잠재적으로) 버전이에요. 현재 이 바인딩들 중 일부는 단순히 대응하는 안전한 바인딩의 별칭이에요.
(unsafe-fx->extfl a) → extflonum?
a : fixnum?
procedure
(unsafe-extfl->fx a) → fixnum?
a : extflonum?
fx->extfl과 extfl->fx의 비검사(잠재적으로) 버전이에요.
base 패키지 7.7.0.8 버전에서 변경됨: unsafe-fl->fx가 절삭하도록 변경되었어요.
(unsafe-extflvector-length v) → fixnum?
v : extflvector?
procedure
(unsafe-extflvector-ref v k) → extflonum?
v : extflvector?
k : fixnum?
procedure
(unsafe-extflvector-set! v k x) → void?
v : extflvector?
k : fixnum?
x : extflonum?
extflvector-length, extflvector-ref, extflvector-set!의 비검사 버전이에요. extflvector의 크기는 결코 fixnum보다 클 수 없어요 (extflvector-length조차 항상 fixnum을 돌려줘요).
Unsafe Impersonators and Chaperones
(unsafe-impersonate-procedure proc replacement-proc prop prop-val ... ...)
→ (and/c procedure? impersonator?)
proc : procedure?
replacement-proc : procedure?
prop : impersonator-property?
prop-val : any
procedure
impersonate-procedure와 같지만 replacement-proc가 proc 자신을 호출한다고 가정해요. unsafe-impersonate-procedure의 결과가 인자들에 적용될 때, 인자들은 proc을 무시하고 replacement-proc에 직접 전달돼요. 동시에 impersonator-of?는 unsafe-impersonate-procedure의 결과와 proc에 주어졌을 때 #t를 보고해요.
proc 자신이 impersonate-procedure*나 chaperone-procedure*에서 파생된 impersonator라면 replacement-proc가 그것을 올바르게 호출할 수 없을 것임을 조심하세요. 구체적으로 unsafe-impersonate-procedure가 만든 impersonator는 proc을 생성하기 위해 impersonate-procedure*나 chaperone-procedure*에 제공된 래퍼 프로시저에 전달되지 않을 거예요.
마지막으로 impersonate-procedure와 달리 unsafe-impersonate-procedure는 impersonator-prop:application-mark을 prop으로 특별히 처리하지 않아요.
unsafe-impersonate-procedure의 안전하지 않음은 위의 impersonate-procedure와의 차이로 제한돼요. unsafe-impersonate-procedure의 인자에 대한 계약은 인자가 제공될 때 검사돼요.
예를 들어 f가 단일 인자를 받아들이고 impersonate-procedure*나 chaperone-procedure*에서 파생되지 않았다고 가정하면,
(λ (f)
(unsafe-impersonate-procedure
f
(λ (x)
(if (number? x)
(error 'no-numbers!)
(f x)))))
은
(λ (f)
(impersonate-procedure
f
(λ (x)
(if (number? x)
(error 'no-numbers!)
x))))
와 동등해요.
마찬가지로 f에 대한 같은 가정에서, 다음 두 프로시저 wrap-f1과 wrap-f2는 거의 동등해요. 그것들은 인자가 여러 값을 돌려주는 함수일 때 만들어지는 오류 메시지에서만 (그리고 다른 전역 변수를 갱신한다는 점에서만) 다르지요. unsafe-impersonate-procedure를 사용하는 버전은 let 표현식에서 여러 반환 값에 관한 오류를 신호하고, impersonate-procedure를 사용하는 버전은 impersonate-procedure에서 여러 반환 값에 관한 오류를 신호해요.
(define log1-args '())
(define log1-results '())
(define wrap-f1
(λ (f)
(impersonate-procedure
f
(λ (arg)
(set! log1-args (cons arg log1-args))
(values (λ (res)
(set! log1-results (cons res log1-results))
res)
arg)))))
(define log2-args '())
(define log2-results '())
(define wrap-f2
(λ (f)
(unsafe-impersonate-procedure
f
(λ (arg)
(set! log2-args (cons arg log2-args))
(let ([res (f arg)])
(set! log2-results (cons res log2-results))
res)))))
base 패키지 6.4.0.4 버전에서 추가되었어요.
(unsafe-chaperone-procedure proc wrapper-proc prop prop-val ... ...)
→ (and/c procedure? chaperone?)
proc : procedure?
wrapper-proc : procedure?
prop : impersonator-property?
prop-val : any
procedure
unsafe-impersonate-procedure와 같지만 chaperone을 만들어요. wrapper-proc가 proc 대신 호출되므로, wrapper-proc는 proc이 돌려줄 값의 chaperone을 돌려준다고 가정해요.
base 패키지 6.4.0.4 버전에서 추가되었어요.
(unsafe-impersonate-vector vec replacement-vec prop prop-val ... ...)
→ (and/c vector? impersonator?)
vec : vector?
replacement-vec : (and/c vector? (not/c impersonator?))
prop : impersonator-property?
prop-val : any/c
procedure
impersonate-vector와 같지만 중재(interposition) 프로시저를 통하지 않고, impersonator에 대한 모든 접근이 replacement-vec으로 디스패치돼요.
unsafe-impersonate-vector의 결과는 vec의 impersonator예요.
base 패키지 6.9.0.2 버전에서 추가되었어요.
(unsafe-chaperone-vector vec replacement-vec prop prop-val ... ...)
→ (and/c vector? chaperone?)
vec : vector?
replacement-vec : (and/c vector? (not/c impersonator?))
prop : impersonator-property?
prop-val : any/c
procedure
unsafe-impersonate-vector와 같지만 unsafe-chaperone-vector의 결과는 vec의 chaperone이에요.
base 패키지 6.9.0.2 버전에서 추가되었어요.
Unsafe Assertions
(unsafe-assert-unreachable) → none/c
assert-unreachable과 같지만 unsafe-assert-unreachable의 계약은 결코 만족되지 않으며, "unsafe"가 암시하는 바는 unsafe-assert-unreachable에 대한 호출에 도달하면 무엇이든 일어날 수 있다는 것이에요.
컴파일러는 unsafe-assert-unreachable에 대한 호출 대신 편리하거나 효율적인 동작을 선택하는 자유를 이용할 수 있어요. 예를 들어 표현식
(lambda (x)
(if (pair? x)
(car x)
(unsafe-assert-unreachable)))
은 (unsafe-assert-unreachable)이 (unsafe-car x)와 똑같이 동작하도록 선택하면 if의 두 분기가 같아지고 pair? 검사를 제거할 수 있으므로,
(lambda (x) (unsafe-car x))
과 동등한 코드로 컴파일될 수 있어요.
base 패키지 8.0.0.11 버전에서 추가되었어요.
Unsafe Structure Type Properties
이 절에 문서화된 바인딩들은 racket/unsafe/struct-type-property 라이브러리가 제공하며, racket/base나 racket이 제공하는 게 아니에요.
(require racket/unsafe/struct-type-property) ; package: base
(unsafe-make-struct-type-property/guard-calls-no-arguments
name
[guard supers can-impersonate? accessor-name contract-str realm])
→ struct-type-property?
(any/c . -> . boolean?)
procedure?
name : symbol?
guard : (or/c procedure? #f 'can-impersonate) = #f
supers : (listof (cons/c struct-type-property? (any/c . -> . any/c))) = null
can-impersonate? : any/c = #f
accessor-name : (or/c symbol? #f) = #f
contract-str : (or/c string? symbol? #f) = #f
realm : symbol? = 'racket
procedure
make-struct-type-property와 같지만, guard가 그것의 property-value 인자에 포함된 어떤 프로시저도 호출하지 않는다고 단언해요. 마찬가지로 supers의 어떤 프로시저도 포함된 프로시저를 호출하지 않고, supers의 속성들은 포함된 프로시저를 호출하는 guard나 변환을 가지지 않아요.
주어진 프로시저들이 속성의 guard에 의해 호출되지 않는다고 단언하는 것은 검사를 줄이고 그 속성을 사용하는 구조체 타입에 대한 연산의 최적화를 개선할 수 있어요. 구체적으로 unsafe-make-struct-type-property/guard-calls-no-arguments가 만든 속성이 구조체 타입 선언에서 사용되고, 속성에 주어진 값이 구조체 타입 선언의 바인딩을 다시 참조하는 프로시저를 포함할 때(메서드 같은 속성의 일반적인 패턴), 컴파일러는 속성 값에서 참조되는 정의된 이름이 너무 일찍 참조될 수 없다는 결론을 더 쉽게 내릴 수 있어요.
base 패키지 8.18.0.18 버전에서 추가되었어요.
Unsafe Undefined
이 절에 문서화된 바인딩들은 racket/unsafe/undefined 라이브러리가 제공하며, racket/base나 racket이 제공하는 게 아니에요.
(require racket/unsafe/undefined) ; package: base
unsafe-undefined 상수는 내부적으로 자리표시자 값으로 사용돼요. 예를 들어 letrec이 아직 값이 할당되지 않은 변수의 값으로 사용해요. 그러나 racket/undefined가 내보내는 undefined 값과 달리 unsafe-undefined 값은 안전한 표현식의 결과로 누출되어서는 안 되고, 프로시저에 선택적 인자로 전달되어서도 안 돼요 (그 이유는 "제공된 값 없음"으로 간주될 수 있기 때문이에요). unsafe-undefined를 잠재적으로 만들어내는 표현식 결과는 check-not-unsafe-undefined로 감시할 수 있어, 정의되지 않은 값을 만드는 대신 예외가 일어나게 할 수 있어요.
unsafe-undefined 값은 항상 자기 자신과 eq? 해요.
base 패키지 6.0.1.2 버전에서 추가되었어요. 6.90.0.29 버전에서 변경됨: 선택적 인자가 있는 프로시저가 때때로 "인자가 제공되지 않음"을 의미하기 위해 내부적으로 unsafe-undefined 값을 사용해요.
unsafe-undefined : any/c
value
안전하지 않은 "정의되지 않음" 상수.
unsafe-undefined 사용에 대한 중요한 제약은 위를 참고하세요.
(check-not-unsafe-undefined v sym) → any/c
v : any/c
sym : symbol?
procedure
v가 unsafe-undefined인지 검사하고, 그 경우 "sym: undefined; use before initialization"("초기화 전에 사용") 같은 줄의 오류 메시지와 함께 exn:fail:contract:variable을 일으켜요. v가 unsafe-undefined가 아니면 v가 돌려져요.
(check-not-unsafe-undefined/assign v sym) → any/c
v : any/c
sym : symbol?
procedure
check-not-unsafe-undefined와 같지만, 오류 메시지(있다면)가 "sym: undefined; assignment before initialization"("초기화 전에 할당") 같은 줄이에요.
(chaperone-struct-unsafe-undefined v) → any/c
v : any/c
procedure
v가 (어떤 인스펙터를 통해 본) 구조체이면 그것을 chaperone 해요. 구조체의 필드에 대한 모든 접근은 unsafe-undefined를 돌려주지 않도록 검사돼요. 마찬가지로 구조체의 필드에 대한 모든 할당은 (아래 설명처럼 검사가 비활성화되지 않는 한) 현재 값이 unsafe-undefined인 필드의 할당을 막도록 검사돼요.
필드 접근이 unsafe-undefined를 만들어낼 때나 필드 할당이 unsafe-undefined를 교체할 때 exn:fail:contract 예외가 일어나요.
chaperone의 필드 할당 검사는 (continuation-mark-set-first #f prop:chaperone-unsafe-undefined)이 unsafe-undefined를 돌려줄 때마다 비활성화돼요. 따라서 필드 초기화 할당 — 필드의 unsafe-undefined 값을 교체하려는 할당 — 은 (with-continuation-mark prop:chaperone-unsafe-undefined unsafe-undefined ....)으로 감싸야 해요.
prop:chaperone-unsafe-undefined : struct-type-property?
value
구조체 타입의 생성자가 chaperone-struct-unsafe-undefined와 같은 방식으로 인스턴스의 chaperone을 만들게 하는 구조체 타입 속성이에요.
속성 값은 필드 이름으로 사용되는 심볼들의 리스트여야 하지만, 그 리스트는 구조체의 필드들의 역순이어야 해요. 필드 접근이나 할당이 unsafe-undefined를 만들어내거나 교체할 때, 구조체 속성의 값이 필드 이름을 제공하면 exn:fail:contract:variable 예외가 일어나고, 그렇지 않으면 exn:fail:contract 예외가 일어나요.