I'm currently trying to learn f# using the book Real-World Functional Programming by Petricek and Skeet (2010) but have been encountering problems when using continuations to avoid stack overflow.
The problem that I have been encountering is that my code using continuations works perfectly when launched in the f# interactive, but still causes stack overflow when placing the code in the program.fs file and then launching it through the debugger in Visual Studio.
It is unclear to me why this happens, and would very much appreciate if anyone could give me an explanation to why this happens.
In case the version of Visual Studio is relevant, I am using: Visual Studio Ultimate 2012 Version 11.0.61030.00 Update 4
The .Net framework used is: Version. 4.5.51641
The code presented in the book that is causing this problem is presented below:
open System
let rand = new Random()
//A tree is either a leaf with a value or a node that contains two children
type IntTree =
| Leaf of int
| Node of IntTree * IntTree
//A list of that will decide all leaf values
let numbers2 = List.init 1000000 (fun _ -> rand.Next(-50,51))
///Creates an imbalanced tree with 1000001 leafs.
let imbalancedTree2 =
numbers2 |> List.fold (fun currentTree num ->
Node(Leaf(num), currentTree)) (Leaf(0))
//Sums all leafs in a tree by continuation and will execute the inserted function with the total
//sum as argument once all values have been summed.
let rec sumTreeCont tree cont =
match tree with
| Leaf(num) -> cont(num)
| Node(left, right) ->
sumTreeCont left (fun leftSum ->
sumTreeCont right (fun rightSum ->
cont(leftSum + rightSum)))
//Sums the imbalanced tree using the sumTreeCont function
let sumOfTree = sumTreeCont imbalancedTree2 (fun x -> x)
Thanks in advance! //Tigerstrom
If you are running the program in Debug mode, then the default Visual Studio project setting disables tail calls. The main reason is that, with tail calls enabled, you do not get very useful information in the call stack (which makes debugging harder).
To fix this, you can go to your project options and check "Generate tail calls" on the "Build" page. In release mode, this is enabled by default.