Skip to content

Add map, filter, and reverse to persistent data structures#3

Merged
hellerve merged 1 commit into
mainfrom
claude/map-filter-ops
May 21, 2026
Merged

Add map, filter, and reverse to persistent data structures#3
hellerve merged 1 commit into
mainfrom
claude/map-filter-ops

Conversation

@carpentry-agent

Copy link
Copy Markdown

Summary

Add fundamental FP transformation operations to all persistent data structures:

  • Lists: reverse, map, filter
  • Queues: map, filter
  • Deques: map, filter
  • Tries: map-values, filter
  • Ordered maps: map-values, filter
  • Hash maps: map-values, filter

All implementations build on the existing reduce infrastructure. Map types use map-values (rather than map) since the key type is fixed by the structure's type parameter. List map and filter use reduce-then-reverse to preserve element order. Hash-map map-values/filter use trie-reduce-values directly rather than going through reduce, working around a pre-existing nested closure capture bug in hash-map's reduce that causes a segfault on ARM64.

Comprehensive tests are included for every new operation across all six data structures.

Note: The hash-map test file has a pre-existing segfault on ARM64 caused by the Carp compiler generating broken code for the nested closure pattern in IntIntMap.reduce (and transitively IntIntMap.=). This affects the existing reduce and = tests, not the new map-values/filter tests. The new operations were verified independently.


Opened by the carpentry-org heartbeat agent (Claude). Veit has not reviewed this yet.

Add map/filter operations to lists, queues, deques, tries, ord-maps,
and hash-maps. Lists also get reverse. Map types get map-values
(since keys are fixed by the type). All implementations use the
existing reduce infrastructure for simplicity and correctness.

Hash-map map-values/filter use trie-reduce-values directly to avoid
a pre-existing nested closure capture bug in hash-map reduce.
@hellerve

Copy link
Copy Markdown
Member

Build & Tests

Built and ran all test suites locally (ARM64):

  • persistent_list: 20/20 pass
  • persistent_queue: 18/18 pass
  • persistent_trie: 19/19 pass
  • persistent_deque: 16/16 pass
  • persistent_ord_map: 16/16 pass
  • persistent_hash_map: crashes on ARM64 — pre-existing (same crash on main), caused by a compiler bug with nested closure captures in IntIntMap.reduce/=. Not introduced by this PR.

CI checks are still pending on GitHub.

Findings

  1. Implementations are correct. All six data structures (list, queue, deque, trie, ord-map, hash-map) get consistent map/filter operations built on reduce. List additionally gets reverse. The reduce-then-reverse pattern for list map and filter correctly preserves element order. Queue/deque use their natural insertion operations (enqueue/push-back) during reduce, which preserves FIFO/front-to-back order.

  2. Hash-map workaround is sound. Using %trie-reduce-values directly instead of reduce to avoid the nested closure capture segfault is the right call. The implementations iterate over hash buckets manually and re-insert via insert, which handles rehashing correctly.

  3. Type signatures are appropriate. Map types use map-values (not map) since the key type is fixed by the structure's type parameter. The function signature (Fn [%value-type] %value-type) constrains mapping to same-type transforms, which is inherent to Carp's monomorphized container model.

  4. Tests are thorough. Each structure has tests for: basic operation, empty input, always-false predicate, and always-true predicate. List additionally tests reverse on empty, singleton, and multi-element. Memory-balance tests retained.

  5. Formatting noise. The diff includes substantial whitespace-only reformatting in the test files (single-lining short let bodies, collapsing (do (ignore ...) ...), adjusting and clause indentation). None of this is wrong, but it makes the diff ~2x larger than the actual logic changes and could cause merge conflicts with other branches.

  6. No bugs found. I traced through the map/filter logic for each structure, verified order preservation, checked that reduce callbacks handle ownership correctly (@ copies where needed, references where not), and confirmed the test assertions match expected behavior.

Verdict: revise

The code is correct and well-tested, but CI is still pending — wait for checks to pass before merging. If CI passes, this is a clean merge.

@hellerve hellerve marked this pull request as ready for review May 21, 2026 19:06
@hellerve hellerve merged commit 7e07f0e into main May 21, 2026
0 of 2 checks passed
@hellerve hellerve deleted the claude/map-filter-ops branch May 21, 2026 19:06
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