lambda-cat 0.1.0

Untyped lambda calculus interpreter built on comp-cat-rs. Lex, parse, and tree-walk evaluation expressed as Io effects with static dispatch and no panics.
Documentation
# lambda-cat

Untyped lambda calculus interpreter built on [comp-cat-rs](https://crates.io/crates/comp-cat-rs).

Lex, parse, and tree-walk evaluation, all expressed as `Io<Error, _>` effects with static dispatch, hand-rolled `Error`, exhaustive matches, no panics, no `mut`, no `unsafe`, no interior mutability.

## What it does

Given a source string in a small lambda calculus dialect, `lambda-cat`:

1. **Lexes** the source into tokens via a recursive functional tokenizer.
2. **Parses** the tokens into an `Expr` AST.
3. **Evaluates** the AST against a persistent environment, producing a `Value` (a closure).
4. Wraps the whole pipeline in `Io<Error, Value>` so the catamorphism only fires at the boundary.

## Grammar

```text
expr ::= var
       | "\" var "." expr           -- lambda abstraction
       | expr expr                  -- application (left-associative)
       | "let" var "=" expr "in" expr
       | "fix" var "." expr         -- fixed point (recursion)
       | "(" expr ")"

var  ::= [a-zA-Z_][a-zA-Z0-9_]*
```

Application binds tighter than abstraction and `let`.  Whitespace is insignificant.

## Usage

```rust
# fn main() -> Result<(), lambda_cat::error::Error> {
use lambda_cat::run;

let source = r"(\x. \y. x) a b";
let value = run(source).run()?;
println!("{value}");
# Ok(())
# }
```

Recursion via `fix`:

```rust
# fn main() -> Result<(), lambda_cat::error::Error> {
use lambda_cat::run;

// Church-encoded fixed-point combinator equivalent.
let source = r"
    let id = \x. x in
    let const = \x. \y. x in
    const id id
";
let _value = run(source).run()?;
# Ok(())
# }
```

## Building

```sh
cargo build
cargo test
RUSTFLAGS="-D warnings" cargo clippy --all-targets
```

## Why

This crate is **spike 1** of a comp-cat-rs reformulation of a web engine targeting Tauri integration.  It exists to falsify the hypothesis that comp-cat-rs idioms can express a stateful tree-walking interpreter cleanly.  If the spike fits, spike 2 adds ref cells + a mark-sweep GC; if both fit, the path to a comp-cat-rs JavaScript engine (and beyond, to CSS, layout, DOM, embedder, and Tauri runtime) is open.

## License

Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or [MIT license](LICENSE-MIT) at your option.