프로그램을 쓰되 돌리지 않는 방식을 시작한다. std가 원래 선언-전용이므로 실행만 빼고 전부 진짜로 검사된다 — 종이 스케치가 아니라 컴파일러가 검증한 설계다. 합격 기준을 둘로 잡았다: check exit 0 + 모듈이 실제로 해소될 것. 후자가 없으면 전자가 공허한데, 그것을 첫 시도에서 겪었다. D1 — 상대 경로 import가 패키지로 오인됐다. is_package가 첫 세그먼트에 점이 있는지만 봐서 ".."이 걸렸다. 무서운 것은 버그가 아니라 결과였다: import가 해소되지 않으면 그 모듈의 이름이 전부 불투명해지고, "모르는 것을 틀렸다고 말하지 않는다"는 원칙에 따라 무엇이든 통과한다. 첫 check가 exit 0이었는데 없는 메서드를 불러도 통과하는 상태였다. D2 — 값 있는 식을 문으로 버릴 수 있었다. fs.remove(path)를 문으로 쓰면 Result가 조용히 사라졌다. 즉 실패를 버리는 방법이 있었고, 내가 개밥 먹기 1차 보고서와 투어에 "이 언어에는 실패를 버릴 방법이 없다"고 적은 것은 틀렸다 — List.each 하나의 좁은 사실을 언어 전체로 일반화했다. 이제 오류이고, 일부러 버리려면 let _ = 로 적는다. 부산물로 정리 경로의 관용구가 생겼다. D3(본체) — ?를 자원과 함께 쓸 수 없다. naive.cool 18줄은 조기 반환으로 핸들을 누수하는데 통과한다(v0 정책). 제대로 정리한 careful.cool은 58줄이고 5단 중첩 match이며 ?를 한 번도 못 쓴다. 3.2배다. resource/with가 필요한 이유가 여기 숫자로 있다. 열어둔 것: 함수 타입에 own이 없어 고차 경계에서 소유권이 뚫린다(D5). Mini Shell과 DB Pool이 정면으로 걸리므로 그 둘 전에 결정해야 한다. 문자 접근이 없어 어휘 분석을 못 쓴다(D6). 소유권 검사가 잡는 것은 확인했다: 두 번 닫기, 닫은 뒤 쓰기, 빌린 핸들 반환. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019ZVDeU6KLuUVL3gs18Hm3E
2.8 KiB
2.8 KiB
dogfoods — 실제 유스케이스로 언어를 압박한다
samples/가 검사기를 시험한다면 여기는 언어가 실제 문제를 표현할 수 있는지를
시험한다. 성격이 다르므로 폴더를 나눈다.
방법
프로그램을 쓰되 돌리지 않는다. std-draft/에 런타임이 구현한다고 가정한
선언을 두고, 그것에 대고 실제 프로그램을 쓴다.
"가상"이 아니다. std/*.cool이 원래 본문 없는 선언이므로 실행만 빼고 전부
진짜로 검사된다:
lexer ✓ parser ✓ 이름 해소 ✓ 타입 ✓ effect ✓
capability ✓ move/affinity ✓ 소진성 ✓ interface hash ✓
run ✗
종이 스케치가 아니라 컴파일러가 검증한 설계다.
합격 기준
① coolc check exit 0
② 모듈이 실제로 해소될 것
②가 없으면 ①이 공허하다. import가 조용히 해소되지 않으면 그 모듈의 이름이 전부 불투명해지고, 검사기는 "모르는 것을 틀렸다고 말하지 않는다"는 원칙에 따라 무엇이든 통과시킨다. 실제로 첫 시도에서 이 일이 일어났다 (D1 참고).
규율
std-draft의 선언은 독립적으로 정당화되어야 한다.
- 지금 런타임이 가진 권한으로 구현 가능할 것
- effect를 전부 선언할 것
- 실패 양상을 선언하는 자리에서 정할 것 — 무엇이
Result이고 무엇이crash인지 - 없는 언어 기능에 기대지 말 것. 필요하다는 것이 드러나면 그것이 발견이지 지름길이 아니다
프로그램이 예뻐 보이도록 API를 발명하면 아무것도 배우지 못한다.
한계
이 기준이 증명하는 것은 표현 가능성이지 의미론의 정확성이 아니다.
check가 통과한다고 그 프로그램이 옳게 도는 것은 아니다 — 돌려본 적이 없다.
세트
| 압박하는 곳 | 상태 | ||
|---|---|---|---|
| 1 | Mini Shell | 소유권 / OS 핸들 | 대기 |
| 2 | Atomic File Updater | 자원 수명, 실패 경로 | 완료 |
| 3 | Process Supervisor | 실패 위상 | 대기 |
| 4 | Reverse Proxy | 취소, backpressure | 대기 |
| 5 | TCP Server | 규모의 API 모양 | 대기 |
| 6 | DB Pool | lease, 자원 정리 | 대기 |
| 7 | Resource Exhaustion | 실패 의미론의 최악 조건 | 미룸 — 런타임 속성이라 안 돌리면 알 수 없다. 언어 층 질문("무엇이 Result이고 무엇이 crash인가")은 std-draft 규율로 흡수했다 |
순서는 자원 모델(2, 6, 1) → 동시성·취소(3, 4, 5)다. 2번을 먼저 둔 이유는 동시성을 안 섞고 자원 모델만 시험할 수 있는 유일한 것이기 때문이다.
발견은 FINDINGS.md에 쌓고, 확정된 결정은 docs/thesis.md로 올린다.