Skip to content

Refactor Haskell compiler maintainability and typeclass contracts - #145

Open
Un3qual wants to merge 49 commits into
mainfrom
codex/haskell-maintainability-typeclass-audit
Open

Refactor Haskell compiler maintainability and typeclass contracts#145
Un3qual wants to merge 49 commits into
mainfrom
codex/haskell-maintainability-typeclass-audit

Conversation

@Un3qual

@Un3qual Un3qual commented Aug 16, 2026

Copy link
Copy Markdown
Owner

Summary

  • refactor the Haskell compiler around clear phase ownership and smaller navigable modules while preserving the existing public facades and compiler representations
  • centralize inference results, diagnostics, runtime outcomes, execution requests, scope/finalization contexts, and resolved-module ownership
  • split Typed Core validation, elaboration, Lowered IR lowering, runtime evaluation, and the largest Typed Core fixture/spec modules by responsibility
  • replace bespoke accumulator and enumeration helpers with actively used lawful Semigroup, Monoid, Enum, and Bounded contracts
  • derive structural NFData contracts for pure compiler products and reduce Jazz.Compiler.Force from 1,112 lines to 89 while retaining named phase boundaries
  • add formatting, totality, typeclass-law, and poisoned-thunk regression coverage to prevent the maintainability problems from returning

Why

The Haskell architecture had sound phase boundaries but accumulated oversized orchestration modules, duplicated ownership types, long positional APIs, manual structural forcing, and hand-maintained composition helpers. This refactor keeps the distinct compiler representations and proof boundaries while making responsibility and navigation explicit.

The audit also corrected one supplied-report claim: forceCompiledModules, forceExpr, forceListWith, forceSurfaceExpr, and forceTokens are active benchmark APIs. They remain supported; the structural entry points now delegate to declaration-local NFData instances.

Runtime values, closures, evaluator state, host effects, and inference's intentionally shallow pre-finalization ownership boundary do not receive blanket NFData instances. Rendered runtime-output forcing remains deliberately selective.

Impact

  • future structural fields participate in phase forcing automatically or fail compilation when they lack an intentional contract
  • accumulator laws and collision/ordering behavior are tested next to their current consumers
  • compiler phases expose smaller facades and cohesive internal modules
  • giant validation and fixture modules are split without changing language behavior
  • no universal AST, generic compiler context, phase-wide typeclass hierarchy, or speculative unused instances were introduced

Verification

  • nix --extra-experimental-features 'nix-command flakes' develop --command cabal build all -fdevelopment
  • nix --extra-experimental-features 'nix-command flakes' develop --command cabal test all -fdevelopment --test-show-details=direct --test-option=--sequential — all 63 suites passed; no failed-suite or FAIL: log entries
  • nix --extra-experimental-features 'nix-command flakes' develop --command cabal check
  • repository Haskell format checks passed for every changed file accepted by the pinned Ormolu parser
  • git diff --check

Runtime/Types.hs retains the documented formatter exception: the pinned Ormolu Haddock parser cannot parse GHC 9.14's valid data VExplicitResultHints export syntax; the development build and runtime suites cover that file.


Summary by cubic

Refactors the Haskell compiler for clearer phase ownership and smaller modules, replaces bespoke forcing/accumulators with lawful typeclass contracts, and centralizes runtime outcomes. Public behavior and representations are unchanged; manual structural forcing is replaced by declaration-local NFData without widening runtime strictness.

  • Lowering now splits into requirements, shape analysis, and emission; runtime execution is a focused façade over a dedicated evaluator engine with explicit execution requests.
  • Type inference centralizes traversal/result contracts, splits elaboration into profiles, specialization, and finalization, and prunes repository‑unused wrappers while keeping canonical entry points.
  • Replaces custom accumulators with Semigroup/Monoid; derives Enum/Bounded for surface numeric types; adds minimal law-focused tests.
  • Derives NFData for pure compiler products and reduces the forcing façade to named rnf boundaries; runtime closures/env/state remain intentionally non-NFData.
  • Splits and simplifies Typed Core validation behind one public façade; test fixtures align with the contracts they cover; semantics and diagnostic ordering remain unchanged.
  • Restores Haskell review gates: formatting via scripts/check-haskell-format.sh, rejection of partial error and qualified Map.!, and advisory HLint; adjusts Cabal warnings for the pinned formatter.
  • Diagnostics.Strictness provides the only cross‑phase diagnostic forcing; ModuleResolver drops a duplicate ResolvedModule in favor of the canonical graph artifact.

Migration

  • Replace removed Driver helpers with the canonical entry points: use runSource* or runModuleGraph* (and their Observed variants) for compilation/execution, or construct explicit runtime requests where applicable.
  • No change to benchmark callers using forceCompiledModules, forceExpr, forceListWith, forceSurfaceExpr, or forceTokens; they now delegate to local NFData instances.

