Skip to content

Add str/prn for Diff, refactor unified, add unified-with-context#9

Merged
hellerve merged 1 commit into
masterfrom
claude/str-prn-unified-refactor
Jun 22, 2026
Merged

Add str/prn for Diff, refactor unified, add unified-with-context#9
hellerve merged 1 commit into
masterfrom
claude/str-prn-unified-refactor

Conversation

@carpentry-agent

Copy link
Copy Markdown

Summary

  • str/prn for the Diff type: the Diff sumtype now implements both interfaces, so diffs can be printed and formatted (e.g. (str &(Eq [1 2 3]))"(Eq [1 2 3])")
  • Refactored unified: eliminated O(n²) string accumulation (now collects hunk strings in an array and concatenates once at the end) and deduplicated the hunk-start logic that was copy-pasted across the Deletion and Insertion branches (now a single when-do block before the match-ref)
  • unified-with-context: new public function that takes the number of context lines as a parameter; unified now delegates to it with 3. Renamed the internal emit-hunk (which accumulated into the result string) to format-hunk (which returns a single hunk string)
  • Tests: 8 new tests covering str on all three variants, unified-with-context with 0/1/3 context lines, and equivalence with unified

All 62 tests pass. carp-fmt and angler clean.


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

@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

CI: pass (ubuntu-latest, macos-latest) — all 62 tests pass (54 existing + 8 new).
Local build: no Carp compiler available on this machine — relied on CI.

Findings

Reviewed all changed code in diff.carp (lines 14-266) and all 8 new tests in tests/diff.carp (lines 313-381).

str/prn (lines 14-26): correct

Both use match-ref (borrowing), dispatch to the inner type's str/prn, and wrap with the variant name. Standard Carp pattern for sumtype printing. implements declarations are present.

format-hunk rename (lines 144-159): correct

Renamed from emit-hunk, now returns a single hunk string instead of concatenating onto the accumulator. Clean separation of concerns.

change? helper (line 142): correct

Returns false for Eq, true for Insertion/Deletion. Used to deduplicate the hunk-start logic.

unified-with-context refactoring (lines 165-261): correct

Verified the refactoring preserves behavior by tracing through several cases:

  1. Hunk-start deduplication: the when-do (and (not in-hunk) (change? elem)) block (lines 181-189) runs before the match-ref, correctly replacing the identical unless-do in-hunk blocks that were duplicated in the old Deletion and Insertion branches. Since change? returns false for Eq, the when-do never fires for context lines. ✓

  2. O(n²) elimination: result accumulation changed from (String.concat &[output header ... body ...]) (copying the entire string on each hunk emission) to collecting into a hunks array and concatenating once at the end (line 261). Genuine asymptotic improvement for multi-hunk diffs. ✓

  3. ctx=0: traced through manually — trailing = min(0, n) = 0 and leading = min(0, ...) = 0 correctly suppress all context lines. The test at line 332 confirms. ✓

  4. ctx=1 multi-hunk: traced through — two hunks with 3 intervening Eq lines (gap > 2*ctx) correctly split into separate hunks. The test at line 359 confirms. ✓

  5. Edge case — change at start of diff: lead-lines is empty initially, so hunk-lines starts empty, hunk-old-count = 0. Context is only appended after the change. ✓

  6. Edge case — change at end of diff: the post-loop when in-hunk (line 254) correctly emits the final hunk. ✓

unified delegation (line 266): correct

(defn unified [d] (unified-with-context d 3)) — matches the original hardcoded context of 3. The test at line 350 explicitly checks unified and unified-with-context 3 produce identical output.

Minor notes (non-blocking)

  • No test for prn output (only str is tested). For integer arrays they produce the same output, so this is cosmetic. Would be meaningful for (Diff String) where prn quotes strings.
  • No CHANGELOG in this repo.

Verdict: merge

Clean, well-motivated refactoring. The O(n²) fix is genuine. Hunk-start deduplication reduces 15 lines of copy-paste to a single when-do block. unified-with-context is a useful addition. All 62 tests pass. No bugs found.

@hellerve hellerve marked this pull request as ready for review June 22, 2026 07:52
@hellerve hellerve merged commit c18173d into master Jun 22, 2026
2 checks passed
@hellerve hellerve deleted the claude/str-prn-unified-refactor branch June 22, 2026 07:52
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