@calcit/procs 0.13.42 → 0.13.44

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 (68) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/RFCs/04-15-match-syntax-rfc.md +14 -8
  3. package/RFCs/04-15-type-directed-optimization-catalog.md +20 -14
  4. package/RFCs/08-05-systematic-nil-reduction-rfc.md +16 -5
  5. package/editing-history/20260823-0401-guard-range-progress.md +9 -0
  6. package/editing-history/20260824-0318-range-backend-consistency.md +13 -0
  7. package/editing-history/20260824-0645-unit-truthiness-review.md +6 -0
  8. package/editing-history/20260824-0655-project-module-merge-review.md +4 -0
  9. package/editing-history/20260824-0705-unit-effect-return-review.md +5 -0
  10. package/editing-history/20260824-1540-scaffold-data-kind-schema.md +6 -0
  11. package/editing-history/20260824-2119-validate-number-call-metadata.md +8 -0
  12. package/editing-history/20260824-2155-stable-js-struct-layout.md +11 -0
  13. package/editing-history/20260824-2224-struct-index-review-followups.md +7 -0
  14. package/editing-history/20260824-2233-indexed-struct-js-regressions.md +5 -0
  15. package/editing-history/20260824-2256-dynamic-method-analysis.md +9 -0
  16. package/editing-history/20260824-2329-dynamic-method-review-followups.md +7 -0
  17. package/editing-history/202608241525-release-01343.md +5 -0
  18. package/editing-history/202608241731-contiguous-executable-calls.md +34 -0
  19. package/editing-history/202608241920-borrowed-syntax-arguments.md +34 -0
  20. package/editing-history/202608241924-unify-editing-history-directory.md +7 -0
  21. package/editing-history/202608242013-typed-native-number-ops.md +34 -0
  22. package/editing-history/20260825-0020-indexed-enum-match.md +34 -0
  23. package/editing-history/20260825-0100-indexed-enum-match-validation.md +7 -0
  24. package/editing-history/20260825-0120-indexed-enum-match-review.md +7 -0
  25. package/editing-history/20260825-1215-typed-literal-paths.md +56 -0
  26. package/editing-history/20260825-1344-typed-literal-path-review.md +17 -0
  27. package/editing-history/20260825-1505-typed-method-native-op.md +23 -0
  28. package/editing-history/20260825-1540-nil-unit-runtime-separation.md +15 -0
  29. package/editing-history/20260825-1725-typed-method-error-stack-review.md +10 -0
  30. package/editing-history/20260825-1733-nil-unit-doc-review.md +5 -0
  31. package/editing-history/20260825-1758-nil-unit-review-followup.md +6 -0
  32. package/editing-history/20260825-1845-release-01344.md +6 -0
  33. package/examples/bench_enum_match.rs +41 -0
  34. package/lib/calcit-data.d.mts +4 -0
  35. package/lib/calcit-data.mjs +59 -9
  36. package/lib/calcit.procs.d.mts +17 -9
  37. package/lib/calcit.procs.mjs +104 -57
  38. package/lib/custom-formatter.mjs +12 -3
  39. package/lib/js-cirru.mjs +6 -5
  40. package/lib/js-impl.mjs +4 -3
  41. package/lib/js-primes.d.mts +1 -1
  42. package/lib/js-primes.mjs +22 -18
  43. package/lib/js-struct-def.mjs +4 -6
  44. package/lib/js-struct-value.d.mts +5 -1
  45. package/lib/js-struct-value.mjs +66 -38
  46. package/lib/package.json +8 -2
  47. package/package.json +8 -2
  48. package/ts-src/calcit-data.mts +54 -9
  49. package/ts-src/calcit.procs.mts +107 -61
  50. package/ts-src/custom-formatter.mts +12 -3
  51. package/ts-src/js-cirru.mts +6 -5
  52. package/ts-src/js-impl.mts +4 -3
  53. package/ts-src/js-primes.mts +5 -1
  54. package/ts-src/js-struct-def.mts +4 -6
  55. package/ts-src/js-struct-value.mts +78 -33
  56. /package/{history → editing-history}/202608191501-release-01326.md +0 -0
  57. /package/{history → editing-history}/202608191628-revert-transparent-union-types.md +0 -0
  58. /package/{history → editing-history}/202608191741-release-01327.md +0 -0
  59. /package/{history → editing-history}/202608212020-release-01328.md +0 -0
  60. /package/{2026082200-release-01330.md → editing-history/2026082200-release-01330.md} +0 -0
  61. /package/{2026082200-same-package-module-meta.md → editing-history/2026082200-same-package-module-meta.md} +0 -0
  62. /package/{2026082200-transitive-module-loading.md → editing-history/2026082200-transitive-module-loading.md} +0 -0
  63. /package/{2026082222-release-01331.md → editing-history/2026082222-release-01331.md} +0 -0
  64. /package/{history → editing-history}/2026082223-release-01332.md +0 -0
  65. /package/{history → editing-history}/2026082223-same-package-namespaces.md +0 -0
  66. /package/{history → editing-history}/2026082300-fix-cross-package-namespace-merge.md +0 -0
  67. /package/{history → editing-history}/2026082300-release-01333.md +0 -0
  68. /package/{history → editing-history}/2026082316-release-01334.md +0 -0
