박스
박스 (Boxes)
박스(box)는 값 하나를 담는 가변(mutable) 저장소로, 함수형 언어에서 상태를 흉내 낼 때 자주 쓰는 작은 도구예요. Racket의 박스는 수정 가능한 것과 불변(immutable)인 것이 따로 있어요.
출처: Racket Reference
본문
4.14 박스
The Racket Guide의 박스 문서에서 박스를 소개하고 있어요.
박스는 원소 하나짜리 벡터와 비슷하며, 보통 최소한의 가변 저장소로 사용됩니다.
박스는 가변(mutable)일 수도 있고 불변(immutable)일 수도 있습니다. 불변 박스를 set-box! 같은 프로시저에 넘기면 exn:fail:contract 예외가 발생합니다. 기본 리더가 만들어 내는 박스 상수(문자열 읽기 참고)는 불변입니다. 박스가 불변인지 확인하려면 immutable?을 쓰세요.
리터럴로 쓰이거나 출력되는 박스는 #&로 시작합니다. 박스 읽기에 대해서는 Reading Boxes, 박스 출력에 대해서는 Printing Boxes를 참고하세요.
box?
(box? v) → boolean?
v : any/c
v가 박스이면 #t를, 그렇지 않으면 #f를 반환합니다. immutable-box?와 mutable-box?도 참고하세요.
box
(box v) → box?
v : any/c
v를 담은 새 가변 박스를 반환합니다.
box-immutable
(box-immutable v) → (and/c box? immutable?)
v : any/c
v를 담은 새 불변 박스를 반환합니다.
unbox
(unbox box) → any/c
box : box?
box의 내용을 반환합니다. 임의의 v에 대해 (unbox (box v))와 (unbox (box-immutable v))는 v를 반환합니다.
set-box!
(set-box! box v) → void?
box : (and/c box? (not/c immutable?))
v : any/c
box의 내용을 v로 설정합니다.
unbox*, set-box*!
(unbox* box) → any/c
box : (and box? (not/c impersonator?))
(set-box*! box v) → void?
box : (and/c box? (not/c immutable?) (not/c impersonator?))
v : any/c
unbox와 set-box!와 같지만, 임퍼서네이터(impersonator)가 아닌 박스에만 작동하도록 제한됩니다.
Added in version 6.90.0.15 of package base.
box-cas!
(box-cas! box old new) → boolean?
box : (and/c box? (not/c immutable?) (not/c impersonator?))
old : any/c
new : any/c
box가 현재 old와 eq?인 값을 담고 있을 때, 그 내용을 원자적으로(atomically) new로 갱신하고 #t를 반환합니다. box가 old를 담고 있지 않으면 결과는 #f입니다.
다른 스레드나 퓨처가 box에 접근하려 하지 않는다면, 이 연산은
(and (eq? old (unbox box)) (set-box! box new) #t)
와 같습니다. 다만 일부 플랫폼에서는 box-cas!가 드물게 실패할 수 있어요. 즉, box가 old를 담고 있어도 낮은 확률로 결과가 #f가 되고 box의 값은 그대로 남을 수 있습니다.
Racket이 퓨처(futures)를 지원하도록 컴파일된 경우, box-cas!는 하드웨어 비교-및-설정(compare and set) 연산을 사용함이 보장됩니다. box-cas!의 사용은 퓨처 안에서 안전하게 수행될 수 있어요 (즉, 퓨처 thunk가 병렬로 계속 진행되도록 허용). Machine Memory Order도 참고하세요.