Commit Graph
4 Commits
Author SHA1 Message Date
coolguyandClaude Opus 5 2307bafda2 naming: panic을 crash로 — 그리고 이름을 고르는 원칙을 철학에 넣는다
철학 6번을 추가했다:

  이름은 관례가 아니라 뜻에서 고른다 — 낯섦은 한 번 치르고 끝나지만
  부정확함은 읽는 사람마다 매번 치른다.

판정 방법도 같이 적었다. 그 단어로 평범한 문장을 써 보고, 단어가 문장을
도우면 맞는 이름이고 싸우면 틀린 이름이다.
  "크래시는 복구하는 것이 아니라 조사하는 것이다" — 돕는다
  "패닉은 복구할 수 없다" — 다른 언어에서는 할 수 있어 싸운다

panic의 자연어 뜻은 "갑작스러운 공포"다. 반응하는 쪽의 감정이지 결함에
대한 말이 아니다. 그리고 Go/Rust에서는 붙잡을 수 있어 이름이 거짓말을 한다.
crash는 "계획 없이 갑자기 완전히 망가져 끝남"이고 복구의 함의가 없다 —
크래시는 복구하는 게 아니라 조사하는 것이다.

어휘의 출신도 이유가 됐다. panic+recover는 Go 전통이고 거기엔 감독이 없다.
crash+supervision은 얼랭 전통이며, 우리가 만드는 것이 그쪽이다.

한국어 용어도 세 층으로 정리했다: 실패(Result) / 결함(crash) / 감독.
세 층이 세 가지 다른 기제로 규율된다 — 타입, 없음(발산), capability.
"상황이 나쁨"은 결함이 아니라 실패다. 이 선을 안 그으면 crash가 게으름의
배출구가 된다. "오류"는 컴파일러 진단에만 쓴다.

얼랭 질문에 대한 답도 기록했다: 감독은 가져오고 비구조적 spawn은 안
가져온다. sc.spawn과 sup.spawn(sc, f)로 갈리며 문법 변경이 없다 — 실패를
삼키려면 Supervisor를 받았어야 하고 그것이 시그니처에 보인다.

개명은 문법을 먼저 고치고 대조 장치로 확인했다. 문장 500개, 파일 26개
모두 갈림 0건.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZVDeU6KLuUVL3gs18Hm3E
2026-08-30 18:21:05 +09:00
coolguyandClaude Opus 5 78ef07d2ee panic: panic/Never와 내장 테스트 — 문법을 먼저 고치고 대조 장치가 파서를 지적했다
순서가 요점이다. 문법에 test_decl과 panic_expr을 넣고 파서는 안 고친 채로
대조 장치를 돌렸더니 즉시 잡혔다:

  문장 300개 중 파서가 거부한 것 140개
  [1] 선언 (fn, struct, enum, capability, const)이(가) 필요합니다 — test 발견

파서를 따라가게 하니 다시 0건. 문법과 구현이 어긋나는 상태가 관측 가능한
것이 되었다는 뜻이다.

panic:
- 키워드다. prelude가 없어 함수로 두면 쓸 때마다 import해야 한다
- effect가 아니다. 경계 검사 하나에 {Panic}이 호출자 전부로 전염되면
  effect 절은 신호가 아니라 잡음이 된다
- Never는 어떤 타입 자리에도 놓인다. 없으면 panic을 match 팔에서 못 쓴다
- 언어 수준 recover 없음. 되감기 없음. 자원 해제 여부는 열어둔다
- 0으로 나누기, assert 실패가 이 하나로 모인다

test:
- 파라미터가 없어 capability를 받을 수 없고, 만들 문법도 없다. 그래서
  effect-free임이 증명된다 — 관례가 아니라 검사다. 시험해 보니 실제로
  "테스트는 effect를 수행할 수 없습니다"로 거부한다
- 일반 코드와 같은 타입/effect/move 검사를 받는다
- interface hash에서 제외 — 테스트를 고쳤다고 downstream이 재검사되면 안 된다
- 격리는 런타임의 일이다. 하나가 죽어도 나머지는 돈다