@@ -0,0 +1,41 @@
1
+ use std::hint::black_box;
2
+ use std::sync::Arc;
3
+ use std::time::Instant;
4
+
5
+ use calcit::calcit::{Calcit, CalcitEnumDef, CalcitList, CalcitStructDef, CalcitStructValue};
6
+ use cirru_edn::EdnTag;
7
+
8
+ const ITERATIONS: usize = 5_000_000;
9
+ const VARIANT_COUNT: usize = 16;
10
+
11
+ fn main() {
12
+ let fields: Vec<EdnTag> = (0..VARIANT_COUNT).map(|idx| EdnTag::new(format!("variant-{idx:02}"))).collect();
13
+ let values = vec![Calcit::from(CalcitList::Vector(vec![])); fields.len()];
14
+ let enum_def = CalcitEnumDef::from_struct(CalcitStructValue {
15
+ struct_ref: Arc::new(CalcitStructDef::from_fields(EdnTag::new("DispatchState"), fields)),
16
+ values: Arc::new(values),
17
+ })
18
+ .expect("valid benchmark enum");
19
+ let target = enum_def.variants().last().expect("last variant").tag.clone();
20
+
21
+ run("linear-tag-scan", || {
22
+ enum_def
23
+ .variants()
24
+ .iter()
25
+ .position(|variant| variant.tag == target)
26
+ .expect("target variant")
27
+ });
28
+ run("indexed-branch-slot", || enum_def.variant_index(&target).expect("target variant"));
29
+ }
30
+
31
+ fn run(label: &str, mut dispatch: impl FnMut() -> usize) {
32
+ let mut checksum = 0usize;
33
+ for _ in 0..100_000 {
34
+ checksum = checksum.wrapping_add(black_box(dispatch()));
35
+ }
36
+ let started = Instant::now();
37
+ for _ in 0..ITERATIONS {
38
+ checksum = checksum.wrapping_add(black_box(dispatch()));
39
+ }
40
+ println!("{label}: {:.2}ms checksum={checksum}", started.elapsed().as_secs_f64() * 1000.0);
41
+ }
@@ -25,6 +25,10 @@ export declare let isNestedCalcitData: (x: CalcitValue) => boolean;
25
25
  export declare let tipNestedCalcitData: (x: CalcitValue) => string;
26
26
  export type CalcitFn = (...xs: CalcitValue[]) => CalcitValue;
27
27
  export declare let getStringName: (x: CalcitValue) => string;
28
+ /** Compare tag names by Unicode scalar value, matching Rust `str` ordering. */
29
+ export declare function compareTagNames(x: CalcitTag, y: CalcitTag): number;
30
+ export declare function tagNamesAreCanonical(fields: CalcitTag[]): boolean;
31
+ export declare function canonicalizeTagPairs<T>(fields: CalcitTag[], values: T[], context: string): [CalcitTag[], T[]];
28
32
  /** returns -1 when not found */
29
33
  export declare function findInFields(xs: Array<CalcitTag>, y: CalcitTag): number;
30
34
  export declare let newTag: (content: string) => CalcitTag;
