From c1179f4b7257241f9c1dddf6944e58c4a87b580f Mon Sep 17 00:00:00 2001 From: eunhhu Date: Sun, 4 Oct 2026 11:42:52 +0100 Subject: Say how a library declares records, and what it must show (005's 4) A library declares records as it does fns: an app writes store.User, which is User in its module (Pure's record names are identifiers, one namespace with states), so a record moved into a library leaves the module as it was and another module reading the same store has the same record. Only the library records an app's lists and rows use go into its module; a record value is matched to its declaration. --- docs/design/002-dsl-direction.md | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/docs/design/002-dsl-direction.md b/docs/design/002-dsl-direction.md index eebda2a..921a9e8 100644 --- a/docs/design/002-dsl-direction.md +++ b/docs/design/002-dsl-direction.md @@ -246,6 +246,48 @@ view summary = words.counted(tasks.count, "task", "tasks") 검증: 라이브러리를 쓴 할 일 목록이 참조 모델과 일치하고, 인자를 한 번만 계산하며(값 전달), 라이브러리 경로·순환· 상태 선언·앱 상태 읽기 오류가 해당 파일 위치로 보고된다. 같은 소스와 라이브러리는 같은 모듈을 만든다. 진단 10건을 더했다. +### 라이브러리의 레코드 (설계) + +[외부 리뷰 005](/srv/git/pure.git)의 (4)에서 시작한다. 라이브러리는 `fn`과 `use`만 선언할 수 있어서, 레코드는 앱의 파일 +하나에 모여야 했다. 같은 저장소를 읽는 두 번째 모듈(옮기기 스크립트, 질의)은 레코드를 베껴 써야 했다. 상태는 앱 하나의 +것이지만(원칙 2), 레코드는 상태가 아니라 형태다(원칙 3: 형태는 한 번만 선언한다). + +```text +# store.aup: 레코드와 fn을 가진 라이브러리 +record User { name: text, points = 0 } +fn rank(points) = if points > 100 { "gold" } else { "plain" } + +# main.aup +use store +state users: list of store.User by name +input join = message { name: text } +on join { users.add(store.User { name: join.name }) } +view first = store.rank(users[join.name].points) +``` + +- **라이브러리는 `record`도 선언한다.** 여전히 상태, 입력, 보기, 핸들러, 출력은 선언하지 않는다. +- **쓸 때는 라이브러리 이름을 붙인다.** `list of store.User`, `rows: list of store.User`, `store.User { ... }`. fn과 같다. + 라이브러리 안에서는 제 레코드를 이름만으로 쓴다. +- **모듈에는 선언한 이름으로 들어간다.** Pure 모듈의 레코드 이름은 식별자이고, 상태·입력·보기와 한 이름공간이다(Pure + `core/module.c`). 그래서 `store.User`는 모듈에서 `User`다. 레코드를 앱에서 라이브러리로 옮겨도 모듈이 같다. 같은 저장소를 + 읽는 다른 모듈도 같은 레코드를 같은 이름으로 갖는다. 한 모듈에 같은 이름의 레코드 둘(앱의 것과 라이브러리의 것, 두 라이브러리의 + 것)은 컴파일 오류다. +- **쓰는 레코드만 모듈에 들어간다.** 앱이 선언한 레코드는 지금처럼 모두 들어간다. 라이브러리의 레코드는 앱의 리스트 상태나 + 메시지의 행 필드가 처음 쓸 때 들어간다. 레코드 많은 라이브러리(Vega)를 써도 쓰지 않는 레코드는 모듈의 자리를 차지하지 않는다. +- **레코드 값은 선언으로 맞춘다.** `store.User { ... }`는 `list of store.User`에만 들어간다. 다른 라이브러리의 같은 이름 레코드와 + 섞이지 않는다. + +착수 기준: + +- 바꿀 결정: 라이브러리가 레코드를 선언하게 할지. 아래를 채우지 못하면 레코드는 앱의 파일에만 둔다. +- 최소 확인(`make check`): + - 레코드를 라이브러리로 옮긴 할 일 앱(`examples/tasks.aup`)이 옮기기 전과 바이트 단위로 같은 모듈을 만든다. + - 레코드 셋을 가진 라이브러리에서 하나만 쓰는 앱의 모듈에는 레코드가 하나다. + - 앱이 저장소에 쓴 항목을, 같은 라이브러리를 쓰는 두 번째 모듈(옮기기)이 같은 저장소에서 읽고 바꾸고, 앱이 다시 읽는다. + - 진단: 라이브러리 레코드를 이름만으로 쓰기, 라이브러리에 없는 레코드, 같은 이름의 레코드 둘, 라이브러리 레코드와 앱의 + 상태 이름이 겹침, 다른 레코드의 값을 리스트에 넣기, 라이브러리의 상태 선언(지금처럼 오류). + - aup, Pure, Vega의 검사가 모두 초록이다. + ### 시간 ```text -- cgit v1.2.3