언제 필요한가요?
바인딩은 결과에 이름을 붙일 때, 로컬 스코프를 만들 때, 호출과 호출 사이의 상태를 일부러 남겨 둘 때 씁니다. 대부분의 코드는 define과 let이면 충분합니다. set!은 공유 변경이 모델의 일부일 때만 꺼내세요.
실행으로 확인하기
LISPEX
(define x 1)
(define get (lambda () x))
(set! x 2)
(get)관측 결과
OUTPUT
2예제 읽기
get이 들고 있는 것은 숫자 1을 복사해 얼려 둔 값이 아닙니다. 이 프로시저는 x라는 이름의 전역 셀을 닫아 둡니다. set!이 바로 그 셀에 2를 쓰므로 뒤이은 호출은 2를 봅니다. 안쪽에 새 x를 만들었다면 기존 셀을 바꾸지 않고 가리기만 합니다.
이 순서로 생각하세요
- 조회는 가장 가까운 어휘 셀을 고릅니다. 섀도잉은 바깥 바인딩을 바꾸지 않습니다.
letrec은 초기식보다 먼저 셀을 할당합니다. 아직 초기화되지 않은 셀을 읽으면 E321이 납니다.- 최상위에서
define을 다시 쓰면 기존 전역 셀을 갱신합니다. 그래서 앞서 만든 클로저의 참조가 그대로 살아 있습니다.
빠르게 고르기
| 형식 | 쓸 때 | 초기식이 보는 범위 |
|---|---|---|
define | 최상위 이름이나 이름 있는 프로시저 | 현재 최상위 환경 |
let | 서로 독립인 로컬 값 | 바깥 환경 |
let* | 앞선 로컬에 의존하는 로컬 | 앞서 만든 각 바인딩 |
letrec | 서로 재귀하는 로컬 프로시저 | 먼저 할당된 모든 셀, 이른 읽기는 실패 |
set! | 기존 셀 갱신 | 새 바인딩을 만들지 않음 |
흔한 오해
바인딩되지 않은 이름에 set!을 쓰면 E303입니다. 이때 새 바인딩이 만들어지는 일은 없습니다.
현재 경계
- 내부 미초기화 센티널은 게스트 값으로 나타낼 수 없습니다.
다음으로
클로저가 이 셀을 어떻게 캡처하는지는 프로시저에서 이어집니다. 같은 규칙을 작은 상태 예제로 보려면 클로저 가이드를 여세요.