Commit Graph

22 Commits

Author SHA1 Message Date
6b946fb5dc refactor: replace string-based emitter with type-safe generic event system
Refactors the event emitter system from string-based messages to a
type-safe generic implementation using typed events. Consolidates
separate tracker packages into a unified plugins architecture.

Changes:
- Replace Emitter with BaseEmitter[E comparable] using generics
- Add Event type with StartEvent, StepEvent, and StopEvent constants
- Create Listener[E] interface with BaseListener implementation
- Consolidate explanation, performance, and statistics trackers into
  internal/plugins package
- Simplify main CLI by using plugin constructors instead of manual
  event subscription
- Add Items() iterator method to Set for idiomatic range loops
2026-01-13 19:27:56 -05:00
15c904ccc9 feat: improve reduction algorithm with LIFO-based iterator (#15)
## Description

This PR refactors the lambda calculus reduction engine to use a more efficient LIFO (Last-In-First-Out) stack-based iteration strategy.
Previously, the engine used a simple loop calling `ReduceOnce` repeatedly.
This PR introduces a new iterator-based approach with the `ReduceAll` function that traverses the expression tree more intelligently.

Changes include:

- Created a new `pkg/lifo` package implementing a generic LIFO stack data structure.
- Added `pkg/lambda/iterator.go` with an `Iterator` type for traversing lambda expressions.
- Refactored `pkg/lambda/reduce.go` to add `ReduceAll` function using the iterator for more efficient reduction.
- Updated `internal/engine/engine.go` to use `ReduceAll` instead of looping `ReduceOnce`.
- Renamed sample test files from `.txt` to `.test` extension.
- Fixed `.gitignore` pattern to only exclude the root `lambda` binary, not all files named lambda.
- Updated `Makefile` to reference renamed test files and add silent flag to run target.

### Decisions

- Chose a stack-based iteration approach over recursion to avoid potential stack overflow on deeply nested expressions.
- Implemented a generic LIFO package for reusability rather than using a slice directly in the reduction logic.
- Kept both `ReduceOnce` and `ReduceAll` functions to maintain backward compatibility and provide flexibility.

## Performance

Benchmark results comparing main branch vs this PR on Apple M3:

| Test | Before (ms/op) | After (ms/op) | Change |
|------|----------------|---------------|--------|
| Thunk | 0.014 | 0.014 | 0.00% |
| Fast | 1.29 | 1.20 | **-7.04%** |
| Simple | 21.51 | 6.45 | **-70.01%** |
| Church | 157.67 | 43.00 | -76.788% |
| Saccharine | 185.25 | 178.99 | **-3.38%** |

**Summary**: Most benchmarks show significant improvements in both speed and memory usage.
The Church benchmark shows a regression that needs investigation.

## Benefits

- More efficient expression tree traversal with the iterator pattern.
- Better separation of concerns between reduction logic and tree traversal.
- Generic LIFO stack can be reused in other parts of the codebase.
- Cleaner engine implementation with callback-based step emission.

## Checklist

- [x] Code follows conventional commit format.
- [x] Branch follows naming convention (`<type>/<description>`). Always use underscores.
- [ ] Tests pass (if applicable).
- [ ] Documentation updated (if applicable).

Reviewed-on: #15
Co-authored-by: M.V. Hutz <git@maximhutz.me>
Co-committed-by: M.V. Hutz <git@maximhutz.me>
2026-01-12 02:16:07 +00:00
0eff85f8fa feat: add output flag (#13)
## Description

The lambda CLI previously only wrote output to stdout using shell redirection.
This PR adds support for writing results to files using the `-o` flag.
This is implemented using a new `Destination` interface that mirrors the existing `Source` pattern.

Changes:
- Added `Destination` interface with `StdoutDestination` and `FileDestination` implementations.
- Added `-o` flag to CLI argument parser for output file specification.
- Updated `Config` to use `Destination` instead of direct output handling.
- Refactored main to use `Destination.Write()` for result output.
- Updated Makefile targets (`run`, `profile`, `explain`) to use `-o` flag instead of shell redirection.

### Decisions

The `-o` flag defaults to stdout when not specified or when set to `-`.
This maintains backward compatibility while providing explicit file output capability.

## Benefits

- Cleaner command-line interface without shell redirection.
- Symmetric design with `Source` interface for input.
- More portable across different shells and environments.
- Explicit output handling improves code clarity.

## Checklist

- [x] Code follows conventional commit format.
- [x] Branch follows naming convention (`<type>/<description>`).
- [ ] Tests pass (if applicable).
- [ ] Documentation updated (if applicable).

Reviewed-on: #13
Co-authored-by: M.V. Hutz <git@maximhutz.me>
Co-committed-by: M.V. Hutz <git@maximhutz.me>
2026-01-11 22:14:48 +00:00
62699a0e37 feat: add file input flag (#12)
## Description

The lambda CLI previously only supported inline string expressions and stdin input.
This PR adds support for reading lambda expressions from files using the `-f` flag.
This makes it easier to work with larger programs stored in files.

Changes:
- Added `FileSource` type to `internal/config/source.go` for reading from file paths.
- Added `-f` flag to CLI argument parser with validation to prevent conflicting inputs.
- Updated Makefile targets (`run`, `profile`, `explain`) to use `-f` flag instead of stdin redirection.

### Decisions

The `-f` flag takes precedence over positional arguments.
If both are specified, an error is returned to avoid ambiguity.

## Benefits

- More intuitive workflow for file-based lambda programs.
- Cleaner Makefile targets without stdin redirection.
- Consistent with common CLI conventions (e.g., `grep -f`, `awk -f`).

## Checklist

- [x] Code follows conventional commit format.
- [x] Branch follows naming convention (`<type>/<description>`).
- [ ] Tests pass (if applicable).
- [ ] Documentation updated (if applicable).

Reviewed-on: #12
Co-authored-by: M.V. Hutz <git@maximhutz.me>
Co-committed-by: M.V. Hutz <git@maximhutz.me>
2026-01-11 21:43:11 +00:00
Max
2499921679 style: moved functions around 2025-12-30 15:58:14 -05:00
Max
05cd8bc4f3 feat: meaningful comments for internal packages 2025-12-29 20:39:43 -05:00
Max
13989e4c61 style: better flag explanation 2025-12-29 20:06:35 -05:00
Max
529abb7c26 fix: clearly state fatal errors 2025-12-29 20:01:44 -05:00
Max
351faa7e08 feat: statistics flag, commented some more 2025-12-29 20:00:29 -05:00
Max
17cf8f86f8 feat: explanation as observer too 2025-12-29 01:31:09 -05:00
Max
a2ce5b6897 feat: rename profiler to performance, typeless event emitter 2025-12-29 01:15:14 -05:00
Max
c2b397a9f6 feat: observer pattern for statistics 2025-12-29 00:51:50 -05:00
Max
e9dc3fe171 feat: added optional profiling 2025-12-28 22:52:10 -05:00
Max
ee9e71d58e fix: no ds store 2025-12-28 02:07:46 -05:00
Max
0945cedf51 feat: only compute all free variables during a-conversion 2025-12-28 02:07:14 -05:00
Max
6f3b252819 style: no "this" or "self" as receiver 2025-12-26 00:00:10 -05:00
Max
e6e4a0df6f style: no punctuation or capitalization in errors 2025-12-25 23:52:39 -05:00
Max
963435c657 fix: cli.CLIOptions is repetitive 2025-12-25 23:50:17 -05:00
Max
3351eaddfc feat: better structured internal 2025-12-25 17:21:16 -05:00
Max
99703c2587 fix: unbound substitutions, explanation tag 2025-12-25 01:55:46 -05:00
Max
a56ec808ec feat: read from std in 2025-12-25 00:46:48 -05:00
Max
2c3ce9baf7 feat: wogihrsoiuvjsroirgj 2025-12-24 14:55:33 -05:00