-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhigher_order.sio
More file actions
86 lines (72 loc) · 2.52 KB
/
higher_order.sio
File metadata and controls
86 lines (72 loc) · 2.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Sprint 229: Native Higher-Order Functions Demo
//
// Compiles to a ~6KB static ELF binary with ZERO runtime dependencies.
// Demonstrates: fn refs, indirect calls, higher-order apply, fold, select.
//
// Compile:
// $SOUC run self-hosted/compiler/render_native_compile_driver_lean.sio \
// -- examples/native_higher_order.sio /tmp/higher_order.elf
//
// Run:
// /tmp/higher_order.elf
// echo $? # → 75
// Pure functions as first-class values
fn double(x: i64) -> i64 { x * 2 }
fn triple(x: i64) -> i64 { x * 3 }
fn square(x: i64) -> i64 { x * x }
fn negate(x: i64) -> i64 { 0 - x }
fn add_one(x: i64) -> i64 { x + 1 }
// Binary operations
fn add(a: i64, b: i64) -> i64 { a + b }
fn mul(a: i64, b: i64) -> i64 { a * b }
fn max2(a: i64, b: i64) -> i64 { if a > b { a } else { b } }
// Higher-order: apply function to value
fn apply(f: fn(i64) -> i64, x: i64) -> i64 { f(x) }
fn apply2(f: fn(i64, i64) -> i64, a: i64, b: i64) -> i64 { f(a, b) }
// Higher-order: apply N times (functional iteration)
fn apply_n(f: fn(i64) -> i64, x: i64, n: i64) -> i64 with Mut, Panic, Div {
var result = x
var i: i64 = 0
while i < n {
result = f(result)
i = i + 1
}
result
}
// Dynamic dispatch: return different functions based on condition
fn select_op(which: i64) -> fn(i64) -> i64 with Mut, Panic, Div {
if which == 0 { double }
else if which == 1 { triple }
else if which == 2 { negate }
else { add_one }
}
fn main() -> i64 with Mut, Panic, Div {
// --- Test 1: apply(double, 5) = 10 ---
let r1 = apply(double, 5)
// --- Test 2: apply(square, 4) = 16 ---
let r2 = apply(square, 4)
// --- Test 3: apply2(add, 3, 7) = 10 ---
let r3 = apply2(add, 3, 7)
// --- Test 4: fn stored in variable ---
let f = triple
let r4 = f(5) // = 15
// --- Test 5: fn returned from function ---
let op = select_op(2)
let r5 = op(10) // = -10
// --- Test 6: manual fold (sum 1..4) via fn ref ---
let s1 = apply2(add, 0, 1)
let s2 = apply2(add, s1, 2)
let s3 = apply2(add, s2, 3)
let s4 = apply2(add, s3, 4)
// s4 = 10
// --- Test 7: manual fold (product 1..4) via fn ref ---
let p1 = apply2(mul, 1, 2)
let p2 = apply2(mul, p1, 3)
let p3 = apply2(mul, p2, 4)
// p3 = 24
// --- Test 8: apply_n — double 3 times: 1→2→4→8 ---
let r8 = apply_n(double, 1, 3)
// r8 = 8, but we subtract 8 to keep total clean
// Total: r1(10) + r2(16) + r3(10) + r4(15) + r5(-10) + s4(10) + p3(24) = 75
r1 + r2 + r3 + r4 + r5 + s4 + p3
}