docs(base): Get() 확정, Store eager 생성은 table.clone+in-place 교체로 명시

- 읽기 접근자 함수명은 Get()으로 확정(Pull 대비 우위 없음 + 기존 문서와
  일치) — question.md에 반영, .value 존치 여부만 열린 질문으로 남김.
- Store의 eager Source 생성 구현 스케치 추가: table.clone(defaults) 후
  순회하며 각 슬롯을 Source(v)로 교체 — 빈 테이블에 키를 하나씩 넣는 것보다
  해시 슬롯 재사용이 Luau VM에서 더 쌈. Source()(무인자)는 Source(nil)과
  동치라는 점도 명시(lazy 생성 경로가 이 형태를 씀).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
qwreey 2026-08-07 00:31:19 +09:00
parent c5e0b7f452
commit 53d43dc90b
Signed by: qwreey
GPG key ID: D28DB79297A214BD
2 changed files with 19 additions and 11 deletions

View file

@ -142,6 +142,15 @@ State를 만족하도록 만들고, RefSource라는 별도 타입은 폐기**하
게 사용자의 회고적 재평가 — 지금은 타입이 핵심 제약이라 그 전제 자체가 게 사용자의 회고적 재평가 — 지금은 타입이 핵심 제약이라 그 전제 자체가
더 이상 안 맞고, 이번 정리로 Store는 "이름 붙은 Source 모음, 그 이상 더 이상 안 맞고, 이번 정리로 Store는 "이름 붙은 Source 모음, 그 이상
아님"으로 더 단순해짐. 아님"으로 더 단순해짐.
- **구현 스케치(2026-08-07, 성능 근거): eager 생성은 `table.clone(defaults)`
후 그 결과를 순회하며 각 슬롯을 `Source(v)`로 교체하는 모양이어야 함**
(`local sources = table.clone(defaults); for k, v in sources do
sources[k] = Source(v) end` 류) — 빈 테이블을 새로 만들어 키를 하나씩
넣는 것보다, `table.clone`으로 원본의 해시/배열 슬롯 구조를 그대로
재사용하는 쪽이 Luau VM 입장에서 더 쌈(직접 해시 슬롯을 처음부터
구성하는 것보다 기존 슬롯을 복제하는 게 저렴). `Source()`(인자 없이
호출)는 `Source(nil)`과 동치 — `defaults`에 값이 없는 키를 `store.key`
접근 시점에 lazy 생성할 때 이 무인자 형태를 씀.
- **이 서브타입 관계는 `quad2-try`에서 기각한 컴포넌트/클래스 OOP 상속과는 - **이 서브타입 관계는 `quad2-try`에서 기각한 컴포넌트/클래스 OOP 상속과는
다른 층위.** 그때 금지한 건 사용자가 짜는 컴포넌트 계층 구조(`Class:Extend()`류 다른 층위.** 그때 금지한 건 사용자가 짜는 컴포넌트 계층 구조(`Class:Extend()`류
매직)였고, 지금은 두 프리미티브 타입 사이의 구조적 서브타이핑(런타임 매직)였고, 지금은 두 프리미티브 타입 사이의 구조적 서브타이핑(런타임

View file

@ -92,17 +92,16 @@ additional-primitives-plan.md`. 요지:
주기가 없다"는 기존 원칙과 이름이 충돌해 보일 수 있음), `Draw`(짧지만 주기가 없다"는 기존 원칙과 이름이 충돌해 보일 수 있음), `Draw`(짧지만
즉시모드 GUI 뉘앙스), `List`(중립적이나 메커니즘을 안 알려줌) — 아직 즉시모드 GUI 뉘앙스), `List`(중립적이나 메커니즘을 안 알려줌) — 아직
미정, `research/additional-primitives-plan.md` 1번 절 참고. 미정, `research/additional-primitives-plan.md` 1번 절 참고.
- **State/Source 읽기 접근자 — `.value` vs `:Get()`/`:Pull()`(3순위, - **State/Source 읽기 접근자 — 함수명은 `Get()`으로 확정(2026-08-07),
2026-08-07 추가)**: 지금 `.value``:Get()`을 감싼 계산 속성이고 "관용적 `.value` 존치 여부만 남음**: `Get()` vs `Pull()``Get()`으로 확정 —
표기"로 앞세워져 있는데, 이게 quad가 명문화한 "관측해야 실체화된다" 둘 다 "명시적 게터 호출"이라는 엔지니어링 기준에서 동급이라 승부처가
원칙을 프로퍼티 문법이 무디게 만드는 건 아닌지 재검토 중. `Finalize` 아니었고, 이미 문서 전체가 `Get()`을 쓰고 있어 바꿀 이유가 약함(`Finalize`는
quad가 이미 "정리/해제"쪽 의미로 자리 잡아둔 단어(Effect의 leaf-death 앞서 quad의 "정리/해제" 어휘(Effect leaf-death cleanup, `retract`,
cleanup, `retract`, `Destroying`)와 충돌 위험이 있어 기각 — 대신 `Destroying`)와 충돌 위험으로 이미 기각). **아직 열려있는 건 `.value`
`Pull()`(아키텍처 문서 자체가 이 메커니즘을 부르는 "push-invalidate/ (Get()을 감싼 "관용적 표기" 계산 속성) 자체를 유지할지** — quad가
pull-recompute"와 일치)을 검토했다가, 사용자가 `Get()`/`:Set()` 동사 명문화한 "관측해야 실체화된다" 원칙을 프로퍼티 문법이 무디게 만드는 건
짝을 맞추는 쪽이 더 나을 수 있다고 재고 중 — **아직 결정 안 됨**, 아닌지, 유지한다면 State/Source에도 둘지 아니면 진짜 non-lazy인 Ref에만
`.value` 자체를 유지할지(Ref처럼 진짜 non-lazy인 것에만 남길지)도 같이 남길지.
볼 것.
- **"프로바이더"(3순위, 사소함)**: `base/module-lifecycle-plan.md` - **"프로바이더"(3순위, 사소함)**: `base/module-lifecycle-plan.md`
"provider"라고 불러온, `isHandlable`로 참여 여부를 결정하고 우선순위대로 "provider"라고 불러온, `isHandlable`로 참여 여부를 결정하고 우선순위대로
스캔되는 pluggable 참가자 개념 — 정확한 이름을 "provider"/"processor"/ 스캔되는 pluggable 참가자 개념 — 정확한 이름을 "provider"/"processor"/