Skip to content

Add missing List ops; short-circuit any?/all? in all types#13

Open
carpentry-agent[bot] wants to merge 1 commit into
mainfrom
claude/list-ops-short-circuit
Open

Add missing List ops; short-circuit any?/all? in all types#13
carpentry-agent[bot] wants to merge 1 commit into
mainfrom
claude/list-ops-short-circuit

Conversation

@carpentry-agent

Copy link
Copy Markdown

Summary

  • New List operations: nth, take, find, contains? — basic operations users expect from a persistent list (O(n) element access, prefix slicing, search, membership test), all with proper early exit.
  • Short-circuiting any?/all?: Rewrote both predicates across all 11 collection types (List, Queue, Deque, Trie, Ordered Map, Ordered Set, Heap, Hash Map, Hash Set, Vector) to stop as soon as the answer is known instead of walking every element via reduce.

What changed per type

Type any?/all? approach
List Manual linked-list walk with early exit
Queue, Deque Delegate to List's short-circuiting versions (front then reversed rear)
Trie Stack-based DFS with exit flag
Ordered Map In-order BST traversal with exit flag
Ordered Set Delegates to Ordered Map
Heap Stack-based DFS with exit flag
Hash Map HAMT node traversal with exit flag
Hash Set Delegates to Hash Map
Vector Index loop with exit flag

Test plan

  • All 40 list tests pass (12 new for nth/take/find/contains?)
  • All existing tests pass across queue, deque, ord-map, ord-set, heap, hash-map, hash-set, vector
  • carp-fmt -c clean
  • angler findings fixed in new code

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

Add nth, take, find, and contains? to persistent List. Rewrite any?
and all? for all 11 collection types to short-circuit instead of
walking every element via reduce.

@carpentry-reviewer carpentry-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build & Tests

Build: compiles cleanly on ARM Linux.
Tests: all 236 tests pass across 9 collection types (list 41, queue 26, deque 24, ord-map 35, ord-set 23, heap 16, hash-map 28, hash-set 22, vector 21). Trie tests crash under ASan on ARM due to a pre-existing stack overflow in get-in-siblings (confirmed on main — not introduced by this PR).
CI: passing on both macos-latest and ubuntu-latest.

Findings

1. Hash map any?/all? don't fully short-circuit within collision/bitmap nodes (persistent.carp:3292–3305). The for loop continues iterating after result is set — the guard (when (and (not result) ...)) prevents work but not iteration. In practice this is harmless since collision nodes are typically small and HAMT bitmap nodes have at most 32 slots, but it's worth knowing it's O(node-size) per node rather than truly breaking out.

2. All four new list operations are correct:

  • nth (line 248): bounds-checked with negative index handling, O(n) traversal with early exit on Maybe.Nothing.
  • take (line 268): clamps n to list length, builds in reverse then calls reverse — correct order.
  • find (line 290): early exit on match via keep-going flag.
  • contains? (line 308): early exit on equality match.

3. All any?/all? rewrites are correct across all 11 collection types. Each uses an appropriate traversal strategy:

  • List: manual walk with keep-going flag
  • Queue/Deque: delegate to list's short-circuiting versions (front then reversed rear)
  • Trie: stack-based DFS maintaining a path array for key reconstruction — complex but well-structured
  • Ordered Map: Morris-style in-order traversal with explicit stack — correct
  • Ordered Set: delegates to Ordered Map
  • Heap: stack-based DFS over left/right children
  • Hash Map: stack-based HAMT traversal with per-node for loops (see finding #1)
  • Hash Set: delegates to Hash Map
  • Vector: index loop with (< i n) and result flag

4. deftemplate formatting changes (lines 9–19) are whitespace-only reformatting of popcount and array-reserve!. Correct and harmless.

Verdict: merge

Large but well-structured change. All 236 tests pass, CI is green. Finding #1 is a minor performance note, not a correctness issue. The new list operations fill real gaps, and the any?/all? rewrites correctly eliminate the reduce-based full traversal across all collection types.

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.

0 participants