pipe
Fused pipelines: lists.fuse! runs map and filter stages over a list as
one loop, with no list in between. Written with lists.map and
lists.filter, the same pipeline builds a new list at every stage; fused,
it runs about three times as fast natively, as fast as the loop written
out by hand.
fuse! is a macro in lib/lists.jh, written in jihoo. It runs on the VM
while compiling: it takes the stages as code, any number of them, reads each
with meta.node to see map(f) or filter(g), asks type_of what type
the last stage gives, and puts it all together into one for loop in a
block expression. See the design in docs/internals/code-as-data.md.
jihoo run examples/pipe.jhimport lists
fn main() { let xs: [i64] = [] for i in 0..1000 { push(xs, i % 100) } let k = 7
// With a list for `map` and another for `filter`. let ys = lists.map(xs, fn(x) -> i64 { return x * 3 + k }) let zs = lists.filter(ys, fn(x) { return x % 2 == 0 }) print(lists.fold(zs, 0, fn(a, x) { return a + x }))
// Fused: one loop, no list in between. Prints the same. let s = lists.fuse!(xs, map(fn(x: i64) -> i64 { return x * 3 + k }), filter(fn(x: i64) -> bool { return x % 2 == 0 }), sum()) print(s)
// Any number type: here the stages end in `f64`. print(lists.fuse!(xs, filter(fn(x: i64) -> bool { return x < 10 }), map(fn(x: i64) -> f64 { return x as f64 / 4.0 })))
// Other ends: how many are left, or a list of them. print(lists.fuse!(xs, filter(fn(x: i64) -> bool { return x > 90 }), count())) let big = lists.fuse!(xs, filter(fn(x: i64) -> bool { return x > 97 }), map(fn(x: i64) -> str { return to_str(x) + "!" }), collect()) print(len(big)) print(big[0])}