Mere: 언어를 만들다
리전/뷰 타입 메모리 모델, 능력 전달 방식의 이펙트, 브라우저에서의 셀프 호스팅, 네 가지 백엔드(인터프리터 / C / LLVM / Wasm)로의 코드 생성, 타입 안전한 동시성 —— 작은 ML 계열 언어 Mere의 설계 일지. 완성품 소개가 아니라 의사결정의 기록: 무엇을, 어떻게 만들었고, 어떤 문제가 나왔으며, 어떻게 풀었는가.
이 시리즈에 대하여
Mere 는 작은 ML 계열 프로그래밍 언어입니다 —— 힌들리–밀너 타입 추론, 대수적 데이터 타입, 패턴 매칭. 이것을 쌓아 올려, 결국에는 자기 자신을 브라우저에서 타입 검사·평가·컴파일할 수 있고, 네 가지 백엔드(트리 워킹 인터프리터, C, LLVM IR, WebAssembly)로 코드를 생성하며, 그 모두에서 타입 안전한 동시성을 실행하는 데까지 만들었습니다.
이 시리즈는 완성된 언어의 투어가 아닙니다. 의사결정의 기록입니다 —— 각 요소가 무엇이고, 어떻게 만들었으며, 어떤 문제가 나왔고, 어떻게 해결했는가. 선택이 진짜 갈림길이었을 때는, 택하지 않은 대안과 그것을 고른 이유도 이야기의 일부입니다 —— “이것은 아직 만들지 않는다” 는 답이었을 때도 포함해서.
Mere 뒤에 있는 생각
거의 모든 결정을 관통하는 하나의 믿음이 있습니다:
올바름의 검증 가능성을 최적화하고, 암묵적인 것을 명시적으로 만든다.
구체적으로:
- 암묵적인 것은 의도적으로 제거한다. 런타임 표현이나 동작이 조용히 바뀌는 것은 드러낸다 —— 메모리 소유권, 이펙트, 그리고 (나중에는) 어떤 값이 스레드 경계를 넘을 수 있는지, 이 모두가 타입에서 보이는 형태가 됩니다.
- 타협은 피할 수 없다. 그러니 “어디서” 할지를 고른다. 모든 설계 페이지는 타협이 없는 척하지 않고, 자신이 하고 있는 트레이드오프를 명시합니다.
- 장황함은 허용한다. 코드는 AI의 도움으로 작성하므로, “타이핑이 많다” 는 것은 예전만큼의 비용이 아닙니다. 덕분에, 인간 우선 언어라면 간결함을 위해 숨길 부분을 명시적으로 설계할 수 있습니다.
이것은 영리함이나 속도의 이야기가 아닙니다. 프로그램을 보고 그것이 무엇을 하는지 알 수 있게 하기 위한 것입니다.
각 요소를 어떻게 결정했는가
프로젝트 전체를 관통하며 거의 매번 등장하는 패턴이 있습니다:
- 지상(紙上) 시도 —— 커밋하기 전에, 설계를 종이 위에서 (그리고 종종 버릴 프로토타입으로) 끝까지 생각한다.
- 미결 사항을 구조화한다 —— 결정하지 못한 논점은
Q-###로 세워, 의도적으로 열린 채로 둔다. 구현이 답을 요구하는 시점에 정한다. - 도그푸딩 —— 실제 프로그램을 툴체인에 통과시켜, 설계 문서로는 보이지 않는 문제를 드러낸다.
전체 아크
- 토대 —— 사상, 호스트 언어로 OCaml을 고르는 것, 동작하는 최소 ML 코어.
- 메모리 —— 다섯 가지 전략을,
Trivial/Drop/with를 동반한 통합된 리전/뷰 모델로 증류한다. - 이펙트 —— 숨겨진 환경 상태가 아니라, 능력(capability)으로 전달하는 부수 효과와 세분화된 대여 표기.
- 코드 생성 —— 하나의 언어, 네 백엔드를 발맞추어 유지한다.
- 셀프 호스팅 —— Mere 자신의 렉서·파서·포매터·평가기·타입 검사기·코드 생성기를 Mere로 작성해, 브라우저에서 실행한다.
- 동시성 ——
spawn/ 채널 /par_map을Send/Sync타입 안전과 함께, 모든 백엔드에서. - 앞으로 —— 그리고 그만큼 중요한, 의도적으로 만들지 않은 것.
어디서부터 읽어도 괜찮지만, 각 파트는 대체로 이 순서로 쌓여 있습니다.