두 개념이 하나였을 때: region과 arena
다섯 전략의 설계 공간에는 'arena'와 'region'이 모두 있었고, 의심스러울 만큼 닮아 있었다. 살펴보니 그것들은 같은 아이디어를 두 이름으로 부른 것일 뿐, 부수적인 기능으로 치장되어 있었다. 하나의 개념으로 접는 결정과, 거짓 구별을 일찍 제거하는 것이 왜 하류 전체를 정합적으로 유지하는가.
지난 회는 의심으로 끝났다: 설계 공간에는 arena 와 region 이 모두 있었고, 지나치게 닮아 있었다. 이번 회는 그 의심을 결론까지 따라가는 이야기다 —— 그것들은 하나의 개념이 두 이름을 걸치고 있었으며, 한쪽만 남기기로 정했다.
두 기술(記述), 하나의 아이디어
나란히 적어 보면, 둘은 같은 기계를 그리고 있었다.
arena: 범프 포인터 할당, 개별 해제 없음, arena를 파기할 때 한꺼번에 해제. 한 arena 안의 상호 참조는 자유롭고, 그것이 그래프에 강하다. 그리고 정리가 필요 없는 타입만 들어갈 수 있다.
region: 프로그램 구조에 묶인 메모리 영역, 블록에 스코프되고, 중첩 가능하며, 블록을 벗어나면 한꺼번에 해제.
이것들을 나란히 두면 “차이”는 증발한다. 범프 할당, 개별로 해제하지 않음, 스코프 탈출 시 영역째 해제, 내부에서는 자유롭게 공유 는 Tofte–Talpin 의미에서의 region 의 교과서적 기술이다 —— ML 계열 언어가 빌려 온, 잘 연구된 region 계산. 기술된 그대로의 arena는, 다른 이름 아래의 같은 계산이었다.
겉보기의 구별은 부수적이었지, 본질적이지 않았다:
- 중첩은 region에는 적혀 있고 arena에는 그저 언급되지 않았을 뿐 —— 금지된 게 아니라, 적히지 않았다.
- “정리가 필요 없는 타입만 들어간다”는 제약은 arena에는 명기되고 region에는 암묵적 이었다 —— 하지만 region도, 똑같은 이유로, 똑같은 규칙을 필요로 한다.
- 저마다 조금 다른 구문을 주웠고, 그것이 두 이름을 두 가지로 느끼게 했다.
그 어느 것도, 기능이 무엇인가 에서의 진짜 차이가 아니다. 다른 시기에 쓰여서 벌어진, 하나의 아이디어의 두 스케치였다.
결정: 하나의 개념, 이름은 region
그래서 둘은 하나의 기능으로 접혔고, 유용한 부분의 합집합을 지켰다: 스코프되고 중첩 가능한 영역, 포인터를 밀어 할당, 블록 종료 시 한꺼번에 해제, 내부의 상호 참조는 자유 —— 그리고 거기에 무엇이 살 수 있는가의 한 규칙(다음 회의 주제). 쓰는 법은 소박하다:
region r {
// r에 할당한다. 여기의 모든 것은 블록 종료 시 해제된다
}
남긴 이름은 arena가 아니라 region 이다. 하나는, 설계가 딛고 선 확립된 이론을 가리키기 때문. 또 하나는 —— 명명을 다루는 뒤의 회에서 짚겠지만 —— “region” 이 언어 자신의 정체성에서 힘을 쓰기 때문이다.
왜 일찍 접는가
이것은 정리처럼 보이지만, 메모리 모델 전체에서 가장 지렛대가 큰 결정 중 하나였다. 설계 노트가 솔직하게 적어 둔 이유가 있다: 다른 거의 모든 메모리 결정이 이 하나에 의존한다. 뷰 타입, region 대응 표준 컬렉션, 정리가 실행되는 순서 —— 그것들은 모두 “region은 어떻게 행동하는가?“에 대한 논의다. 만약 겹치는 두 개념이 남아 있었다면, 그 논의들은 모두 두 번, 개념마다 하고, 영원히 동기화해야 한다. 거짓 구별은 공짜가 아니다. 모든 미래의 결정에 부과되는 세금이다.
먼저 접은 덕에, Part II의 나머지는 하나의 것에 대해 추론할 수 있었다.
언어의 제1원칙으로 곧장 돌아가는 선도 있다. Mere는 읽고 확신할 수 있는 프로그램을 최적화한다 —— 그리고 하나의 아이디어에 두 이름이 있는 것은 그것에 정면으로 반한다. 독자는 차이를 배우고(없다), 어느 것을 쓸지 정하고(상관없다), 둘 다 머리에 담아야 한다 (낭비). 각자가 정확히 하나를 뜻하는, 더 적은 개념 은, 명시적 타입·명시적 이펙트와 같은 목표를, 언어 자신의 어휘에 적용한 것이다. 여기서의 단순함은 미학이 아니다. 검증 가능성이다.
이것이 연 것
하나의 region으로의 통합은, 둘이 있던 동안 흐릿했던 물음들을 곧바로 날카롭게 했다:
- region에는 실제로 무엇이 살 수 있는가? 범프 할당과 일괄 해제가 통하는 것은,
진짜 정리가 필요 없는 값뿐이다. 파일 핸들이나 소켓을 가진 값은, 포인터를 리셋하는
것만으로는 해제할 수 없다. 그 제약에는 이름이 있다 ——
Trivial—— 그리고 정리가 정말로 필요한 값을 위한 별도의 이야기가 다음 회다. - region 으로의 참조란 무엇을 뜻하며, 그것이 region보다 오래 사는 것을 어떻게 막는가? 그것은 몇 회 뒤에, 독립된 작은 이론이 된다.
하나의 개념, 날카로운 모서리. 다음 회: Trivial, 그리고 region이 일부러 넣을 수 없는
값을 Mere가 어떻게 다루는가.