Written for commit 088db94. Summary will update on new commits.

Review in cubic

Un3qual added 30 commits August 15, 2026 12:01
@codeant-ai

codeant-ai Bot commented Aug 16, 2026

Copy link
Copy Markdown

Skipping CodeAnt AI review — this PR changes more than 100 files, which usually means a migration, codemod, or vendored drop. Line-level review on diffs this large produces duplicate findings on the same rewrite pattern and drowns out anything that actually matters.

If you still want a review, comment @codeant-ai : review. For better signal, consider splitting the PR into smaller chunks.

@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 106 files, which is 6 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c3b3808d-8ad2-43f6-b8ac-aea315e440e6

📥 Commits

Reviewing files that changed from the base of the PR and between ee7176a and 088db94.

📒 Files selected for processing (106)
  • .codex/plans/2026-08-15-jazz-haskell-maintainability-design.md
  • .codex/plans/2026-08-15-jazz-haskell-maintainability-m1-invariants-ownership.md
  • .codex/plans/2026-08-15-jazz-haskell-maintainability-m2-inference-navigation.md
  • .codex/plans/2026-08-15-jazz-haskell-maintainability-m3-lowering-runtime-navigation.md
  • .codex/plans/2026-08-15-jazz-haskell-maintainability-m4-validator-tests-tooling.md
  • .codex/plans/2026-08-15-jazz-haskell-typeclass-audit-design.md
  • .codex/plans/2026-08-15-jazz-haskell-typeclass-audit-m1-composition.md
  • .codex/plans/2026-08-15-jazz-haskell-typeclass-audit-m2-nfdata.md
  • CONTRIBUTING.md
  • jazz.cabal
  • scripts/check-haskell-format.sh
  • src/Jazz/Compiler/AST.hs
  • src/Jazz/Compiler/BuiltinCatalog.hs
  • src/Jazz/Compiler/DiagnosticCatalog.hs
  • src/Jazz/Compiler/Diagnostics.hs
  • src/Jazz/Compiler/Diagnostics/Strictness.hs
  • src/Jazz/Compiler/Driver.hs
  • src/Jazz/Compiler/Force.hs
  • src/Jazz/Compiler/FractionalLiteral.hs
  • src/Jazz/Compiler/LoweredIR.hs
  • src/Jazz/Compiler/LoweredIR/Lower.hs
  • src/Jazz/Compiler/LoweredIR/Lower/Emit.hs
  • src/Jazz/Compiler/LoweredIR/Lower/Requirements.hs
  • src/Jazz/Compiler/LoweredIR/Lower/Shapes.hs
  • src/Jazz/Compiler/LoweredIR/Lower/Types.hs
  • src/Jazz/Compiler/ModuleCompiler.hs
  • src/Jazz/Compiler/ModuleExports.hs
  • src/Jazz/Compiler/ModuleGraph.hs
  • src/Jazz/Compiler/ModuleInterface.hs
  • src/Jazz/Compiler/ModuleResolver.hs
  • src/Jazz/Compiler/ModuleRuntime.hs
  • src/Jazz/Compiler/Name.hs
  • src/Jazz/Compiler/Parser/AST.hs
  • src/Jazz/Compiler/Parser/Declaration.hs
  • src/Jazz/Compiler/Parser/Expression.hs
  • src/Jazz/Compiler/Parser/Lexer.hs
  • src/Jazz/Compiler/Parser/TokenStream.hs
  • src/Jazz/Compiler/Purity.hs
  • src/Jazz/Compiler/RecursiveBindings.hs
  • src/Jazz/Compiler/Runtime.hs
  • src/Jazz/Compiler/Runtime/Engine.hs
  • src/Jazz/Compiler/Runtime/HostEvaluation.hs
  • src/Jazz/Compiler/Runtime/Observation.hs
  • src/Jazz/Compiler/Runtime/Outcome.hs
  • src/Jazz/Compiler/Runtime/Primitives.hs
  • src/Jazz/Compiler/Runtime/Request.hs
  • src/Jazz/Compiler/Runtime/Semantics.hs
  • src/Jazz/Compiler/Runtime/Types.hs
  • src/Jazz/Compiler/RuntimeHints.hs
  • src/Jazz/Compiler/TypeInference.hs
  • src/Jazz/Compiler/TypeInference/Capabilities.hs
  • src/Jazz/Compiler/TypeInference/Diagnostics.hs
  • src/Jazz/Compiler/TypeInference/Elaboration.hs
  • src/Jazz/Compiler/TypeInference/Elaboration/Finalize.hs
  • src/Jazz/Compiler/TypeInference/Elaboration/Profiles.hs
  • src/Jazz/Compiler/TypeInference/Elaboration/Specialize.hs
  • src/Jazz/Compiler/TypeInference/Elaboration/Types.hs
  • src/Jazz/Compiler/TypeInference/Operator.hs
  • src/Jazz/Compiler/TypeInference/Pattern.hs
  • src/Jazz/Compiler/TypeInference/Result.hs
  • src/Jazz/Compiler/TypeInference/Scope.hs
  • src/Jazz/Compiler/TypeInference/Traversal.hs
  • src/Jazz/Compiler/TypeInference/Types.hs
  • src/Jazz/Compiler/TypedCore.hs
  • src/Jazz/Compiler/TypedCore/Validate.hs
  • src/Jazz/Compiler/TypedCore/Validate/Declarations.hs
  • src/Jazz/Compiler/TypedCore/Validate/Evidence.hs
  • src/Jazz/Compiler/TypedCore/Validate/Expressions.hs
  • src/Jazz/Compiler/TypedCore/Validate/Internal.hs
  • src/Jazz/Compiler/TypedCore/Validate/Patterns.hs
  • src/Jazz/Compiler/TypedCore/Validate/Program.hs
  • src/Jazz/Compiler/TypedCore/Validate/TypeRecipes.hs
  • test/Jazz/Compiler/Bootstrap/CanonicalParserComparisonSpec.hs
  • test/Jazz/Compiler/Bootstrap/JazzTypedCoreContractSpec.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreContract/FixedFixtures.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreContract/Fixtures.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreContract/ManifestTests.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreContract/ParityTests.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreContract/RegressionTests.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreContract/ReviewFixtures.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreContract/Tests.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreExpressionDirectCallFixtures.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreExpressionDirectCallFixtures/CallsCaptures.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreExpressionDirectCallFixtures/LowererBoundary.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreExpressionDirectCallFixtures/ManagedText.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreExpressionDirectCallFixtures/Scalar.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreExpressionDirectCallFixtures/Source.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreExpressionDirectCallSpec.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreExpressionDirectCallSpec/BoundaryTests.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreExpressionDirectCallSpec/CallTests.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreExpressionDirectCallSpec/CaptureRecursionTests.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreExpressionDirectCallSpec/ManifestTests.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreExpressionDirectCallSpec/ScalarTextTests.hs
  • test/Jazz/Compiler/Bootstrap/TypedCoreExpressionDirectCallSpec/Support.hs
  • test/Jazz/Compiler/HaskellTypeclassContractsSpec.hs
  • test/Jazz/Compiler/Modules/ModuleResolutionSpec.hs
  • test/Jazz/Compiler/ProfilingSpec.hs
  • test/Jazz/Compiler/Runtime/ObservationSpec.hs
  • test/Jazz/Compiler/Runtime/OutcomeTests.hs
  • test/Jazz/Compiler/Semantics/BindingSignature/InferenceOwnershipTests.hs
  • test/Jazz/Compiler/Semantics/CoreNormalizationSpec.hs
  • test/Jazz/Compiler/Semantics/PatternCoverageSpec.hs
  • test/Jazz/Compiler/Semantics/Runtime/CapabilitiesTests.hs
  • test/Jazz/Compiler/Stdlib/OrderedCollectionsTests.hs
  • test/Jazz/Repository/AuditSpec.hs
  • test/Jazz/Repository/HaskellSourcePolicy.hs

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codacy-production

