@calcit/procs 0.12.18 → 0.12.20
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.
- package/.yarn/install-state.gz +0 -0
- package/editing-history/202504160117-wasm-codegen-and-catalog-update.md +40 -0
- package/editing-history/202507160207-wasm-encoder-migration.md +48 -0
- package/editing-history/202507161633-wasm-data-structures.md +61 -0
- package/editing-history/202604151211-record-nth-optimization.md +44 -0
- package/editing-history/20260416-1936-predicate-narrowing-expansion.md +31 -0
- package/editing-history/202604160131-wasm-math-and-test-integration.md +28 -0
- package/editing-history/202604161507-wasm-data-structures-and-rfc-rename.md +27 -0
- package/editing-history/202604161520-wasm-bitwise-and-match.md +21 -0
- package/editing-history/202604161542-wasm-cross-ns-host-imports.md +38 -0
- package/editing-history/20260417-0026-wasm-rest-args.md +62 -0
- package/editing-history/202604170048-wasm-type-of.md +70 -0
- package/editing-history/202604170051-wasm-derived-predicates.md +34 -0
- package/editing-history/202604170132-monomorphize-map-filter.md +50 -0
- package/editing-history/202604170135-monomorphize-includes-reverse.md +31 -0
- package/editing-history/202604170140-fold-type-predicates.md +44 -0
- package/editing-history/202604170154-generic-dispatch-records-tuples.md +52 -0
- package/lib/calcit.procs.mjs +39 -6
- package/lib/package.json +4 -3
- package/package.json +4 -3
- package/rfc/02-04-runtime-traits-plan.md +613 -0
- package/rfc/02-14-project-modernization-roadmap.md +229 -0
- package/rfc/02-17-register-platform-api-rfc.md +115 -0
- package/rfc/02-18-language-theory-evolution-plan.md +367 -0
- package/rfc/02-23-optional-record-macro-plan.md +30 -0
- package/rfc/03-05-function-schema-dual-track-rfc.md +162 -0
- package/rfc/03-16-runtime-boundary-refactor-plan.md +546 -0
- package/rfc/03-18-query-def-tree-show-chunked-display-plan.md +301 -0
- package/rfc/04-13-call-arg-literal-rewrite-rfc.md +205 -0
- package/rfc/04-13-type-slot-mechanism-rfc.md +194 -0
- package/rfc/04-15-match-syntax-rfc.md +175 -0
- package/rfc/04-15-type-directed-optimization-catalog.md +170 -0
- package/rfc/04-15-wasm-compilation-feasibility.md +236 -0
- package/rfc/04-16-wasm-data-structures.md +192 -0
- package/rfc/README.md +40 -0
- package/ts-src/calcit.procs.mts +33 -6
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Extend generic assoc/nth/get/count/contains?/empty?/first to records & tuples
|
|
2
|
+
|
|
3
|
+
## 背景
|
|
4
|
+
|
|
5
|
+
Recollect 升级到 `defstruct` + `%{}` 构造记录后,在 JS 运行时调用 `assoc` /
|
|
6
|
+
`nth` / `get` 等会 fallback 到 `.method`,再经过 `invoke_method` 在
|
|
7
|
+
`structRef.impls` 中查找;但默认构造的 struct 并没有自动挂上 core 的
|
|
8
|
+
`:assoc` / `:nth` / `:get` impls,导致 `Error: No implementation for ... to
|
|
9
|
+
lookup .assoc` 等。
|
|
10
|
+
|
|
11
|
+
Rust 解释器路径能自动解析到 `&record:*` 内置 proc,所以 `cr --entry test`
|
|
12
|
+
能跑过,但 JS 输出(`cr js` + Node)跑不过。
|
|
13
|
+
|
|
14
|
+
## 改动
|
|
15
|
+
|
|
16
|
+
在 `src/cirru/calcit-core.cirru` 的若干 generic 分发函数里显式增加
|
|
17
|
+
`record?` / `tuple?` 分支,直接路由到内置 proc,不再依赖 method lookup:
|
|
18
|
+
|
|
19
|
+
| 函数 | 新增分支 |
|
|
20
|
+
| ----------- | -------------------------------------------------------- |
|
|
21
|
+
| `assoc` | `record? -> &record:assoc`, `tuple? -> &tuple:assoc` |
|
|
22
|
+
| `nth` | `tuple? -> &tuple:nth`, `record? -> &record:nth` |
|
|
23
|
+
| `get` | `tuple? -> &tuple:nth`, `record? -> &record:get` |
|
|
24
|
+
| `count` | `tuple? -> &tuple:count`, `record? -> &record:count` |
|
|
25
|
+
| `contains?` | `record? -> &record:contains?` |
|
|
26
|
+
| `empty?` | `record? -> (&= 0 (&record:count x))`, tuple 同理 |
|
|
27
|
+
| `first` | `tuple? -> (&tuple:nth x 0)` |
|
|
28
|
+
|
|
29
|
+
这几处与“运行时按 `type-of` 分支”的方向是一致的——在当前 Calcit 语义下
|
|
30
|
+
records / tuples 是独立 kind,本来就应该在 generic 分发里显式处理,而不是
|
|
31
|
+
掉到“最后一条 method lookup” 的兜底里。
|
|
32
|
+
|
|
33
|
+
与此前添加的 **编译期单态化**(`try_specialize_polymorphic_call`)是互补的:
|
|
34
|
+
当静态类型已知时在预处理阶段直接改写成 proc 调用;静态类型未知时,运行时
|
|
35
|
+
分支也能正确分发到 `&record:*` / `&tuple:*`,而不再需要结构实现端配合
|
|
36
|
+
impls。
|
|
37
|
+
|
|
38
|
+
## 验证
|
|
39
|
+
|
|
40
|
+
- `cargo fmt && cargo clippy --release -- -D warnings` ✓
|
|
41
|
+
- `cargo test --release` ✓(179 + 67 全过)
|
|
42
|
+
- `yarn check-all` ✓
|
|
43
|
+
- recollect 全套:
|
|
44
|
+
- `cr --entry test` ✓
|
|
45
|
+
- `cr --entry test js && env=ci node test.mjs` ✓(此前 `.assoc` 报错修复)
|
|
46
|
+
- `cr js && yarn vite build --base=./` ✓
|
|
47
|
+
|
|
48
|
+
## 后续
|
|
49
|
+
|
|
50
|
+
随着 Calcit 继续演进,这些 chain-of-if 分发仍然是临时形态。更彻底的做法是
|
|
51
|
+
在预处理阶段通过类型推断消除所有 generic 分发 defn,让核心库只暴露
|
|
52
|
+
`&list:*` / `&map:*` / `&record:*` 等单态 proc —— 见下一步语言简化计划。
|
package/lib/calcit.procs.mjs
CHANGED
|
@@ -124,11 +124,22 @@ export let _$n_assert_traits = function (value, traitDef) {
|
|
|
124
124
|
if (!(traitDef instanceof CalcitTrait)) {
|
|
125
125
|
throw new Error(`&assert-traits expected a trait definition, but received: ${toString(traitDef, true)}`);
|
|
126
126
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
// For records/tuples, only check instance impls (not builtin fallbacks),
|
|
128
|
+
// matching the Rust runtime behavior of collect_impl_records_for_value.
|
|
129
|
+
let impls;
|
|
130
|
+
if (value instanceof CalcitRecord) {
|
|
131
|
+
impls = value.structRef.impls ?? [];
|
|
132
|
+
}
|
|
133
|
+
else if (value instanceof CalcitTuple) {
|
|
134
|
+
impls = value.impls ?? [];
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
const pair = lookup_impls(value);
|
|
138
|
+
if (pair == null) {
|
|
139
|
+
throw new Error(`&assert-traits cannot resolve impls for: ${toString(value, true)}`);
|
|
140
|
+
}
|
|
141
|
+
impls = pair[0];
|
|
130
142
|
}
|
|
131
|
-
const impls = pair[0];
|
|
132
143
|
const missing = [];
|
|
133
144
|
for (let i = 0; i < traitDef.methods.length; i++) {
|
|
134
145
|
const method = traitDef.methods[i];
|
|
@@ -1674,6 +1685,8 @@ let calcit_builtin_impls = {
|
|
|
1674
1685
|
list: null,
|
|
1675
1686
|
map: null,
|
|
1676
1687
|
fn: null,
|
|
1688
|
+
tuple: null,
|
|
1689
|
+
record: null,
|
|
1677
1690
|
};
|
|
1678
1691
|
// need to register code from outside
|
|
1679
1692
|
export let register_calcit_builtin_impls = (options) => {
|
|
@@ -1714,11 +1727,31 @@ function lookup_impls(obj) {
|
|
|
1714
1727
|
}
|
|
1715
1728
|
else if (obj instanceof CalcitRecord) {
|
|
1716
1729
|
tag = obj.name.toString();
|
|
1717
|
-
|
|
1730
|
+
let instanceImpls = obj.structRef.impls;
|
|
1731
|
+
let builtinRecordImpls = normalize_builtin_impls(calcit_builtin_impls.record);
|
|
1732
|
+
if (builtinRecordImpls && instanceImpls && instanceImpls.length > 0) {
|
|
1733
|
+
impls = [...builtinRecordImpls, ...instanceImpls];
|
|
1734
|
+
}
|
|
1735
|
+
else if (builtinRecordImpls) {
|
|
1736
|
+
impls = builtinRecordImpls;
|
|
1737
|
+
}
|
|
1738
|
+
else {
|
|
1739
|
+
impls = instanceImpls;
|
|
1740
|
+
}
|
|
1718
1741
|
}
|
|
1719
1742
|
else if (obj instanceof CalcitTuple) {
|
|
1720
1743
|
tag = obj.tag.toString();
|
|
1721
|
-
|
|
1744
|
+
let instanceImpls = obj.impls;
|
|
1745
|
+
let builtinTupleImpls = normalize_builtin_impls(calcit_builtin_impls.tuple);
|
|
1746
|
+
if (builtinTupleImpls && instanceImpls && instanceImpls.length > 0) {
|
|
1747
|
+
impls = [...builtinTupleImpls, ...instanceImpls];
|
|
1748
|
+
}
|
|
1749
|
+
else if (builtinTupleImpls) {
|
|
1750
|
+
impls = builtinTupleImpls;
|
|
1751
|
+
}
|
|
1752
|
+
else {
|
|
1753
|
+
impls = instanceImpls;
|
|
1754
|
+
}
|
|
1722
1755
|
}
|
|
1723
1756
|
else if (obj instanceof CalcitSet) {
|
|
1724
1757
|
tag = "&core-set-methods";
|
package/lib/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@calcit/procs",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.20",
|
|
4
4
|
"main": "./lib/calcit.procs.mjs",
|
|
5
5
|
"devDependencies": {
|
|
6
6
|
"@types/node": "^25.0.9",
|
|
@@ -18,12 +18,13 @@
|
|
|
18
18
|
"test-snippets": "cargo test -q snippets::tests",
|
|
19
19
|
"bench-recur-smoke": "cargo run --bin cr -- calcit/test.cirru js && node --input-type=module -e \"import { test_loop } from './js-out/test-recursion.main.mjs'; const n=3000; const t0=process.hrtime.bigint(); for(let i=0;i<n;i++) test_loop(); const dt=Number(process.hrtime.bigint()-t0)/1e6; console.log('test_loop_ms='+dt.toFixed(3));\"",
|
|
20
20
|
"check-smooth": "yarn fmt-rs && yarn lint-rs && yarn test-rs && yarn check-all",
|
|
21
|
-
"check-all": "yarn compile && yarn try-rs && yarn try-js && yarn try-ir",
|
|
21
|
+
"check-all": "yarn compile && yarn try-rs && yarn try-js && yarn try-ir && yarn try-wasm",
|
|
22
22
|
"try-rs": "cargo run --bin cr -- calcit/test.cirru",
|
|
23
23
|
"warn-dyn-method": "cargo run --bin cr -- calcit/test.cirru --warn-dyn-method",
|
|
24
24
|
"try-js-brk": "cargo run --bin cr -- calcit/test.cirru js && node --inspect-brk js-out/main.mjs",
|
|
25
25
|
"try-js": "cargo run --bin cr -- calcit/test.cirru js && node js-out/main.mjs",
|
|
26
|
-
"try-ir": "cargo run --bin cr -- calcit/test.cirru js"
|
|
26
|
+
"try-ir": "cargo run --bin cr -- calcit/test.cirru js",
|
|
27
|
+
"try-wasm": "bash scripts/test-wasm.sh"
|
|
27
28
|
},
|
|
28
29
|
"repository": {
|
|
29
30
|
"type": "git",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@calcit/procs",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.20",
|
|
4
4
|
"main": "./lib/calcit.procs.mjs",
|
|
5
5
|
"devDependencies": {
|
|
6
6
|
"@types/node": "^25.0.9",
|
|
@@ -18,12 +18,13 @@
|
|
|
18
18
|
"test-snippets": "cargo test -q snippets::tests",
|
|
19
19
|
"bench-recur-smoke": "cargo run --bin cr -- calcit/test.cirru js && node --input-type=module -e \"import { test_loop } from './js-out/test-recursion.main.mjs'; const n=3000; const t0=process.hrtime.bigint(); for(let i=0;i<n;i++) test_loop(); const dt=Number(process.hrtime.bigint()-t0)/1e6; console.log('test_loop_ms='+dt.toFixed(3));\"",
|
|
20
20
|
"check-smooth": "yarn fmt-rs && yarn lint-rs && yarn test-rs && yarn check-all",
|
|
21
|
-
"check-all": "yarn compile && yarn try-rs && yarn try-js && yarn try-ir",
|
|
21
|
+
"check-all": "yarn compile && yarn try-rs && yarn try-js && yarn try-ir && yarn try-wasm",
|
|
22
22
|
"try-rs": "cargo run --bin cr -- calcit/test.cirru",
|
|
23
23
|
"warn-dyn-method": "cargo run --bin cr -- calcit/test.cirru --warn-dyn-method",
|
|
24
24
|
"try-js-brk": "cargo run --bin cr -- calcit/test.cirru js && node --inspect-brk js-out/main.mjs",
|
|
25
25
|
"try-js": "cargo run --bin cr -- calcit/test.cirru js && node js-out/main.mjs",
|
|
26
|
-
"try-ir": "cargo run --bin cr -- calcit/test.cirru js"
|
|
26
|
+
"try-ir": "cargo run --bin cr -- calcit/test.cirru js",
|
|
27
|
+
"try-wasm": "bash scripts/test-wasm.sh"
|
|
27
28
|
},
|
|
28
29
|
"repository": {
|
|
29
30
|
"type": "git",
|