Skip to content

Built-in Map and Set collections (pipe-fence [|K => V|] / [|T|]) - #160

Open
assapir wants to merge 8 commits into
mainfrom
feat/map-set-collections-72
Open

Built-in Map and Set collections (pipe-fence [|K => V|] / [|T|])#160
assapir wants to merge 8 commits into
mainfrom
feat/map-set-collections-72

Conversation

@assapir

@assapir assapir commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Built-in Map and Set collection types — the first slice of #72. These are built-in parametric collection primitives (like []T), not user-defined generics.

What's implemented (built-in keys only)

  • Syntax — pipe fence. Map type [|K => V|], literal [|"a" => 1|], empty [|=>|]; Set type [|T|], literal [|"a", "b"|], empty [||]. The fence keeps a set literal distinct from an array literal.
  • Immutable / persistent — every mutating method returns a NEW collection.
  • Fail-loud access mirroring arraysm[k] returns the value and crashes on a missing key; m.get(k) is the safe Ok(v)/NotOk form.
  • Method surface — Map: get/has/set/keys/values/each + the .size field. Set: has/add/items/each + .size.
  • Set algebra+ union, - difference, +- (= -+) intersection (single-token symmetric operators; whitespace disambiguates from + -, per the locked design).
  • Native-backed by plain std::collections::HashMap/HashSet in quilon-rt over GC memory. Keys are the built-in hashable types (Num / Text / Bool; Text hashes by content, consistent with value ==).
  • Iteration order is unspecified; a fixed-seed BuildHasher keeps programs reproducible run-to-run (order is unspecified by contract, not insertion order).
  • 18 runtime intrinsics registered through the existing intrinsic_registry! macro; the intrinsic_link_test reaches every one under both linkers.

Deferred to a later slice (per #72)

  • User-defined key hashing — the %/== hooks and their compile-time pairing + debug-build consistency check.
  • remove.
  • Handing ^'s env over as a [|Text => Text|] map (and core.cli's getEnv adaptation).

Ships with

  • docs/LANGUAGE.md: Maps and Sets section, symbol-table entries, and feature-matrix rows.
  • tests/collections_test.rs: run + type-error suite; a subprocess test for the fail-loud m[k] miss.
  • examples/maps_and_sets.ql: a self-asserting demo (order-independent asserts only).

Notes for review

  • Rebased onto current main (concurrency runtime, deferred values, docs/corelib split). Conflicts were clean unions in the intrinsic registry and codegen; new MapLit/SetLit arms were added to main's post-fork deferral.rs/reachability.rs.
  • Read-only correctness + simplification review passes applied. No bugs found; cleanups (decorative comments, spelled-out identifiers) folded in.

🤖 Generated with Claude Code

assapir and others added 8 commits August 21, 2026 16:05
Lexer, parser, AST, checker, codegen, and runtime for built-in Map/Set
(pipe-fence [|K => V|] / [|T|]) all build warning-clean and pass smoke
tests via JIT and AOT. Intrinsic link gate extended. Dedicated test file,
example, and LANGUAGE.md still to come.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Also apply rustfmt to the collections codegen/runtime modules.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Correctness (from review):
- Canonicalize Num keys: -0.0 unifies with +0.0 (matches float ==), and NaN
  collapses to one self-equal key. Adds two run tests.
- Fix: an identifier map key (`[|k => v|]`) was mis-parsed as a lambda; keys
  now parse with lambda detection suppressed.
- Document the persistent-collection native-heap leak trade-off.

Simplification (from review):
- Extract build_conditional_result helper shared by array .at and map .get.
- Move Map/Set .size codegen into collections.rs reusing call_rt_int.
- Factor __set_diff/__set_intersect into set_filter; minor consistency nits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adapt the Map/Set pipeline to code that landed on main while this branch
was parked:

- Add MapLit/SetLit arms to the deferred-value analysis (deferral.rs) and
  the reachability walk (reachability.rs), both introduced after this
  branch forked. Literal keys/values/elements are strict slots that
  deliver a ready value.
- Drop collections.rs's local int_to_bool in favour of the shared helper
  main added to text.rs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Apply the read-only review passes:
- Remove the decorative section-divider banners in the collections
  codegen, runtime, and test files, and the per-intrinsic C-prototype
  comments that restated the LLVM signature on the next line; keep the
  load-bearing ABI/GC notes and short semantic annotations.
- Spell out runtime identifiers: snap_a/snap_b/snap_v become
  snapshot_a/snapshot_b/snapshot_values, key_desc becomes
  key_description; the map-literal parser's value binding is `value`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant