fix: make all example programs work correctly

- Add string concatenation support to + operator in typechecker
- Register ADT constructors in both type environment and interpreter
- Bind handlers as values so they can be referenced in run...with
- Fix effect checking to use subset instead of exact match
- Add built-in effects (Console, Fail, State) to run block contexts
- Suppress dead code warnings in diagnostics, modules, parser

Update all example programs with:
- Expected output documented in comments
- Proper run...with statements to execute code

Add new example programs:
- behavioral.lux: pure, idempotent, deterministic, commutative functions
- pipelines.lux: pipe operator demonstrations
- statemachine.lux: ADT-based state machines
- tailcall.lux: tail call optimization examples
- traits.lux: type classes and pattern matching

Add documentation:
- docs/IMPLEMENTATION_PLAN.md: feature roadmap and status
- docs/PERFORMANCE_AND_TRADEOFFS.md: performance analysis

Add benchmarks for performance testing.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 09:05:06 -05:00
parent 20bf75a5f8
commit 15a820a467
25 changed files with 1210 additions and 28 deletions

20
benchmarks/closures.lux Normal file
View File

@@ -0,0 +1,20 @@
// Benchmark: Closure creation and calls (measures closure overhead)
// Tests: Closure capture, higher-order functions
fn makeAdder(n: Int): fn(Int): Int =
fn(x: Int): Int => x + n
fn applyN(f: fn(Int): Int, x: Int, n: Int): Int =
if n <= 0 then x
else applyN(f, f(x), n - 1)
// Create 1000 closures and apply them
fn benchmark(count: Int): Int =
if count <= 0 then 0
else {
let adder = makeAdder(count)
let result = applyN(adder, 0, 100)
result + benchmark(count - 1)
}
let result = benchmark(1000)

24
benchmarks/effects.lux Normal file
View File

@@ -0,0 +1,24 @@
// Benchmark: Effect handling (measures effect overhead)
// Tests: Effect dispatch, handler lookup, effect calls
effect Counter {
fn increment(): Unit
fn get(): Int
}
fn countTo(n: Int): Int with {Counter} =
if n <= 0 then Counter.get()
else {
Counter.increment()
countTo(n - 1)
}
handler counterHandler: Counter {
fn increment() = ()
fn get() = 0
}
// Run the effect benchmark
let result = run countTo(10000) with {
Counter = counterHandler
}

9
benchmarks/fibonacci.lux Normal file
View File

@@ -0,0 +1,9 @@
// Benchmark: Recursive Fibonacci (measures call overhead)
// Tests: Function call performance, recursion overhead
fn fib(n: Int): Int =
if n <= 1 then n
else fib(n - 1) + fib(n - 2)
// Calculate fib(30) - about 1 million calls
let result = fib(30)

View File

@@ -0,0 +1,11 @@
// Benchmark: Tail-recursive Fibonacci (measures TCO efficiency)
// Tests: Tail call optimization, accumulator pattern
fn fibTCO(n: Int, a: Int, b: Int): Int =
if n <= 0 then a
else fibTCO(n - 1, b, a + b)
fn fib(n: Int): Int = fibTCO(n, 0, 1)
// Calculate fib(100000) - many iterations, constant stack
let result = fib(100000)

View File

@@ -0,0 +1,18 @@
// Benchmark: List operations (measures collection performance)
// Tests: List creation, map, filter, fold
fn square(x: Int): Int = x * x
fn isEven(x: Int): Bool = x % 2 == 0
fn add(acc: Int, x: Int): Int = acc + x
// Create a list of 10000 elements
let numbers = List.range(1, 10000)
// Map: square each element
let squared = List.map(square, numbers)
// Filter: keep only even numbers
let evens = List.filter(isEven, squared)
// Fold: sum all values
let sumResult = List.fold(0, add, evens)

View File

@@ -0,0 +1,20 @@
// Benchmark: Pattern matching (measures ADT performance)
// Tests: Constructor creation, pattern matching, recursion
type Tree =
| Leaf(Int)
| Node(Tree, Tree)
fn sumTree(tree: Tree): Int =
match tree {
Leaf(n) => n,
Node(left, right) => sumTree(left) + sumTree(right)
}
fn buildTree(depth: Int, value: Int): Tree =
if depth <= 0 then Leaf(value)
else Node(buildTree(depth - 1, value), buildTree(depth - 1, value + 1))
// Build a tree of depth 15 (32767 nodes) and sum it
let tree = buildTree(15, 1)
let sumResult = sumTree(tree)

15
benchmarks/strings.lux Normal file
View File

@@ -0,0 +1,15 @@
// Benchmark: String operations (measures string performance)
// Tests: String concatenation, conversion, manipulation
fn buildString(n: Int, acc: String): String =
if n <= 0 then acc
else buildString(n - 1, acc + toString(n) + " ")
fn countWords(s: String): Int =
List.length(String.split(s, " "))
// Build a string with 1000 numbers
let longString = buildString(1000, "")
// Count words in the string
let wordCount = countWords(longString)