I’ve been comparing for fun different languages for speed in execution of the following program:
for i from 1 to 1000000 sum the product i*(sqrt i)
One of my implementations (not the only one) is constructing a list [1..1000000] and then folding with a specific function.
The program works fine and fast in Haskell (even when using foldl and not foldl’) but stack overflows in OCaml and F#.
Here is the Haskell code:
test = foldl (\ a b -> a + b * (sqrt b)) 0
create 0 = []
create n = n:(create (n-1))
main = print (test (create 1000000))
And here is the OCaml one:
let test = List.fold_left (fun a b -> a +. (float_of_int b) *. (sqrt (float_of_int b))) 0. ;;
let rec create = function
| 0 -> []
| n -> n::(create (n-1)) ;;
print_float (test (create 1000000));;
Why does the OCaml/F# implementation stack overflows?
The Haskell code for
createevaluates the list lazily, i.e. as elements are needed byfoldl. The entire list is not needed all at once.By contrast, F# and OCaml evaluate the
createlist strictly, i.e. the code tries to generate the entire list in one go before passing it tofold_left.One possibility in F# is to use a
seqexpression in thecreatefunction: this generates the list lazily in the same way as Haskell. (I’m not sure if OCaml has an equivalent feature.)