다음에 오는 것: 지도의 가장자리
이것은 끝이 아니라, 한 매듭이다. 시스템은 세워졌다 —— 메모리 모델, 이펙트, 네 backend, 셀프 호스트 컴파일러, 안전한 병행 처리 —— 그리고 남는 것은 지도의 가장자리다: 이펙트를 통한 async, work-stealing 스케줄러, 미룬 atomic, 특징적인 분석의 셀프 호스팅. 그 어느 것도 스케줄 위에 없다. 저마다, 지도로 끌어들이는 이름 붙여진 조건이다. 언어는 소망 목록이 아니라, 수요로 자라기에.
일곱 Part가, Mere를 언어로 만드는 시스템을 세웠다: 사상과 최소 코어, 명시적 메모리 모델, 이펙트 시스템, 엄밀한 일치에 유지된 네 backend로의 코드 생성, 언어 자신으로 쓰이고 브라우저에서 도는 컴파일러, 공적인 존재, 그리고 타입 안전한 병행 처리. 그것은 하나의 완결된 것이다. 하지만, 끝난 것은 아니다 —— 살아 있는 언어는 결코 끝나지 않는다 —— 그래서 이 마지막 회는 끝이 아니라, 한 매듭이다. 지도의 현재 가장자리에서 취해져, 그 조금 너머에 있는 것을 바라본다.
지평은 약속이 아니라, 조건의 목록이다
이런 연재를 닫는 자연스러운 방식은 로드맵일 것이다: 다음에 무엇을 세울까. 하지만 연재 전체가 돌아온 규율이 그것에 반한다. feature는 스케줄에 맞춰 세워진 적이 없다; 저마다, 실의 현재 수요가 그것을 가리켰을 때 세워지고, 수요가 추측일 뿐일 때는 미뤄졌다 —— 때로 길게, 때로 재어진 영수증과 함께. 그래서 “다음에 오는 것”의 정직한 형태는, 약속의 목록이 아니라 조건의 목록이다: 지도의 가장자리에 있는 것, 그 저마다가, 세워진 세계로 끌어들이는 이름 붙여진 트리거를 가진다. 이하가 그 목록이다, 그 정신으로.
이펙트를 통한 async
Part III의 이펙트 시스템은 능력 전달 위에 세워졌고, 문을 열어 둔다: 비동기 실행은 이펙트로 표현될 수 있고, 프로그램이 고르는 곳에서 handle되며, 언어가 나머지 부작용에 이미 쓰는 것과 같은 어휘로. 종이 위에서는 매력적인 들어맞음이다. 하지만 병행 처리 Part가 이미 가까운 미래의 수요를 처리했다 —— 그것을 시작한 pain point, 하나의 프로세스의 두 loop는, 진짜 스레드로 풀리고, I/O 병행은 호스트에서 이미 다뤄졌다. 그래서 async-via-effects는, 아직 갖지 않은 수요를 기다린다: 구조화 병행, 취소, 스레드와 채널이 어색하게 봉사하는 형태. 트리거는, 그것들을 genuine하게 요하고 현재의 primitive가 너무 거칠다고 알아채는 프로그램이다 —— 그리고 그것이 나타났을 때, 이펙트가 답을 세울 자연스러운 곳이다, 밑작업이 세 Part 전에 깔렸기에.
work-stealing 스케줄러
오늘 spawn은 하나의 OS 스레드이고, 그것은 거친 병렬성 —— par_map 너머의 한 줌의 worker —— 에는
꼭 옳고, 아주 많은 작은 태스크 —— 스레드의 비용이 그것이 하는 일을 삼키는 —— 에는 꼭 그르다.
표준의 답은 work-stealing 스케줄러다: 작은 스레드 풀이 세밀한 태스크를 서로 넘긴다. 그것은 지평의
항목 중 가장 크고, 다른 것보다 긴 길이며, 그 트리거는 특정적이다: 현재의 모델이 이미 잘 봉사하는
거친 데이터 병렬이 아니라, 많은 작은 병렬 태스크의 실의 워크로드. 프로그램이 그 형태를 원할 때까지,
더 단순한 모델은 플레이스홀더가 아니다 —— 사람이 실제로 쓰고 있는 병렬성에 옳은 도구다.
미뤄진 것, 그 영수증과 함께
몇몇은 연재의 앞쪽에서 조건을 써 내려 미뤄졌고, 철된 그대로 지평에 앉는다. 지난 회의 atomic과 락은, branch-and-bound나 적응 탐색이 실의 타깃이 되는 것을 기다린다, API와 example은 이미 초안되어. 일반적인 제약 기구 —— qualified types —— 는, 타입을 넘어 재사용되는 다형 채널 콤비네이터를 genuine 하게 요하는 프로그램을 기다린다. 패키지 매니저는, 그것을 요할 만큼 큰 adoption을 기다린다. 특징적인 분석의 셀프 호스팅 —— 대여 검사기, region, 이펙트 시스템, Mere를 일반적인 ML이 아니라 Mere 자신으로 만드는 것 —— 은, 오늘 셀프 호스트된 고전적 코어의 뒤에서 차례를 기다린다. 그리고 언어로서의 고유한 인식, 그 자신의 구문 하이라이트와 등록은, 그것을 버는 사용을 기다린다. 그 저마다가, 누락이 아니라, 트리거 붙은 미뤄진 물음이다.
변하지 않는 것
feature가 변수라면, 일곱 Part를 통해 일정하게 있어 온 무언가가 있고, 그것은 가장 앞으로 가지고 갈
가치가 있는 부분이다. 결정이 이뤄지는 방식은 변하지 않았다: 어려운 물음은 종이 위에서 정밀한 하위
물음으로 좁혀지고, 커밋되기 전에 작은 실험에서 시도되고, 그다음 rough edges가 나타날 때까지 진짜에
대해 dogfood되었다. 새 문제가 나타난 곳에서, 첫 수는 더 발명하는 것이 아니라 이미 세워진 기구에
기대는 것이었다 —— 네 backend를, 그리고 네 방향의 병행 처리를 가능하게 한 클로저 표현, Send와
Sync가 확장한 Trivial 규칙, 능력의 라이프사이클로 판명된 with 구문, par_map이 desugar한
곳의 primitive. 절제는 태만이 아니라 행위로 다뤄졌다: 무언가를 만들지 않는다고 정하는 것은, 그 부재의
비용을 재고, 답을 초안하고, 트리거를 이름 붙이는 것을 뜻했다. 그리고 보장은 양방향으로 정직하게
유지되었다 —— 거기에 없는 건전성을 결코 주장하지 않고, 거기에 없는 결함도 결코 진단하지 않고.
그것들이 상수이고, 그것들이야말로, 독자가 이 연재에서, 어느 특정 feature보다 오래 가지고 돌아갈 수 있는 것이다: 채용할 언어가 아니라, 하나를 세우는 방식 —— 적은 개념을 구별한 채 유지하는 것이, 많은 개념을 슬며시 병합하는 것보다 이기고, 확신할 수 있는 것이, 그저 도는 것보다 값진, 그런 방식.
지도에는 가장자리가 있고, 개발은 그것을 다시 그려 나간다. 지평의 feature 중 하나가 그 이름 붙여진 트리거를 넘어 세워질 때, 그것은 여기서의 새 장이 된다, 같은 방식으로 쓰인 —— 좁혀지고, 시도되고, dogfood되고, 곧게 이야기된. 그때까지, 여기가 언어가 서는 곳이다: 작고, 명시적이고, 검증 가능하고, 가장자리에서 열려 있는. 그것이 늘, 요점이었다.