How nbun/efci works
1. This is a Haskell-based Curry interpreter. The repository is split into a small executable front end, an interpreter/runtime core, a transformation layer, and a set of effect handlers that model Curry semantics such as nondeterminism, state, reader context, memoization, error handling, and IO.
2. The executable entry point is app/Main.hs, which wires the CLI/REPL behavior to the interpreter code in src/. src/App.hs is the top-level application orchestration module, while the user-facing commands described in the README (:q, :o, :time, :fcy) indicate an interactive interpreter loop rather than a batch compiler.
3. Source programs are Curry files (.curry). The repository includes a curry-frontend submodule, which is the external frontend used to parse/translate Curry source into FlatCurry, the intermediate representation used by this interpreter. The bundled data/Prelude.curry and benchmarks/data/Prelude.curry show that Prelude loading is part of the normal runtime setup.
4. The core execution pipeline appears to be: Curry source or interactive input → frontend-generated FlatCurry → internal transformation/intermediate forms → effectful evaluation. src/Pipeline.hs is the obvious coordination point for these stages, and src/Transformation/FCY2AE.hs suggests a translation from FlatCurry into an algebraic-effects-based representation.
5. The interpreter itself is split across multiple execution styles or evaluation layers. src/InterpFL.hs suggests a FlatCurry interpreter, while src/Monolith.hs implies an alternative “all-in-one” interpreter path. The README’s “rotate between interpretation modes” strongly suggests the CLI can switch among these modes at runtime.
6. Effects are the main architectural boundary. Under src/Effect/General/ are reusable effect handlers for Error, Memoization, ND (nondeterminism), Reader, and State. Under src/Effect/FlatCurry/ are handlers specialized to FlatCurry constructs such as constructors, declarations, functions, let-bindings, and IO. This indicates the interpreter is structured as a stack of effect handlers rather than a single monolithic evaluator.
7. The effect infrastructure is supported by generic runtime machinery in src/Free.hs, src/DelCont.hs, and src/Data/Union.hs. These modules likely implement the underlying free/effect representation, delimited continuations, and type-safe effect unions used by the handlers. src/Signature.hs and src/Type.hs appear to define the typed interface for operations and Curry/FlatCurry types.
8. src/Debug.hs is a supporting diagnostics layer, likely used for tracing or development output. This is consistent with an interpreter project where visibility into evaluation order, sharing, and nondeterminism is important.
9. examples/ contains small Curry programs used to exercise language features such as arithmetic, binary data, nondeterminism, sharing semantics, and special effects. benchmarks/ contains larger benchmark programs plus a benchmark driver (benchmarks/Main.hs) and benchmark output (benchmarks/result/bench.csv), showing that performance and semantics across different evaluation strategies are both first-class concerns.
10. tests/Main.hs provides the test entry point, while stack.yaml, effective-curry-interpreter.cabal, and fourmolu.yaml show the project is built and formatted as a standard Haskell package. The README’s note about “not all external functions are implemented” implies there is a runtime boundary between the interpreted Curry core and host-provided primitives.
11. A useful architecture diagram would show three external inputs feeding the system: interactive user expressions, Curry source modules, and benchmark/example programs. Those all flow into the frontend/FlatCurry layer, then into the effect-based interpreter, and finally back to the REPL/benchmark/test harness as evaluated results, nondeterministic outcomes, or runtime errors.
Main entry points: General General effects · Pipeline.hs Pipeline · FlatCurry FlatCurry effects · App.hs App
Components 29
Front end
User entrypoints and project-facing orchestration.
Core pipeline
Translation and interpreter coordination.
- Pipeline · Coordinates source loading, translation, and execution stages.
src/Pipeline.hs - FCY2AE · Transforms FlatCurry into an algebraic-effects representation.
src/Transformation/FCY2AE.hs - InterpFL · Interpreter path specialized around FlatCurry evaluation.
src/InterpFL.hs - Monolith · Alternative all-in-one evaluation path.
src/Monolith.hs - Frontend · External Curry frontend used to parse and produce FlatCurry.
curry-frontend
Effect runtime
General effect machinery and FlatCurry-specific handlers.
- General effects · Reusable handlers for core computational effects.
src/Effect/General - ND · Branches and searches through multiple outcomes.
src/Effect/General/ND.hs - State · Threaded interpreter state.
src/Effect/General/State.hs - Reader · Shared read-only execution context.
src/Effect/General/Reader.hs - Error · Runtime error and exception handling.
src/Effect/General/Error.hs - Memoization · Caches results to preserve sharing semantics.
src/Effect/General/Memoization.hs - FlatCurry effects · Handlers specialized to FlatCurry constructs.
src/Effect/FlatCurry - Constructors · Handles data constructor evaluation.
src/Effect/FlatCurry/Constructor.hs - Declarations · Processes declarations and bindings.
src/Effect/FlatCurry/Declarations.hs - Functions · Evaluates function application and rules.
src/Effect/FlatCurry/Function.hs - Let · Models let-bound sharing and scope.
src/Effect/FlatCurry/Let.hs - IO · Bridges interpreted code to host-provided IO.
src/Effect/FlatCurry/IO.hs
Support
Types, debugging, and runtime plumbing.
- Free · Core free/effect representation utilities.
src/Free.hs - DelCont · Delimited continuation machinery used by effects.
src/DelCont.hs - Union · Type-safe union for composing effects.
src/Data/Union.hs - Signature · Typed operation signatures for effects and evaluation.
src/Signature.hs - Type · Curry and FlatCurry type representations.
src/Type.hs - Debug · Diagnostics and tracing support.
src/Debug.hs
Inputs and workloads
Curry programs used by the interpreter, examples, and benchmarks.
- Prelude · Bundled Curry Prelude loaded at runtime.
data/Prelude.curry - Examples · Small programs covering language features and semantics.
examples - Benchmarks · Benchmark suite and results for evaluation strategies.
benchmarks
Connections 31
- Main → App: starts · Executable delegates to application orchestration.
- App → Pipeline: drives · App wires CLI/REPL commands into the processing pipeline.
- Pipeline → Frontend: parses · Source Curry modules are translated through the external frontend.
- Pipeline → FCY2AE: transforms · FlatCurry is lowered into the effect-based internal form.
- Pipeline → InterpFL: evaluates · One execution mode runs the FlatCurry interpreter path.
- Pipeline → Monolith: evaluates · Another execution mode uses the monolithic evaluator.
- Pipeline → Prelude: loads · Prelude is part of normal runtime initialization.
- InterpFL → FlatCurry effects: uses · Interpreter evaluation is assembled from FlatCurry effect handlers.
- Monolith → General effects: uses · Monolithic path still relies on the shared effect runtime.
- FCY2AE → General effects: targets · Translation produces structures consumed by general effect handlers.
- FlatCurry effects → Constructors: includes · Constructor semantics are handled separately.
- FlatCurry effects → Declarations: includes · Declaration processing is a dedicated handler.
- FlatCurry effects → Functions: includes · Function evaluation is a dedicated handler.
- FlatCurry effects → Let: includes · Let-binding semantics and sharing are handled explicitly.
- FlatCurry effects → IO: includes · IO is bridged through a specialized handler.
- General effects → ND: contains · Nondeterminism is one of the core general effects.
- General effects → State: contains · State is threaded through execution via effects.
- General effects → Reader: contains · Read-only interpreter context is provided by Reader.
- General effects → Error: contains · Runtime failures are represented as an effect.
- General effects → Memoization: contains · Memoization preserves sharing and avoids recomputation.
- General effects → Free: built on · Effect handlers are supported by the free-effect core.
- General effects → DelCont: built on · Delimited continuations support effect resumption.
- General effects → Union: built on · Typed unions compose the effect stack.
- General effects → Signature: uses · Operations are described through typed signatures.
- General effects → Type: uses · Evaluation and effect interfaces depend on Curry types.
- App → Debug: traces · Diagnostics support interactive debugging and evaluation visibility.
- Tests → Pipeline: exercises · Tests invoke the interpreter pipeline.
- Benchmarks → Pipeline: measures · Benchmarks compare interpretation strategies and performance.
- Examples → Frontend: feeds · Example Curry programs are parsed through the frontend.
- Benchmarks → Prelude: depends on · Benchmark programs also rely on the bundled Prelude.
- IO → Error: reports · IO boundaries can surface runtime errors.