@@ -105,6 +105,51 @@ export let getStringName = (x) => {
105
105
  }
106
106
  throw new Error("Cannot get string as name");
107
107
  };
108
+ /** Compare tag names by Unicode scalar value, matching Rust `str` ordering. */
109
+ export function compareTagNames(x, y) {
110
+ let xIdx = 0;
111
+ let yIdx = 0;
112
+ while (xIdx < x.value.length && yIdx < y.value.length) {
113
+ const xCode = x.value.codePointAt(xIdx);
114
+ const yCode = y.value.codePointAt(yIdx);
115
+ if (xCode < yCode)
116
+ return -1;
117
+ if (xCode > yCode)
118
+ return 1;
119
+ xIdx += xCode > 0xffff ? 2 : 1;
120
+ yIdx += yCode > 0xffff ? 2 : 1;
121
+ }
122
+ if (xIdx < x.value.length)
123
+ return 1;
124
+ if (yIdx < y.value.length)
125
+ return -1;
126
+ return 0;
127
+ }
128
+ export function tagNamesAreCanonical(fields) {
129
+ for (let idx = 1; idx < fields.length; idx++) {
130
+ if (compareTagNames(fields[idx - 1], fields[idx]) >= 0)
131
+ return false;
132
+ }
133
+ return true;
134
+ }
135
+ export function canonicalizeTagPairs(fields, values, context) {
136
+ if (fields.length !== values.length) {
137
+ throw new Error(`${context}: fields and values length mismatch`);
138
+ }
139
+ if (tagNamesAreCanonical(fields))
140
+ return [fields, values];
141
+ const pairs = fields.map((field, idx) => [field, values[idx]]);
142
+ pairs.sort((a, b) => compareTagNames(a[0], b[0]));
143
+ for (let idx = 1; idx < pairs.length; idx++) {
144
+ if (pairs[idx - 1][0].value === pairs[idx][0].value) {
145
+ throw new Error(`${context}: duplicated field :${pairs[idx][0].value}`);
146
+ }
147
+ }
148
+ return [
149
+ pairs.map(([field]) => field),
150
+ pairs.map(([, value]) => value),
151
+ ];
152
+ }
108
153
  /** returns -1 when not found */
