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:
20
benchmarks/closures.lux
Normal file
20
benchmarks/closures.lux
Normal 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
24
benchmarks/effects.lux
Normal 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
9
benchmarks/fibonacci.lux
Normal 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)
|
||||
11
benchmarks/fibonacci_tco.lux
Normal file
11
benchmarks/fibonacci_tco.lux
Normal 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)
|
||||
18
benchmarks/list_operations.lux
Normal file
18
benchmarks/list_operations.lux
Normal 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)
|
||||
20
benchmarks/pattern_matching.lux
Normal file
20
benchmarks/pattern_matching.lux
Normal 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
15
benchmarks/strings.lux
Normal 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)
|
||||
Reference in New Issue
Block a user