// Effect System Test: Complex Pure Computation
// =============================================
//
// What this test validates:
// - Complex pure computations with multiple branches remain pure
// - Conditional logic does not introduce effects
// - Helper functions composed together maintain purity
// - Sign, absolute value, min/max, clamp operations
//
// Expected effect inference results:
// - min(a, b) -> Pure
// - max(a, b) -> Pure
// - clamp(value, lo, hi) -> Pure
// - abs(x) -> Pure
// - sign(x) -> Pure
// - in_range(x, lo, hi) -> Pure
gene Math.Complex @0.1.0 {
"""
Complex pure computations involving multiple operations
and branching logic. All remain pure as they only
transform data without side effects.
"""
// Pure: minimum of two values
fn min(a: Int, b: Int) -> Int {
if a < b {
a
} else {
b
}
}
// Pure: maximum of two values
fn max(a: Int, b: Int) -> Int {
if a > b {
a
} else {
b
}
}
// Pure: clamp value to range [lo, hi]
// Composes min and max
fn clamp(value: Int, lo: Int, hi: Int) -> Int {
max(lo, min(value, hi))
}
// Pure: absolute value
fn abs(x: Int) -> Int {
if x < 0 {
-x
} else {
x
}
}
// Pure: sign function (-1, 0, or 1)
fn sign(x: Int) -> Int {
if x < 0 {
-1
} else if x > 0 {
1
} else {
0
}
}
// Pure: check if value is in range [lo, hi]
fn in_range(x: Int, lo: Int, hi: Int) -> Bool {
x >= lo && x <= hi
}
// Pure: distance between two points (1D)
fn distance(a: Int, b: Int) -> Int {
abs(a - b)
}
// Pure: midpoint between two values
fn midpoint(a: Int, b: Int) -> Int {
(a + b) / 2
}
// Pure: linear interpolation factor
fn lerp_factor(value: Int, start: Int, end: Int) -> Int {
if start == end {
0
} else {
(value - start) * 100 / (end - start)
}
}
// Pure: map value from one range to another
fn map_range(value: Int, in_lo: Int, in_hi: Int, out_lo: Int, out_hi: Int) -> Int {
let factor = lerp_factor(value, in_lo, in_hi);
out_lo + (out_hi - out_lo) * factor / 100
}
// Pure: three-way comparison
fn compare(a: Int, b: Int) -> Int {
if a < b {
-1
} else if a > b {
1
} else {
0
}
}
}
// Test assertions for effect inference
test effects {
assert_pure(Math.Complex.min);
assert_pure(Math.Complex.max);
assert_pure(Math.Complex.clamp);
assert_pure(Math.Complex.abs);
assert_pure(Math.Complex.sign);
assert_pure(Math.Complex.in_range);
assert_pure(Math.Complex.distance);
assert_pure(Math.Complex.midpoint);
assert_pure(Math.Complex.lerp_factor);
assert_pure(Math.Complex.map_range);
assert_pure(Math.Complex.compare);
}