Commit Graph
3 Commits
Author SHA1 Message Date
coolguyandClaude Opus 5 a9f6527825 std: 마찰 보고의 F1/F3/F6/F7 처리 — 292줄이 244줄로
문법은 건드리지 않았다. 표본이 한 사람이 쓴 300줄 하나뿐인데 되돌리기
비싼 축을 움직일 수는 없다. std 보강만 했다.

추가: List.first/nth, String.join, std/option.cool, std/result.cool.

samples/app 재작성 결과 config.cool 196 → 148줄. head_or, second_or,
Pick, take_at, first_text, first_entry가 통째로 사라졌다. 예측 40줄,
실제 48줄 — F1의 값이 확인됐다.

F3은 줄 수로 값이 안 보인다. main.cool은 96줄 그대로다. 4단 중첩
String.concat이 4줄짜리 String.join 배열이 됐으니 줄 수가 같다. 읽기는
확실히 나아졌다. 줄 수는 읽기 좋음의 대리 지표일 뿐이고 여기서 그 대리가
깨진다 — 다음 개밥 먹기는 다른 것을 재야 한다.

F7: Interp.implemented와 std/*.cool 선언이 서로를 덮는지 테스트가 양방향
으로 검사한다. 어긋나면 빌드가 깨진다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZVDeU6KLuUVL3gs18Hm3E
2026-08-30 16:20:23 +09:00
coolguyandClaude Opus 5 5831af7760 app: 개밥 먹기 — 일하는 프로그램 하나와 그 마찰 보고
1단계 최소 IO: File(읽기), Args capability. 권한의 출처는 여전히 런타임
하나이고, IO 오류는 Result[a, String]이다 — 런타임이 사용자 정의 enum을
만들 수 없고, 만들 수 있게 하면 런타임이 프로그램의 타입을 알아야 한다.

2단계 std 확장: fold, filter, push, concat, reverse, is_empty,
String.split/trim/starts_with/contains, Int.parse.

3단계 samples/app: 설정 파서 + 리포트 도구, 2모듈 304줄. 검사기를 시험
하려고 쓴 것이 아니라 일을 하려고 쓴 첫 프로그램이다.

산출물은 프로그램이 아니라 docs/friction.md다. 요약:
- 되돌리기 비싼 결정은 하나도 후회되지 않았다. capability 전달, effect
  명시, 실패를 버릴 수 없음, 소진적 match — 300줄 내내 거추장스럽지
  않았고 소진성은 실제로 실수를 잡았다(Value에 경우 하나 추가하니 고칠
  자리 넷을 정확히 짚었다).
- 불편은 전부 되돌리기 싼 것들이었다. 리스트 n번째 접근이 없어 fold로
  우회(40줄), else if가 없어 3~4단 중첩, String.concat이 2항이라 중첩
  지옥. 304줄 중 70줄쯤이 이 셋 때문에 존재한다.

v0의 질문은 "되돌리기 비싼 결정이 옳은가"였고 답은 그렇다이다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZVDeU6KLuUVL3gs18Hm3E
2026-08-30 16:06:08 +09:00
coolguyandClaude Opus 5 5593b54772 std: 표준 라이브러리 — effect 다형성이 처음으로 검사된다
std/list.cool, string.cool, int.cool, bool.cool. 본문 없는 선언이고
런타임이 구현한다. 이 파일들은 구현이 아니라 시험대다.

부채 상환이 아니라 검증이다. std가 없을 때 List.each는 모르는 이름이라
조용히 통과했다. "모르는 것을 틀렸다고 말하지 않는다"는 맞는 원칙이지만,
그 그늘에 검사되지 않는 영역이 숨어 있었다.

넣자마자 샘플 01이 깨졌다 — List.each에 Result를 반환하는 클로저를 넘기고
그 안에서 ?를 쓰고 있었다. each는 값을 남기지 않는 클로저만 받고, ?는
클로저 밖으로 나가지 못하며, 결과를 버릴 방법은 언어에 없다. map으로
고쳤다. 이것이 std를 먼저 한 이유 그 자체다.

- IR은 이제 모듈 그래프 전체를 받고 전역 이름은 "<경로>#<이름>"으로
  정규화된다. 별칭은 가져오는 쪽의 선택이므로 실행 의미에 남아서는 안 된다.
- 본문 없는 선언은 런타임 구현으로 낮아지고, 그 이름은 모듈 파일에서 온다
  (std/list.cool의 each = "list.each"). 별칭과 무관하다.
- prelude 없음. std도 명시적으로 가져온다.
- samples/12: effect 변수가 호출 지점에서 실제로 해소된다는 증거.

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