@calcit/procs 0.11.7 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/.gitattributes +1 -1
  2. package/.yarn/install-state.gz +0 -0
  3. package/build.rs +229 -11
  4. package/editing-history/2026-0303-1934-check-types-and-core-annotations.md +17 -0
  5. package/editing-history/2026-0304-1331-tag-call-warning-and-dot-access-migration.md +28 -0
  6. package/editing-history/2026-0304-1548-impl-new-dot-method-input-and-doc-hints.md +33 -0
  7. package/editing-history/2026-0304-1645-calcit-eq-contract-refactor-and-macro-tests.md +28 -0
  8. package/editing-history/2026-0304-2200-assert-type-assert-traits-composable-runtime-checks.md +18 -0
  9. package/editing-history/2026-0304-generics-fn-typevar-identity.md +30 -0
  10. package/editing-history/2026-0305-0042-type-inference-argtypes-and-core-hints.md +54 -0
  11. package/editing-history/2026-0305-0115-calcit-core-generic-refinements.md +57 -0
  12. package/editing-history/2026-0305-1930-schema-migration-cr-edit.md +30 -0
  13. package/editing-history/2026-0305-1939-query-schema-adaptation.md +42 -0
  14. package/editing-history/2026-0306-0120-schema-hint-migration-batch.md +38 -0
  15. package/editing-history/2026-0306-1416-core-macro-schema-migration.md +20 -0
  16. package/editing-history/2026-0306-1552-core-schema-and-hintfn-migration.md +63 -0
  17. package/editing-history/2026-0306-1936-schema-normalization-and-preprocess-preload.md +12 -0
  18. package/editing-history/2026-0307-0142-unit-type-and-builtin-schemas.md +82 -0
  19. package/editing-history/2026-0307-1302-calcit-agent-docs-update.md +32 -0
  20. package/editing-history/2026-0307-1652-decouple-snapshot-schema-to-calcit-type.md +112 -0
  21. package/editing-history/2026-0307-1821-snapshot-schema-validation.md +6 -0
  22. package/editing-history/2026-0307-1959-schema-def-kind-arity-validation.md +96 -0
  23. package/editing-history/2026-0307-migrate-hint-fn-to-schema.md +29 -0
  24. package/editing-history/2026-0307-remove-enum-prototype-field.md +43 -0
  25. package/editing-history/2026-0307-schema-args-type-enforcement.md +66 -0
  26. package/editing-history/2026-0308-0031-schema-generics-quote-normalization.md +35 -0
  27. package/editing-history/2026-0308-1905-schema-typeref-and-assert-migration.md +34 -0
  28. package/editing-history/2026-0308-2033-schema-wrapper-migration.md +45 -0
  29. package/editing-history/2026-0308-2315-late-schema-cleanup-and-warning-compat.md +27 -0
  30. package/lib/calcit-data.mjs +6 -0
  31. package/lib/calcit.procs.mjs +3 -1
  32. package/lib/package.json +2 -2
  33. package/package.json +2 -2
  34. package/ts-src/calcit-data.mts +6 -0
  35. package/ts-src/calcit.procs.mts +3 -1