assert는 std/test.cool에 coollang으로 쓰였다 — panic 위의 설탕임이 코드로
보이고, std에서 본문이 있는 첫 함수가 됐다. 그 바람에 std/런타임 양방향
테스트가 걸렸고(본문 있는 함수에 런타임 구현을 요구했다), 그 구분을 넣었다.

samples/app/config.cool에 첫 테스트 넷.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZVDeU6KLuUVL3gs18Hm3E
2026-08-30 17:51:56 +09:00
coolguyandClaude Opus 5 801a7b330b modules: 모듈 경계, interface hash, 그리고 고정점 invalidation
되돌리기 비싼 결정 중 마지막 하나 — incremental 아키텍처 — 를 코드와
테스트로 닫는다.

- iface.ml: exported surface 추출과 해시. 별칭 한정(qualify)은 소비 시점에만
  일어나므로 가져오는 쪽의 별칭이 정의 모듈의 hash에 새지 않는다.
- session.ml: 모듈 로딩과 고정점 전파. hash 비교가 dependents 재검사보다
  앞선다 — 이 순서가 "본문만 수정 시 downstream 0건"의 전부다.
- 한정 이름(Alias.Type, Alias.Ctor, Alias.fn)을 타입 검사, 패턴, 소진성,
  move 검사가 모두 하나의 키("Alias.name")로 본다.
- 패키지 경로(cool.dev/std/list)는 v0에서 해소하지 않고 불투명하게 둔다.
  없다고 말하지 않는다.
- 회귀 테스트: 본문만 고치면 자기 자신만 재검사(1건), variant를 추가하면
  downstream까지 전파되고 실제로 소진성이 깨진다(2건).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZVDeU6KLuUVL3gs18Hm3E
2026-08-30 14:11:30 +09:00
coolguyandClaude Opus 5 2e67b74376 move: move/affinity 검사 — v0 fast path 완성
보안 정리 (ii) — safe code에서 capability는 복제·위조되지 않는다 — 를 코드로
닫는다. 검사는 전부 함수 로컬 데이터플로우이고 전역 분석이 없다.

affinity의 뿌리는 capability다. 필드로 가진 타입은 전이적으로 affine이며
고정점까지 돌려 상호 재귀 타입도 유도한다. 이 전이가 없으면 wrapper 하나를
복사해 capability가 사실상 복제되므로 정리가 깨진다. copyable 선언과 affine
필드의 공존은 오류다.

구현한 규칙:
- affine 값은 소유 자리로 갈 때 move된다(own 파라미터, 반환, struct 저장,
  컨테이너 삽입, let 바인딩, by-move capture). moved 이후 사용은 오류이고
  진단이 어디서 소비됐는지를 말한다
- 분기 병합은 보수적 합집합. 한 분기에서라도 moved면 병합 이후 moved
- 빌린 값은 탈출하지 못한다: 반환, struct 저장, 소유 자리로 넘기기 전부 거부
- use의 전염: 빌린 값을 capture한 클로저는 그 자체가 빌린 값이라 소유 자리로
  갈 수 없다. 별도의 nonescaping 개념 없이 use 규칙 하나로 닫힌다
- callable affinity: affine 값을 capture한 클로저는 affine fn이며 fn 자리에
  갈 수 없다

자율 결정 둘:
- 클로저는 mut 바인딩을 capture할 수 없다. spawn만 막는 특수 규칙 대신
  일반 규칙으로 뒀다 — v0에 참조가 없으므로 별칭도 조용한 복사도 만들 수
  없고, spawn 제한은 이 규칙의 특수 사례가 된다
- v0에 부분 move는 없다. 필드 접근은 빌림이고 결과도 빌린 값이다.
  affine 필드만 꺼내려면 부분 move 상태 추적이 필요한데 v0가 살 복잡도가 아니다

05를 자족적으로 다시 썼다. affinity의 뿌리가 capability라 자원 타입을 모듈
안에서 정의해야 검사기가 affine임을 유도할 수 있다. 외부 타입은 affine임을
증명할 수 없으므로 copyable로 본다.

이로써 fast path(L0 parse / L1 type·effect·capability·ownership)가 완성됐다.
cool check가 처음으로 성공을 선언한다 — 01~04, 06, 07이 exit 0으로 통과한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZVDeU6KLuUVL3gs18Hm3E
2026-08-30 03:01:05 +09:00