Copy link
Copy Markdown
Contributor

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@greptile-apps

greptile-apps Bot commented Aug 16, 2026

Copy link
Copy Markdown

Greptile Summary

This change reorganizes the Haskell compiler into focused modules for inference, elaboration, typed-core validation, lowered-IR lowering, runtime execution, diagnostics, and NFData-based forcing. It also updates Cabal registrations and separates related test fixtures and specifications.

No actionable defect was identified from the available evidence.

T-Rex validation blocked

The whole-package compilation check, cabal build all --jobs=1, could not start because the required Cabal tool is missing from PATH. The pinned environment also cannot be entered because nix and ghc are unavailable. Compilation and test execution should be completed in the repository's Nix development environment before merging.

Confidence Score: 5/5

No product defect was established, but build and test confirmation remains necessary in the supported Haskell environment.

There are no final review findings or severity-bearing execution findings. The attempted package build was blocked before compilation because the required Haskell tools are absent.

Files Needing Attention: The refactored compiler boundaries and Cabal registrations, particularly jazz.cabal, src/Jazz/Compiler/Runtime/Engine.hs, src/Jazz/Compiler/LoweredIR/Lower.hs, src/Jazz/Compiler/TypeInference/Elaboration.hs, and src/Jazz/Compiler/TypedCore/Validate.hs, should be compiled and exercised in the pinned Nix environment.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex attempted to build the refactored compiler modules by running cabal build all --jobs=1 from the project directory, but the toolchain was unavailable and the command exited with a not-found error.
  • Evidence of the blocked build attempt was captured and attached as artifacts, including the compiler contract build command script and the blocked build output.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "docs: correct forcing facade line count" | Re-trigger Greptile

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

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