109
154
  export function findInFields(xs, y) {
110
155
  let low = 0;
@@ -112,10 +157,11 @@ export function findInFields(xs, y) {
112
157
  while (low <= high) {
113
158
  const mid = Math.floor((low + high) / 2);
114
159
  const midVal = xs[mid];
115
- if (midVal.idx < y.idx) {
160
+ const ordering = compareTagNames(midVal, y);
161
+ if (ordering < 0) {
116
162
  low = mid + 1;
117
163
  }
118
- else if (midVal.idx > y.idx) {
164
+ else if (ordering > 0) {
119
165
  high = mid - 1;
120
166
  }
121
167
  else {
@@ -156,6 +202,7 @@ export let castTag = (x) => {
156
202
  };
157
203
  export var refsRegistry = new Map();
158
204
  let defaultHash_nil = valueHash("nil:");
205
+ let defaultHash_unit = valueHash("unit:");
159
206
  let defaultHash_number = valueHash("number:");
160
207
  let defaultHash_string = valueHash("string:");
161
208
  let defaultHash_tag = valueHash("tag:");
@@ -177,9 +224,11 @@ let defaultHash_unknown = valueHash("unknown:");
177
224
  let fnHashCounter = 0;
178
225
  let jsObjectHashCounter = 0;
179
226
  export let hashFunction = (x) => {
180
- if (x == null) {
227
+ if (x === null) {
181
228
  return defaultHash_nil;
182
229
  }
230
+ if (x === undefined)
231
+ return defaultHash_unit;
183
232
  if (typeof x === "number") {
184
233
  return mergeValueHash(defaultHash_number, x);
185
234
  }
@@ -367,9 +416,11 @@ let hashCirru = (base, x) => {
367
416
  // Dirty code to change ternary-tree behavior
368
417
  overwriteHashGenerator(hashFunction);
369
418
  export let toString = (x, escaped, disableJsDataWarning = false) => {
370
- if (x == null) {
419
+ if (x === null) {
371
420
  return "nil";
372
421
  }
422
+ if (x === undefined)
423
+ return "&unit";
373
424
  if (typeof x === "string") {
374
425
  if (escaped) {
375
426
  // turn to visual string representation
@@ -473,9 +524,11 @@ export let to_js_data = (x, options) => {
473
524
  return to_js_data_inner(x, addColon);
474
525
  };
475
526
  let to_js_data_inner = (x, addColon) => {
476
- if (x == null) {
527
+ if (x === null) {
477
528
  return null;
478
529
  }
530
+ if (x === undefined)
531
+ return undefined;
479
532
  if (x === true || x === false) {
480
533
  return x;
481
534
  }
@@ -560,10 +613,7 @@ export let _$n__$e_ = (x, y) => {
560
613
  if (x === y) {
561
614
  return true;
562
615
  }
563
- if (x == null) {
564
- if (y == null) {
565
- return true;
566
- }
616
+ if (x === null) {
567
617
  return false;
568
618
  }
569
619
  let tx = typeof x;
@@ -18,7 +18,13 @@ export declare const calcit_package_json: {
18
18
  "test-fail": string;
19
19
  "test-snippets": string;
20
20
  "check-js-runtime": string;
21
+ "check-literal-paths": string;
22
+ "check-typed-method-rem": string;
21
23
  "bench-recur-smoke": string;
24
+ "bench-enum-match": string;
25
+ "bench-literal-paths": string;
26
+ "bench-typed-method-rem": string;
27
+ "bench-struct-index": string;
22
28
  "check-smooth": string;
23
29
  "check-all": string;
24
30
  "check-agent-interface": string;
@@ -87,7 +93,9 @@ export declare function _$n_str_$o_count(x: CalcitValue): number;
87
93
  export declare function _$n_map_$o_count(x: CalcitValue): number;
88
94
  export declare function _$n_struct_$o_count(x: CalcitValue): number;
89
95
  export declare function _$n_struct_$o_field_tag(x: CalcitValue, idx: CalcitValue): CalcitTag;
90
- export declare function _$n_struct_$o_nth(x: CalcitValue, idx: CalcitValue): CalcitValue;
96
+ export declare function _$n_struct_$o_nth(x: CalcitValue, idx: CalcitValue, field?: CalcitValue): CalcitValue;
97
+ export declare function _$n_struct_$o_assoc_at(x: CalcitValue, idx: CalcitValue, field: CalcitValue, value: CalcitValue): CalcitValue;
98
+ export declare function _$n_struct_$o_with_at(x: CalcitValue, ...triples: CalcitValue[]): CalcitValue;
91
99
  export declare function _$n_set_$o_count(x: CalcitValue): number;
92
100
  export declare let _$L_: (...xs: CalcitValue[]) => CalcitSliceList;
93
101
  export declare let _SQUO_: (...xs: CalcitValue[]) => CalcitSliceList;
@@ -119,7 +127,7 @@ export declare let _$n_enum_$o_definition: (x: CalcitEnumValue) => CalcitEnumDef
119
127
  export declare let _$n_enum_def_$o_has_variant_$q_: (enumPrototype: CalcitValue, variantTag: CalcitTag) => boolean;
120
128
  export declare let _$n_enum_def_$o_has_variant: (enumPrototype: CalcitValue, variantTag: CalcitTag) => boolean;
121
129
  export declare let _$n_enum_def_$o_variant_arity: (enumPrototype: CalcitValue, variantTag: CalcitTag) => number;
122
- export declare let _$n_enum_$o_validate: (enumValue: CalcitValue, tag: CalcitValue) => CalcitValue;
130
+ export declare let _$n_enum_$o_validate: (enumValue: CalcitValue, tag: CalcitValue) => void;
123
131
  export declare let _$n_struct_$o_get: (xs: CalcitValue, k: CalcitTag) => CalcitValue;
124
132
  export declare let _$n_list_$o_assoc: (xs: CalcitValue, k: CalcitValue, v: CalcitValue) => CalcitList;
125
133
  export declare let _$n_enum_$o_assoc: (xs: CalcitValue, k: CalcitValue, v: CalcitValue) => CalcitEnumValue;
@@ -136,10 +144,10 @@ export declare let _$n_list_$o_assoc_before: (xs: CalcitList | CalcitSliceList,
136
144
  export declare let _$n_list_$o_assoc_after: (xs: CalcitSliceList, k: number, v: CalcitValue) => CalcitList | CalcitSliceList;
137
145
  export declare let _$n_list_$o_dissoc: (xs: CalcitValue | CalcitSliceList, k: CalcitValue) => CalcitList | CalcitSliceList;
138
146
  export declare let _$n_map_$o_dissoc: (xs: CalcitValue, ...args: CalcitValue[]) => CalcitMap | CalcitSliceMap;
139
- export declare let reset_$x_: (a: CalcitRef, v: CalcitValue) => null;
140
- export declare let add_watch: (a: CalcitRef, k: CalcitTag, f: CalcitFn) => null;
141
- export declare let remove_watch: (a: CalcitRef, k: CalcitTag) => null;
142
- export declare let range: (n: number, m: number, step?: number) => CalcitSliceList | CalcitList;
147
+ export declare let reset_$x_: (a: CalcitRef, v: CalcitValue) => CalcitValue;
148
+ export declare let add_watch: (a: CalcitRef, k: CalcitTag, f: CalcitFn) => void;
149
+ export declare let remove_watch: (a: CalcitRef, k: CalcitTag) => void;
150
+ export declare let range: (n: number, m?: number, step?: number) => CalcitSliceList;
143
151
  export declare function _$n_list_$o_empty_$q_(xs: CalcitValue): boolean;
144
152
  export declare function _$n_str_$o_empty_$q_(xs: CalcitValue): boolean;
145
153
  export declare function _$n_map_$o_empty_$q_(xs: CalcitValue): boolean;
@@ -149,7 +157,7 @@ export declare let _$n_list_$o_last: (xs: CalcitValue) => CalcitValue;
149
157
  export declare let _$n_str_$o_first: (xs: CalcitValue) => CalcitValue;
150
158
  export declare let _$n_map_$o_destruct: (xs: CalcitValue) => CalcitValue;
151
159
  export declare let _$n_set_$o_destruct: (xs: CalcitValue) => CalcitValue;
152
- export declare let timeout_call: (duration: number, f: CalcitFn) => null;
160
+ export declare let timeout_call: (duration: number, f: CalcitFn) => void;
153
161
  export declare let _$n_list_$o_rest: (xs: CalcitValue) => CalcitList | CalcitSliceList;
154
162
  export declare let _$n_str_$o_rest: (xs: CalcitValue) => CalcitValue;
155
163
  export declare let recur: (...xs: CalcitValue[]) => CalcitRecur;
@@ -162,7 +170,7 @@ export declare let butlast: (xs: CalcitValue) => CalcitList | CalcitSliceList |
162
170
  export declare let initCrTernary: (x: string) => CalcitValue;
163
171
  export declare let _SHA__$M_: (...xs: CalcitValue[]) => CalcitValue;
164
172
  export declare let generate_id_$x_: () => string;
165
- export declare let _$n_display_stack: () => null;
173
+ export declare let _$n_display_stack: () => void;
166
174
  export declare let _$n_list_$o_slice: (xs: CalcitList, from: number, to: number) => CalcitSliceList | CalcitList;
167
175
  export declare let _$n_list_$o_concat: (...lists: (CalcitList | CalcitSliceList)[]) => CalcitList | CalcitSliceList;
168
176
  export declare let _$n_list_$o_reverse: (xs: CalcitList) => CalcitList;
@@ -247,7 +255,7 @@ export declare let parse_cirru: (code: string) => CalcitCirruQuote;
247
255
  export declare let parse_cirru_list: (code: string) => CalcitList;
248
256
  export declare let parse_cirru_edn: (code: string, options: CalcitValue) => CalcitValue;
249
257
  type DataShapeNode = {
250
- kind: "unit" | "bool" | "number" | "string" | "symbol" | "tag" | "buffer" | "cirru-quote" | "dynamic";
258
+ kind: "nil" | "unit" | "bool" | "number" | "string" | "symbol" | "tag" | "buffer" | "cirru-quote" | "dynamic";
251
259
  } | {
252
260
  kind: "optional" | "list" | "set" | "ref";
253
261
  inner: number;