-- Tests -- ----- -- A collection of tests for compiler bugs, benchmarking, etc. -- Benchmarks -- ---------- -- A collection of simple benchmarks. You can view the results -- by opening your browser's terminal. module "Benchmarks for the prelude" open prelude open prelude.speedtest open prelude.list open prelude.string title x = do log "\r " log x return true -- Here we have 5 implementations of -- (Project Euler problem #1)[http://projecteuler.net/problem=1]. -- The first is simply a native JS implementation. euler_1 x = `var sum = 0; for (var i = 1; i < x; i++) { if (i % 3 == 0 || i % 5 == 0) sum += i; }; return sum;` -- The second is a tail recursive. The forml compiler will -- optimize simple functions which are tail recursive into -- javascript `for` loops automatically, making them -- much faster. euler_2 x y when x < 3 = y | x y when x % 3 == 0 || x % 5 == 0 = euler_2 (x - 1) (y + 1) | x y = euler_2 (x - 1) y euler_3 x when x < 3 = 0 euler_3 x = if x % 3 == 0 || x % 5 == 0 then 1 + euler_3 (x - 1) else euler_3 (x - 1) euler_4 z = yield 1 .. z |> filter (λx = x % 3 == 0 || x % 5 == 0) |> sum euler_5 x y when x < 3 = y | x y when do! `x % 3 == 0 || x % 5 == 0` = euler_5 (x - 1) (y + 1) | x y = euler_5 (x - 1) y do! title "Relative Speeds (10k)" w <- time (euler_1 10000) x <- time yield euler_2 10000 0 y <- time yield euler_3 10000 z <- time (euler_4 10000) q <- time yield euler_5 10000 0 log " Native JS: `w / 1000`s" log " Forml TCO Unboxed: `q / 1000`s" log " Forml TCO: `x / 1000`s" log " Forml Recursive: `y / 1000`s" log " Forml list: `z / 1000`s" return <| (x <= y && y < z) string? (err yield euler_3(250000)).message do! title "Relative Speeds (2.5M)" w <- time (euler_1 2500000) x <- time yield euler_2 2500000 0 y <- time yield euler_5 2500000 0 log " Native JS: `w / 1000`s" log " Forml TCO Unboxed: `y / 1000`s" log " Forml TCO: `x / 1000`s" log " Forml Recursive: `err yield euler_3(250000)`" log " Forml list: `err (euler_4 250000)`" log "" return <| (w < x) module "Tests for partial records" open prelude var f {a: x, b: y, _ } = x + y f { a: 5, b: 5, c: 5 } == f { a: 5, b: 5, d: 5 } var f {a: 1, b: 1, _ } = 2 f {b: 2, c: 2, _ } = 2 f {a:1,b:1,c:3,d:5} + f {a:1,b:2,c:2,e:5} == 4 var f { a = 1, b = 2, _ } = 1 g { b = 2, c = 3, _ } = 2 x = { a = 1, b = 2, c = 3, d = 4 } f x + 1 == g x module "Tests for TCO bugs" open prelude open prelude.list rev_1 y = var r rest [:] = rest | rest { head: x, tail: xs } = r (x :: rest) xs r {nil} y rev_2 = var rrr rest [:] = rest rrr rest { head: x, tail: xs } = rrr (x :: rest) xs rrr {nil} rev_2 [: 1, 2, 3, 4 ] == [: 4, 3, 2, 1 ] test_x = [: 1, 2, 3, 4, 5, 6, 7 ] rev_2 test_x == rev_1 test_x rev_1 test_x == reverse test_x length (rev_2 test_x) == length (rev_1 test_x) length (rev_2 test_x) == length test_x length (rev_1 test_x) == length (reverse test_x) module "Tests for typing bugs" open prelude ff x = gg x + 1 gg x = ff x - 1 module "Tests for parser bugs" open prelude open prelude.string open prelude.html var x = do! `[ {x: 1}, {x: 2}, {x: 3} ]` stringify (x !! 0).x == "1" module "Test that definition names dont collide with namespaces" open prelude module nametest x = 1 nametest = {} module "Seperator" open nametest x == 1