@@ -0,0 +1,20 @@
1
+ ## 概要
2
+
3
+ 本次提交继续推进 schema-first 迁移,聚焦 `src/cirru/calcit-core.cirru`,为核心宏入口补齐显式 `:schema`,在不改变运行逻辑的前提下提升静态信息覆盖率与一致性。
4
+
5
+ ## 关键改动
6
+
7
+ - 补齐高频线程/控制宏 schema:`->`、`->>`、`<-`、`if-not`、`thread-as`、`thread-first`、`thread-last`、`;nil`、`:`。
8
+ - 补齐构造/模式宏 schema:`list-match`、`record-match`、`record-with`、`tag-match`、`field-match`、`{}`。
9
+ - 补齐内部宏入口 schema:`&case`、`&list-match-internal`、`&record-match-internal`、`&field-match-internal`。
10
+ - 补齐工具/调试宏 schema:`[,]`、`[][]`、`\`、`\.`、`call-w-log`、`call-wo-log`、`js-object`、`w-log`、`w-js-log`、`with-cpu-time`、`with-gensyms`、`wo-log`、`wo-js-log`、`noted`。
11
+
12
+ ## 结果
13
+
14
+ - `calcit-core` 中 `defmacro` 对应的 `:schema nil` 已清空。
15
+ - 每批改动后均执行 `edit format` 与 `yarn check-all`,回归通过。
16
+
17
+ ## 经验
18
+
19
+ - 采用“按语义分组小批次补齐 + 每批全量回归”策略,可在大文件中稳定推进迁移并快速定位异常。
20
+ - 对宏统一使用 `:kind :macro` 与 `:args/:rest/:return` 结构,能减少后续工具链处理分支。
@@ -0,0 +1,63 @@
1
+ # 2026-03-06 15:52 core schema + hint-fn 迁移批次
2
+
3
+ ## 背景
4
+
5
+ 本批次延续 schema-first 迁移:
6
+
7
+ - 在 `src/cirru/calcit-core.cirru` 继续将 runtime 内建的 `:schema nil` 改为显式 schema。
8
+ - 在 `calcit/` 测试目录中,将旧式 `hint-fn` 参数写法迁移为新写法。
9
+
10
+ ## 主要改动
11
+
12
+ ### 1) Core runtime schema 补齐(无行为改动)
13
+
14
+ 在 `src/cirru/calcit-core.cirru` 增补了多批低风险条目的 schema,覆盖例如:
15
+
16
+ - 数学/比较/位运算:`cos`/`sin`/`sqrt`/`round`/`round?`/`floor`/`ceil`、`bit-*` 系列等
17
+ - 字符串/解析/格式化:`split`/`split-lines`/`trim`/`parse-cirru*`/`format-cirru*`
18
+ - IO 与环境:`read-file`/`write-file`/`get-env`/`generate-id!`
19
+ - 运行时工具:`atom`/`add-watch`/`remove-watch`/`type-of`/`turn-*`/`fold*`/`range`/`recur`/`raise`/`quit!`
20
+
21
+ 原则:仅补 schema,不改运行时逻辑。
22
+
23
+ ### 2) 旧式 hint-fn 参数写法迁移
24
+
25
+ 在 `calcit/test-types-inference.cirru` 中,将旧写法:
26
+
27
+ - `:args $ [] :number`
28
+
29
+ 迁移为新写法:
30
+
31
+ - `:args $ [] (:: 'x :number)`
32
+
33
+ 并复查 `calcit/**` 下同模式,不再命中。
34
+
35
+ ## 验证
36
+
37
+ 每批次均执行:
38
+
39
+ - `cargo run --bin cr -- demos/compact.cirru edit format`
40
+ - `yarn check-all`
41
+
42
+ 结果均通过(尾部稳定为 `... and 24 files not changed.`)。
43
+
44
+ ## 备注
45
+
46
+ - 当前提交聚合了本轮连续小批次迁移结果,便于后续按文件/功能继续清理剩余 `:schema nil`。
47
+
48
+ ## 增补(同批次续改)
49
+
50
+ ### 3) 移除 legacy hint-fn clause 兼容(改为直接报错)
51
+
52
+ 在 `src/runner/preprocess.rs` 中将旧语法兼容从 warning 升级为 hard error:
53
+
54
+ - 不再接受 `hint-fn` 内 legacy clauses:`return-type` / `generics` / `type-vars`
55
+ - 统一在 `preprocess_hint_fn` 阶段报 `Syntax` 错误,提示迁移到 schema map 形式
56
+ - 删除旧的 `warn_on_legacy_hint_fn_syntax` 路径并同步测试
57
+
58
+ ### 4) 文档更新(docs + guidebook)
59
+
60
+ 同步更新示例与说明,避免继续传播旧写法:
61
+
62
+ - `docs/CalcitAgent.md`:补充“legacy clause 会直接报错”,并将 `:args` 示例改为命名参数条目
63
+ - `guidebook/docs/cirru-syntax.md`、`guidebook/docs/features/static-analysis.md`、`guidebook/docs/features/records.md`:统一 `hint-fn` 示例为 schema-map + `(:: 'arg <type>)` 形式
@@ -0,0 +1,12 @@
1
+ # 本次修改记录
2
+
3
+ - 统一 schema 风格:清理 `:args` / `:rest` 中参数名,保留类型表达式,降低重复声明。
4
+ - 预处理前置 schema:在 `preprocess_defn` 中优先注入 schema hint,再进行类型与返回值检查。
5
+ - 程序装载增强:`program` 层为定义缓存并暴露 schema 查询能力。
6
+ - 快照规范化:`snapshot` 序列化时统一去除 schema 的 `:name` 字段与命名参数注解。
7
+ - 文档同步:更新 Agent 文档中 `hint-fn` / schema 写法示例到当前风格。
8
+
9
+ ## 验证
10
+
11
+ - `cargo test` 通过。
12
+ - `yarn check-all` 通过。
@@ -0,0 +1,82 @@
1
+ # 2026-0307-0142 `:unit` 类型 + 内建函数 schema 批量补全
2
+
3
+ ## 改动概要
4
+
5
+ ### 1. Rust 类型系统: `CalcitTypeAnnotation::Nil` (`:unit`)
6
+
7
+ 在 `src/calcit/type_annotation.rs` 中添加新的 `Nil` variant, 对应 Cirru 关键字 `:unit`。
8
+
9
+ **使用场景**: 副作用函数 (side-effectful functions), 明确标注返回 `nil` 的情况, 区别于 `:dynamic` (未知类型)。
10
+
11
+ **涉及改动点**:
12
+
13
+ - `CalcitTypeAnnotation` enum: 新增 `Nil` variant
14
+ - `builtin_type_from_tag_name`: `"unit" | "nil" => Self::Nil`
15
+ - `builtin_tag_name`: `Self::Nil => Some("unit")`
16
+ - `variant_order`: `Self::Nil => 27`
17
+ - `matches_with_bindings`: `(Self::Nil, Self::Nil) => true`
18
+ - `Hash impl`: `Self::Nil => "nil".hash(state)`
19
+ - `value_matches_type_annotation`: `CalcitTypeAnnotation::Nil => matches!(value, Calcit::Nil)`
20
+ - `gen_ir.rs`: `CalcitTypeAnnotation::Nil => type_tag_map("unit")`
21
+
22
+ ### 2. 副作用函数 `:return :unit` schema
23
+
24
+ 在 `src/cirru/calcit-core.cirru` 中为以下函数补充 `:return :unit` schema:
25
+
26
+ | 函数名 | schema 要点 |
27
+ | -------------- | ------------------------------------------------------- |
28
+ | `each` | `:args ([] :dynamic :fn) :return :unit` |
29
+ | `write-file` | `:args ([] :string :string) :return :unit` |
30
+ | `quit!` | `:args ([] (:: :optional :number)) :return :unit` |
31
+ | `add-watch` | `:args ([] :ref :dynamic :fn) :return :unit` |
32
+ | `remove-watch` | `:args ([] :ref :dynamic) :return :unit` |
33
+ | `reset!` | `:generics 'T :args ([] (:: :ref 'T) 'T) :return :unit` |
34
+
35
+ **注意事项**: 在 `:: :fn ('T) :unit` 中, `'T` 出现在 `('T)` 列表的算子位置会触发 EDN 解析错误 (`invalid operator for edn: 'T`)。对 `each` 的解决方案是简化成 `:fn`, 避免在 fn 参数类型中使用泛型变量作为算子。
36
+
37
+ ### 3. 内建函数 schema 批量补全 (54 条)
38
+
39
+ 对 `calcit-core.cirru` 中原本 `:schema nil` 的内建 primitive 函数批量补充类型:
40
+
41
+ **`&list:*` (16 条)**: `assoc`, `assoc-after`, `assoc-before`, `concat`, `contains?`, `count`, `dissoc`, `distinct`, `empty?`, `first`, `includes?`, `nth`, `rest`, `reverse`, `slice`, `to-set`
42
+
43
+ **`&map:*` (12 条)**: `assoc`, `common-keys`, `contains?`, `count`, `destruct`, `diff-keys`, `diff-new`, `dissoc`, `empty?`, `get`, `includes?`, `to-list`
44
+
45
+ **`&str:*` (15 条)**: `compare`, `concat`, `contains?`, `count`, `empty?`, `escape`, `find-index`, `first`, `includes?`, `nth`, `pad-left`, `pad-right`, `replace`, `rest`, `slice`
46
+
47
+ **集合操作 (10 条)**: `&difference`, `&exclude`, `&include`, `&set:count`, `&set:destruct`, `&set:empty?`, `&set:includes?`, `&set:intersection`, `&set:to-list`, `&union`
48
+
49
+ **泛型模式** (使用 `'T` 非算子位置):
50
+
51
+ ```cirru
52
+ {} (:kind :fn)
53
+ :generics $ [] 'T
54
+ :args $ [] (:: :list 'T) :number 'T
55
+ :return $ :: :list 'T
56
+ ```
57
+
58
+ ### 4. Clippy & 代码质量修复
59
+
60
+ - `emit_js.rs`: 消除冗余闭包 `xs.iter().skip(1).any(schema_marks_async)`
61
+ - `query.rs`: 添加复杂类型别名 `type RefResults = ...`
62
+
63
+ ## 技术知识点
64
+
65
+ ### `'T` 在 schema 文件中的限制
66
+
67
+ - **可用位置**: `:generics $ [] 'T`, `(:: :list 'T)` 的末尾参数, `[] :arg1 'T`
68
+ - **不可用位置**: `('T)` 即 `'T` 作为列表算子 (head), 例如 `(:: :fn ('T) :unit)` 中的 `('T)`
69
+ - **根本原因**: schema 验证通过 `cirru_edn::parse` 进行, EDN 解析器要求列表头部必须是合法算子
70
+
71
+ ### `:unit` vs `:dynamic`
72
+
73
+ - `:unit` — 明确标注 "此函数返回 nil, 且是预期行为" (副作用函数)
74
+ - `:dynamic` — 未知/任意类型 (默认回退)
75
+
76
+ ## 验证结果
77
+
78
+ ```
79
+ cargo clippy -- -D warnings → ✓ 0 warnings
80
+ cargo test → ✓ 17/17 passed
81
+ yarn check-all → ✓ took 571ms, all passed
82
+ ```
@@ -0,0 +1,32 @@
1
+ # 2026-03-07 CalcitAgent.md 文档更新
2
+
3
+ ## 修改内容
4
+
5
+ ### 1. 新增 `--no-tips` 全局标志文档
6
+
7
+ 在「主要运行命令」小节中,`cr js --check-only` 之后新增:
8
+
9
+ ```
10
+ - `cr --no-tips <subcommand> ...` - 隐藏所有编辑/查询命令输出的 "Tips:" 提示行(适合脚本/Agent 使用)
11
+ - 示例:`cr --no-tips demos/compact.cirru query def calcit.core/foldl`
12
+ ```
13
+
14
+ **背景**:`aa21b3a` 提交新增了 `--no-tips` 全局开关(`TIPS_SUPPRESSED: AtomicBool`,通过 `suppress_tips()` 设置),文档中缺少记录。
15
+
16
+ ### 2. 新增 HOF 高阶函数回调类型检查说明
17
+
18
+ 在「类型标注与检查 → 3. 支持的类型标签」之后,`约定:动态类型标注…` 注释的下方新增章节:
19
+
20
+ **高阶函数(HOF)回调类型检查:**
21
+ `foldl`、`sort`、`filter`、`find`、`find-index`、`filter-not`、`mapcat`、`group-by` 等内置 HOF 的回调参数已强制要求 `:fn` 类型,传入非函数值时预处理阶段会触发类型警告。附正/误示例。
22
+
23
+ **背景**:`aa21b3a` 提交修复了以下两条路径的类型检查:
24
+
25
+ - Cirru `defn` schema (`calcit-core.cirru`):`filter-not`/`find`/`find-index`/`foldl`/`foldl'`/`foldl-compare`/`mapcat`/`group-by`/`sort` 的回调参数由 `:dynamic` 改为 `:fn`(部分带泛型注解)
26
+ - `ProcTypeSignature` (`proc_name.rs`):`Foldl`/`Sort`/`FoldlShortcut`/`FoldrShortcut` 的回调参数 `dynamic` → `some_fn()`/`optional_fn()`
27
+
28
+ ## 知识点
29
+
30
+ - **文档中不需要描述 `ProTypeSignature` 实现细节**,面向 Agent 只需说明行为:哪些 HOF 要求 `:fn` 参数。
31
+ - **`--no-tips` 定位**:全局开关,放在 subcommand 前;所有 `Tips::print()` 调用均受其控制。
32
+ - CalcitAgent.md 未发现旧 `-s/--stdin` 残留,无需清理。
@@ -0,0 +1,112 @@
1
+ # 2026-0307-1652 — 解耦 snapshot::CodeEntry.schema 为 Arc<CalcitTypeAnnotation>
2
+
3
+ ## 核心改动
4
+
5
+ 将整个项目中 `snapshot::CodeEntry.schema` 和 `program::ProgramDefEntry.schema` 的类型,从 `Option<Edn>` / `Option<Arc<CalcitFnTypeAnnotation>>` 统一迁移为 `Arc<CalcitTypeAnnotation>`。
6
+
7
+ 同时打破了 `type_annotation.rs → program → snapshot → calcit` 的循环依赖。
8
+
9
+ ---
10
+
11
+ ## 循环依赖的解法
12
+
13
+ **原依赖链(错误):**
14
+
15
+ ```
16
+ snapshot → calcit::type_annotation → program → snapshot ❌
17
+ ```
18
+
19
+ **修复方案:** 在 `type_annotation.rs` 中用 `OnceLock<fn>` 注册 program 级别的 lookup 函数,由 `program.rs` 在 `extract_program_data` 时调用 `register_program_lookups` 完成注册:
20
+
21
+ ```rust
22
+ type LookupFn = fn(&str, &str) -> Option<Calcit>;
23
+ static LOOKUP_EVALED_DEF: OnceLock<LookupFn> = OnceLock::new();
24
+ static LOOKUP_DEF_CODE: OnceLock<LookupFn> = OnceLock::new();
25
+
26
+ pub fn register_program_lookups(evaled: LookupFn, code: LookupFn) {
27
+ let _ = LOOKUP_EVALED_DEF.set(evaled);
28
+ let _ = LOOKUP_DEF_CODE.set(code);
29
+ }
30
+ ```
31
+
32
+ ---
33
+
34
+ ## 修改文件列表
35
+
36
+ ### `src/calcit/type_annotation.rs`
37
+
38
+ - 移除 `use crate::program;` 导入
39
+ - 新增 OnceLock 静态注册机制及 `register_program_lookups` 公开函数
40
+ - 将 6 处 `program::lookup_*` 调用替换为本地 `lookup_evaled_def` / `lookup_def_code_registered`
41
+ - 新增 `CalcitTypeAnnotation::to_type_edn(&self) -> Edn` 序列化方法
42
+ - 新增 `calcit_type_to_edn(form: &Calcit) -> Edn` 私有辅助函数(Custom 类型回退)
43
+ - 新增 `CalcitFnTypeAnnotation::to_schema_edn(&self) -> Edn`(输出完整 schema map)
44
+ - 新增 `CalcitFnTypeAnnotation::to_schema_calcit(&self) -> Calcit`(用于 hint-fn 注入)
45
+ - 修复 `Self::Struct/Enum` 序列化:使用 `Edn::Tag` 而非 `Edn::Symbol`(类型不同)
46
+
47
+ ### `src/calcit.rs`
48
+
49
+ - 在 `pub use type_annotation::` 中新增 `register_program_lookups`
50
+
51
+ ### `src/program.rs`
52
+
53
+ - `ProgramDefEntry.schema: Arc<CalcitTypeAnnotation>`(取代旧 `Option<Arc<CalcitFnTypeAnnotation>>`)
54
+ - `extract_program_data` 首行调用 `calcit::register_program_lookups(...)`
55
+ - `lookup_def_schema` 返回类型改为 `Arc<CalcitTypeAnnotation>`(不再返回 Option,缺省返回 `DYNAMIC_TYPE`)
56
+ - `apply_code_changes` 中 `schema: DYNAMIC_TYPE.clone()` 取代 `None`
57
+
58
+ ### `src/snapshot.rs`
59
+
60
+ - 移除 `CalcitFnTypeAnnotation` 从导入(已无直接使用)
61
+ - 新增 `mod schema_serde`:将 `Arc<CalcitTypeAnnotation>` 序列化为 `Option<Edn>` 保持二进制 RMP 兼容
62
+ - `CodeEntry.schema: Arc<CalcitTypeAnnotation>`,带 `#[serde(default, with = "schema_serde")]`
63
+ - `TryFrom<Edn>` / `From` trait 实现全部更新,使用 `parse_fn_schema_from_edn` + `DYNAMIC_TYPE`
64
+ - 测试用例中 `schema: Some(Edn)` 改为通过 `parse_fn_schema_from_edn` 构造 `Arc<CalcitTypeAnnotation>`
65
+
66
+ ### `src/detailed_snapshot.rs`
67
+
68
+ - 同 `snapshot.rs` 模式:新增 `mod schema_serde`,字段类型改为 `Arc<CalcitTypeAnnotation>`
69
+ - `From<CodeEntry>` / `From<DetailedCodeEntry>` 均直接 clone Arc
70
+
71
+ ### `src/runner/preprocess.rs`
72
+
73
+ - hint-fn 注入改为先匹配 `CalcitTypeAnnotation::Fn(fn_annot)`,再调用 `fn_annot.to_schema_calcit()`
74
+
75
+ ### `src/bin/cli_handlers/edit.rs`
76
+
77
+ - schema 清空时:`schema = DYNAMIC_TYPE.clone()`
78
+ - schema 写入时:通过 `parse_fn_schema_from_edn` 解析后包装为 `Arc<CalcitTypeAnnotation::Fn(...)>`
79
+
80
+ ### `src/bin/cli_handlers/query.rs`
81
+
82
+ - 4 处 `entry.schema.is_some()` / `if let Some(schema_edn)` 全部改为 `CalcitTypeAnnotation::Fn(fn_annot)` 匹配
83
+ - 序列化时通过 `fn_annot.to_schema_edn()` 转回 Edn 后再调用 `schema_edn_to_cirru`
84
+
85
+ ### `src/bin/cr.rs`
86
+
87
+ - 新增 `CalcitTypeAnnotation` 到 `use calcit::{calcit::{...}}` 导入
88
+ - 原 `schema: None` 改为 `calcit::calcit::DYNAMIC_TYPE.clone()`
89
+ - `if let Some(schema_edn)` 改为 `if let CalcitTypeAnnotation::Fn(fn_annot)`
90
+
91
+ ### `src/bin/cr_sync.rs`
92
+
93
+ - `schema: None` 改为 `calcit::calcit::DYNAMIC_TYPE.clone()`
94
+
95
+ ---
96
+
97
+ ## 关键设计决策
98
+
99
+ 1. **`Arc<CalcitTypeAnnotation>` 永不为 None**:缺省值统一为 `DYNAMIC_TYPE`(全局 `LazyLock<Arc<CalcitTypeAnnotation>>` 单例),避免到处 `Option` 处理。
100
+
101
+ 2. **二进制兼容**:`schema_serde` 模块确保 `Dynamic` → 序列化为 `None`,`Fn(...)` → 序列化为完整 Edn map,与旧 `Option<Edn>` 格式一一对应。
102
+
103
+ 3. **`Edn::Tag` 用于类型名称**:`Struct`/`Enum` 类型序列化时用 `Edn::Tag(name)` 而非 `Edn::Symbol(name)`,因为 `EdnTag` 不能直接构造 `Edn::Symbol(Arc<str>)`。
104
+
105
+ ---
106
+
107
+ ## 验证结果
108
+
109
+ - `cargo build` ✅
110
+ - `cargo clippy -- -D warnings` ✅
111
+ - `cargo test` ✅(17 passed)
112
+ - `yarn check-all` ✅(515ms)
@@ -0,0 +1,6 @@
1
+ # 2026-0307-1821 Snapshot and Schema Serialization Refinement
2
+
3
+ - Verified Rust core changes using `yarn try-rs`, `cargo test`, and `yarn check-all`.
4
+ - Ensured `Snapshot` and `CodeEntry` serialization/deserialization remains consistent with the new direct map EDN format for schemas.
5
+ - Confirmed unit tests for `CodeEntry` with examples and schema validation are passing.
6
+ - Validated that `calcit-core.cirru` example parsing works as expected.
@@ -0,0 +1,96 @@
1
+ # Schema vs Definition Kind/Arity Validation
2
+
3
+ ## Summary
4
+
5
+ Added structural validation that compares a definition's code form against its schema declaration. This catch mismatches between declared schema metadata (`:kind`, arg count, rest param) and the actual `defn`/`defmacro` code at analysis time.
6
+
7
+ ## Key Changes
8
+
9
+ ### `src/calcit/type_annotation.rs`
10
+
11
+ 1. **Added `SchemaKind` enum** (`pub enum SchemaKind { Fn, Macro }`) — distinguishes `:kind :fn` from `:kind :macro` schemas.
12
+
13
+ 2. **Extended `CalcitFnTypeAnnotation`** with two new fields:
14
+ - `pub fn_kind: SchemaKind` — schema's declared kind (fn/macro).
15
+ - `pub rest_type: Option<Arc<CalcitTypeAnnotation>>` — schema's `:rest` type, if present.
16
+
17
+ 3. **`parse_fn_schema_from_edn`** — now reads `:kind :macro` → `SchemaKind::Macro` and `:rest` → `rest_type` from the EDN map.
18
+
19
+ 4. **`to_schema_edn`** — now serializes `fn_kind` (`fn`/`macro`) and `rest_type` (`:rest` key in the output map). Previously always emitted `:kind :fn` and omitted `:rest`.
20
+
21
+ 5. **All `CalcitFnTypeAnnotation` construction sites** updated to add `fn_kind: SchemaKind::Fn, rest_type: None` defaults (7 total).
22
+
23
+ 6. **`substitute_type_vars`** also propagates `fn_kind` and substitutes `rest_type`.
24
+
25
+ ### `src/calcit.rs`
26
+
27
+ - `SchemaKind` added to the `pub use type_annotation::{ ... }` re-export.
28
+
29
+ ### `src/bin/cr.rs`
30
+
31
+ 1. **`SchemaKind` imported** in the `use calcit::calcit::{...}` block.
32
+
33
+ 2. **`TypeCoverageRow` struct** gained `schema_issues: Vec<String>` field — carries kind/arity mismatch warnings per definition.
34
+
35
+ 3. **`validate_def_vs_schema(ns, def_name, code, schema) -> Vec<String>`** — new function:
36
+ - `&runtime-inplementation` leaf → skip (builtin proc/syntax).
37
+ - Schema not `CalcitTypeAnnotation::Fn` → skip.
38
+ - Code head not `defn`/`defmacro` → skip.
39
+ - Schema `:kind :fn` + code `defmacro` → error.
40
+ - Schema `:kind :macro` + code `defn` → error.
41
+ - Required arg count mismatch → error.
42
+ - `has_rest` mismatch (schema `:rest` vs code `&`) → error.
43
+
44
+ 4. **`analyze_param_arity(args: Option<&Cirru>) -> (usize, bool)`** — helper that counts required params and detects the `&` rest marker in a `defn`/`defmacro` args list.
45
+
46
+ 5. **`analyze_code_entry`** calls `validate_def_vs_schema` to populate `schema_issues` on each `TypeCoverageRow`.
47
+
48
+ 6. **`run_check_types` output loop** prints a `schema-issues:` section for rows with non-empty issues.
49
+
50
+ 7. **10 new unit tests** covering:
51
+ - `&runtime-inplementation` skip
52
+ - Correct defn/macro → no issues
53
+ - Kind mismatch (`:fn` vs `defmacro`, `:macro` vs `defn`)
54
+ - Arity mismatch
55
+ - Rest param mismatch
56
+ - `analyze_param_arity` basics
57
+ 8. **`CR_DEBUG_SCHEMA` debug flag** — when `CR_DEBUG_SCHEMA=1`, prints per-entry schema kind debug info to stderr during `analyze check-types`.
58
+
59
+ ### `src/runner/preprocess.rs`
60
+
61
+ 1. **Runtime/preprocess enforcement added** — schema-vs-definition structural checks now run while preprocessing `defn`/`defmacro`, not only in `analyze check-types`.
62
+ 2. **`validate_def_schema_during_preprocess(...)`** — mirrors the `check-types` validation for `:kind`, required arity, and `:rest`, and raises a hard `[Type Error]` during normal execution paths such as `yarn try-rs`.
63
+ 3. **Schema hints preserved** — preprocess still injects `hint-fn`, but now only after the definition passes structural schema validation.
64
+ 4. **2 new preprocess tests** covering arity mismatch and `:kind` mismatch at preprocess time.
65
+
66
+ ### `calcit/test-hygienic.cirru`
67
+
68
+ - Updated existing test fixture schemas so they match actual code:
69
+ - `add-11` / `add-11-safe`: `:kind :macro`
70
+ - `add-2`: arg schema corrected from 2 params to 1
71
+
72
+ ### `src/snapshot.rs`
73
+
74
+ - **`test_macro_schema_round_trip`** — verifies `schema_cirru_to_edn` + `parse_fn_schema_from_edn` + `normalize_schema_edn` preserve `SchemaKind::Macro` end-to-end.
75
+ - **`test_macro_schema_full_file_round_trip`** — verifies full `CodeEntry` serialize (`From<&CodeEntry> for Edn`) → `cirru_edn::format` → `cirru_edn::parse` → `TryFrom<Edn> for CodeEntry` round-trip preserves `fn_kind: Macro`.
76
+
77
+ ## Validation Rule Summary
78
+
79
+ | Schema `:kind` | Code form | Result |
80
+ | -------------- | ------------------------- | --------------- |
81
+ | `:fn` | `defn` | ✓ ok |
82
+ | `:fn` | `defmacro` | ✗ kind mismatch |
83
+ | `:macro` | `defmacro` | ✓ ok |
84
+ | `:macro` | `defn` | ✗ kind mismatch |
85
+ | any | `&runtime-inplementation` | ✓ skip |
86
+
87
+ Arg count and rest param are checked independently of kind.
88
+
89
+ ## Notes
90
+
91
+ - **`calcit.core` schemas require binary rebuild**: Schema edits to `src/cirru/calcit-core.cirru` do not take effect at runtime until the binary is rebuilt, because the core namespace is always loaded from the embedded `include_bytes!` snapshot produced by `build.rs`. Schema validation is most useful for user-defined namespaces.
92
+ - **Normal execution now checks schemas too**: before this follow-up, schema-vs-def mismatches were only reported by `analyze check-types`; now they fail fast during normal preprocess/runtime startup as well.
93
+
94
+ ## Test Results
95
+
96
+ All 125 tests pass (99 library + 26 binary), including 2 new snapshot round-trip tests and 2 new preprocess validation tests.
@@ -0,0 +1,29 @@
1
+ # 2026-03-07 migrate hint-fn to schema for top-level defs
2
+
3
+ ## 背景
4
+
5
+ `calcit-core.cirru` 中大量顶层函数在函数体内以 `hint-fn $ {} (:return ...)` 的方式标注返回类型。这是旧写法,新写法是在 `:schema` 字段中声明 `{} (:kind :fn) (:return ...)` 等结构。
6
+
7
+ ## 本次操作
8
+
9
+ - 将所有顶层定义(`defn`/`defmacro`)的 `hint-fn` 从函数体 `[3,0]` 位置删除,改为 `edit schema` 写入 `:schema` 字段
10
+ - 共处理 100+ 个函数,包含 `calcit.core` 和 `calcit.internal` 两个 namespace
11
+ - 对带泛型的函数(`&list:filter`、`&list:map`、`&fn:bind` 等)补充了 `:generics` 字段
12
+
13
+ ## 保留 hint-fn 的情况
14
+
15
+ 内层/局部函数没有 schema 位置,仍然保留 hint-fn,例如:
16
+
17
+ - `{,}` 内的 `&{,}` 局部函数
18
+ - `map` 内的 `%map`
19
+ - `join` 内的 `%join` / `%join-str`
20
+ - `select-keys` 内的 `%select-keys`
21
+ - `&map:filter` 等内部 defn
22
+
23
+ ## 修复的 bug
24
+
25
+ - `parse_target` 在 `query.rs` / `edit.rs` 中使用 `rsplit_once('/')` 导致函数名含 `/`(如 `/`、`/=`)无法识别,改为 `split_once('/')` 修复
26
+
27
+ ## 验证
28
+
29
+ `yarn try-rs` 全程通过,最终耗时约 350ms。
@@ -0,0 +1,43 @@
1
+ # 2026-0307 移除 CalcitEnum 的 prototype 字段
2
+
3
+ ## 背景
4
+
5
+ 老版本的 `CalcitEnum` 使用 `prototype: Arc<CalcitRecord>` 存储枚举定义(字段=variant tag,值=payload 类型列表),因为当时 enum 借助 record 的数据结构来定义。现在 enum 已有独立的定义语法(`defenum`),prototype 字段冗余,予以移除。
6
+
7
+ ## 主要变更
8
+
9
+ ### `src/calcit/sum_type.rs`
10
+
11
+ - `CalcitEnum` 结构体:`prototype: Arc<CalcitRecord>` → `name: EdnTag`
12
+ - `from_record` / `from_arc`:提取 name,不再存储整个 record
13
+ - 删除 `prototype()` 方法,新增 `name()` 返回 `&EdnTag`
14
+ - 新增 `to_record_prototype() -> CalcitRecord`:根据 `name + variants` 按需重建 `CalcitRecord`,供 `preprocess.rs` 向后兼容使用
15
+
16
+ ### `src/calcit.rs`
17
+
18
+ - `Hash` 实现:改为对 variant tag + payload type 逐项哈希
19
+ - `PartialEq` 实现:`a.prototype() == b.prototype()` → `a.name() == b.name() && a.variants() == b.variants()`
20
+
21
+ ### `src/calcit/compare.rs`
22
+
23
+ - `compare_calcit_enum_values`:不再对比 prototype record,改为先比较 name,再逐 variant 比较 tag 和 payload types(深度比较),确保 `Ord::cmp == Equal` ⟺ `PartialEq::eq == true`
24
+
25
+ ### `src/data.rs`
26
+
27
+ - `Enum(enum_def)` 序列化分支:通过 `enum_def.name()` 和 `enum_def.variants()` 直接读取,不再依赖 prototype record
28
+
29
+ ### `src/runner/preprocess.rs`
30
+
31
+ - `resolve_record_value` 中所有 `Calcit::Enum(enum_def)` 分支:`enum_def.prototype().to_owned()` → `enum_def.to_record_prototype()`
32
+
33
+ ## 验证结果
34
+
35
+ - `cargo build` ✅(无警告)
36
+ - `cargo test` ✅(94 + 17 = 111 通过,0 失败)
37
+ - `cargo clippy -- -D warnings` ✅(无警告)
38
+ - `yarn check-all` ✅(exit 0)
39
+
40
+ ## 踩坑与注意
41
+
42
+ - `compare_calcit_enum_values` 最初只比 tag 未比 payload types,导致 `cmp_equal_matches_eq_for_complex_named_variants` 失败。修复时需对每个 variant 的 payload types 也做深度比较。
43
+ - `to_record_prototype()` 是按需重建而非缓存,性能上无问题(仅在类型检查预处理阶段调用)。
@@ -0,0 +1,66 @@
1
+ # 2026-03-07 schema.args 类型检查接通与 fn 类型注解修复
2
+
3
+ ## 背景
4
+
5
+ 上一次 session(commit a008f8b)为 calcit-core 的 54+ 函数添加了 `:schema` 中的 `:args` 字段。但发现这些 schema
6
+ 并未实际触发调用现场的类型检查——`CalcitFn.arg_types` 只从函数体的 `assert-type` 扫描,从未读取 schema `:args`。
7
+
8
+ ## 根因分析
9
+
10
+ 类型检查数据流:
11
+
12
+ ```
13
+ calcit-core.cirru :schema :args
14
+ → preprocess.rs 注入为 (HintFn schema_value) 进 defn 体
15
+ → syntax.rs defn 调用 detect_arg_type_hints → collect_arg_type_hints_from_body
16
+ → 只扫描 assert-type/assert-traits,忽略 HintFn!
17
+ → CalcitFn.arg_types 对 schema-only 函数全为 Dynamic
18
+ → check_user_fn_arg_types 提前返回,无任何检查
19
+ ```
20
+
21
+ ## 修复内容
22
+
23
+ ### 1. 接通 schema.args → CalcitFn.arg_types(`syntax.rs` + `type_annotation.rs`)
24
+
25
+ - 新增 `CalcitTypeAnnotation::extract_arg_types_from_hint_form(form, params)` 方法
26
+ - 新增 `parse_schema_args_types` 和 `is_args_list_head` 辅助方法
27
+ - `syntax.rs:defn` 中优先从 hint-fn(schema 注入)提取 arg_types,再回退到 assert-type 扫描
28
+
29
+ ### 2. fn 类型注解解析修复(`type_annotation.rs`)
30
+
31
+ 发现 `(:: :fn ([] 'T 'U) (:: 'T 'U) 'T)` 格式的 fn 类型注解被错误解析,因为 `[]` 头部(list constructor proc)
32
+ 出现在 args 列表中被当作普通类型处理:
33
+
34
+ - **三处** `parse_type_annotation_form` `:fn` 分支:args_form 为 List 时跳过 `[]` 头部
35
+ - **`parse_generics_list`**:跳过 `[]` 头部,使 `([] 'T 'U)` 作为合法 generics 列表(`'T 'U` 不能作 Cirru EDN operator)
36
+ - **`matches_signature`**:移除 generics 数量检查,改用 `matches_with_bindings` 解析 TypeVar 绑定(使具体函数类型能匹配泛型签名)
37
+ - **`matches_with_bindings`**:`Tag` 可满足 `DynFn`/`Fn` 约束(Calcit 中 `:tag` 作为 map key accessor 可调用)
38
+
39
+ ### 3. method 调用类型检查修复(`preprocess.rs`)
40
+
41
+ 方法调用的 arg 类型检查循环中缺少对 `Variadic` 的处理,导致 `.union s1 s2` 误报。修复为与 `check_user_fn_arg_types` 一致的 Variadic 处理。
42
+
43
+ ### 4. calcit-core.cirru schema 修正
44
+
45
+ | 函数 | 修正内容 |
46
+ | --------------- | --------------------------------------------------------------------------------- |
47
+ | `every?` | `:args $ (:: :list :dynamic)` → `:dynamic`(接受 set) |
48
+ | `keys` | `:args $ :map` → `:dynamic`(接受 record) |
49
+ | `merge` | `:args $ :map` + `:rest $ :map` → `:dynamic`(接受 record) |
50
+ | `merge-non-nil` | 同上 |
51
+ | `reduce` | fn-arg 格式 `([] 'T 'U)(:: 'T 'U)` → `([] 'T 'U)([] 'T 'U)`(正确 generics+args) |
52
+ | `map` | fn-arg 格式 `([] 'T 'U)(:: 'T)` → `([] 'T 'U)([] 'T)`(正确 generics+1-arg) |
53
+
54
+ ## 验证
55
+
56
+ - `each ([] 1 2 3) 42` → 正确警告(42 不是 :fn)
57
+ - `reduce ([] 1 2 3) 0 &+` → 无误报(&+ 满足 fn(T,U)->T)
58
+ - `cargo test`:92 passed, 0 failed(之前 1 个失败的 test_examples_field_parsing 也通过了)
59
+ - `yarn check-all`:全量集成测试通过,0 warnings
60
+
61
+ ## 关键知识点
62
+
63
+ - `([] 'T 'U)` 是合法 Cirru EDN(`[]` 是合法 operator),`('T 'U)` 不合法(`'T` 不能作 operator)
64
+ - fn 类型 generics 列表格式:`([] 'T 'U)` 跳过 `[]` 头后得到 `[T, U]`
65
+ - fn 类型 args 列表格式:`([] :number :number)` 跳过 `[]` 头后得到 `[:number, :number]`
66
+ - `matches_signature` 不应检查 generics 数量——调用方传入的具体函数不声明 generics,但 TypeVar 绑定会在 args 匹配时解析
@@ -0,0 +1,35 @@
1
+ # Schema Generics Quote Normalization
2
+
3
+ ## Summary
4
+
5
+ Tightened schema loading so legacy generic symbols stored with embedded leading quotes now fail immediately, then normalized existing `calcit-core.cirru` schema generics from `''T`-style output to the correct `'T` source syntax.
6
+
7
+ ## Key Changes
8
+
9
+ - `src/calcit/type_annotation.rs`
10
+ - Stopped serializing schema generics as `Edn::Symbol("'T")`.
11
+ - Now writes plain EDN symbols like `Edn::Symbol("T")`, which format back to source as `'T`.
12
+ - Keeps compatibility when parsing previously saved legacy symbols, but normalizes them to plain names.
13
+
14
+ - `src/snapshot.rs`
15
+ - Added load-time rejection for legacy schema generic symbols carrying embedded leading quotes.
16
+ - Normalized schema EDN → Cirru conversion to go through format+parse so quoted symbols render correctly.
17
+ - Added regression tests for:
18
+ - single-quote round-trip,
19
+ - rejecting legacy quoted EDN symbols on load,
20
+ - rejecting `''T` on schema writes.
21
+
22
+ - `build.rs`
23
+ - Added the same legacy-generic rejection during build-time loading of `src/cirru/calcit-core.cirru`, so bad schema data fails `yarn check-all` immediately.
24
+
25
+ - `src/cirru/calcit-core.cirru`
26
+ - Replaced all legacy schema generic forms like `''T`, `''A`, `''K` with correct single-quoted forms.
27
+
28
+ - `docs/CalcitAgent.md`
29
+ - Updated schema/type-annotation guidance to reflect schema-first top-level typing and correct generic syntax examples.
30
+
31
+ ## Validation
32
+
33
+ - `cargo fmt`
34
+ - `cargo test schema_ -- --nocapture`
35
+ - `yarn check-all`
@@ -0,0 +1,34 @@
1
+ # 本次修改记录
2
+
3
+ ## 主题
4
+
5
+ - 完善 schema 类型系统:区分泛型变量与命名类型引用,支持 `'Result` 一类类型引用在 schema 中稳定往返。
6
+ - 继续推进 schema-first 迁移:清理 `calcit-core` 与若干测试文件中的 `assert-type`,将约束收敛到 `:schema` 与局部 `hint-fn`。
7
+ - 强化诊断:改进运行时参数个数错误与构建期 schema 解析报错,方便定位问题。
8
+
9
+ ## 主要改动
10
+
11
+ ### 1) Rust 侧类型系统收紧
12
+
13
+ - 在 `src/calcit/type_annotation.rs` 中新增命名类型引用分支,并让解析、匹配、显示、序列化都感知泛型作用域。
14
+ - `src/builtins/syntax.rs` 与 `src/builtins/records.rs` 改为按泛型上下文解析 schema,避免把命名类型误判成 type var。
15
+ - `src/codegen/gen_ir.rs`、`src/snapshot.rs` 同步适配新 schema 结构与 round-trip 测试。
16
+
17
+ ### 2) schema / hint-fn 迁移
18
+
19
+ - `src/cirru/calcit-core.cirru` 中移除剩余 `assert-type` 调用点,改为顶层 `:schema` 或局部 `hint-fn`。
20
+ - `calcit/test.cirru`、`calcit/debug/check-args.cirru`、`calcit/test-fn.cirru`、`calcit/test-types.cirru` 改用更精细的函数签名与局部约束。
21
+ - 修正函数类型直写 schema 的参数形式,统一使用 `([] ...)` 表达参数列表。
22
+
23
+ ### 3) 错误信息增强
24
+
25
+ - `src/runner.rs` 在参数个数不匹配时生成结构化报错,而不是直接触发内部 panic。
26
+ - `build.rs` 对 schema EDN 解析错误增加截断与整理,避免输出过长、难以定位。
27
+
28
+ ## 验证
29
+
30
+ - `cargo fmt` 通过。
31
+ - `cargo clippy -- -D warnings` 通过。
32
+ - `yarn compile` 通过。
33
+ - `cargo test` 通过。
34
+ - `yarn check-all` 通过。