Files
coollang/std/list.cool
T
coolguyandClaude Opus 5 6bfdcaa0d6 Mini Shell: 네 번째 개밥, 보안 구멍 셋, 누수 lint
Mini Shell은 앞의 셋이 못 건드린 모양을 친다 — 파이프 하나는 끝이 둘이고
각각 다른 자식에게 간다. 부모에게 아무것도 안 남고 어느 블록에도 묶이지
않는다. 가장 어려운 자원 코드가 렉시컬하지 않다.

파싱을 자원에서 떼어 놓아 개밥이 처음으로 실제로 돈다 (test 5/5 통과).

보안 정리 (ii)의 구멍 셋 — 전부 "부분 move가 없다"는 하나의 규칙이
닿아야 할 자리가 비어 있던 것:
- 열거형 생성자가 인자를 소비하지 않았다. Some(f)를 두 번 쓰면 복제됐고,
  LRU가 쓰는 우회(affine 값을 열거형으로 나르기)가 그래서 무의미했다
- 소유한 열거형을 두 번 분해할 수 있었다. match가 scrutinee를 늘 빌려서
  조각만 owned로 나갔다 — 같은 파이프에서 같은 fd를 두 번 꺼낼 수 있었다
- 점 왼쪽을 이름 해소가 검사하지 않았다. Nonsense.whatever(1)이 통과했고
  samples 셋(02, 04, 06)이 이 구멍에 기대고 있었다 (D1과 같은 병)

누수 lint를 넣었다. ?와 return 자리에서 소유하고 있고 아직 안 넘긴 affine
값을 말한다. 저장소 전체 네 곳, 오탐 0건 — naive 판만 걸리고 careful 판은
조용하다. 타입 층 정책은 그대로다 (오용 금지, 누수 허용).

결정: resource라는 새 종류는 넣지 않는다. capability가 이미 그것이고
own self가 정리를 말한다. with는 미룬다 — 두 갈래 중 고르기에 데이터가
부족하고, 셸이 with가 닿지 않는 모양을 보여줬다.

List.rest 추가 (첫 원소를 뺀 나머지).

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

64 lines
2.3 KiB
Plaintext

// 표준 라이브러리: 리스트.
//
// 본문이 없다. 런타임이 구현하고, 이 파일은 그 계약을 말한다.
// 그래서 이 파일은 구현이 아니라 시험대다 — effect 다형성이 실제로 쓸 만한지가
// each, map, fold, filter에서 결정된다. 규칙이 틀렸으면 여기서 드러난다.
//
// e는 파라미터의 effect 슬롯에 홀로 나타난다 (결정 위치). 호출 지점에서
// 인자의 시그니처를 읽어 묶인다 — 추론이 아니라 읽기다.
pub fn len[a](xs: List[a]) -> Int
pub fn is_empty[a](xs: List[a]) -> Bool
// 인덱싱 연산자가 언어에 없다. n번째를 꺼내는 일은 이름 있는 함수가 하고,
// 없을 수 있다는 사실은 Option이 말한다 — 범위를 벗어나면 예외도 기본값도
// 아니고 None이다.
pub fn first[a](xs: List[a]) -> Option[a]
pub fn nth[a](xs: List[a], i: Int) -> Option[a]
// 첫 원소를 뺀 나머지. 비어 있으면 빈 리스트다 — 없는 것을 빼는 일은
// 오류가 아니라 아무 일도 아니다. first와 짝이고, 둘은 서로 어긋날 수 없다.
pub fn rest[a](xs: List[a]) -> List[a]
// 번호를 붙인 값. fold에 인덱스를 넣는 대신 이것 하나를 둔다 —
// fold_indexed를 만들면 map_indexed, each_indexed가 따라오고 그것이
// "한 개념 한 방식"을 깨는 방향이다. enumerate는 기존 각 함수와 조합된다.
pub copyable struct Indexed[a] {
i: Int,
value: a,
}
pub fn enumerate[a](xs: List[a]) -> List[Indexed[a]]
// 뒤에 하나 붙인 새 리스트. 제자리 수정이 아니다.
pub fn push[a](xs: List[a], x: a) -> List[a]
pub fn concat[a](xs: List[a], ys: List[a]) -> List[a]
pub fn reverse[a](xs: List[a]) -> List[a]
pub fn each[a, e: effects](
xs: List[a],
f: fn(a) effects e,
) effects e
pub fn map[a, b, e: effects](
xs: List[a],
f: fn(a) effects e -> b,
) effects e -> List[b]
pub fn filter[a, e: effects](
xs: List[a],
keep: fn(a) effects e -> Bool,
) effects e -> List[a]
// 누적자는 매 단계 소비되고 새것으로 바뀐다. own이 그 사실을 말한다 —
// 빌림으로 적으면 affine 값을 fold로 실어나를 수 없다.
pub fn fold[a, acc, e: effects](
xs: List[a],
own init: acc,
f: fn(own acc, a) effects e -> acc,
) effects e -> acc