title: Is the lack of tail call optimization an obstacle when using the Eventually workflow?
body: <p>I'm using a modified version of the Eventually workflow from the F# spec for my development on Xbox. The .net framework on the Xbox does not support tail calls, it seems. Because of this, I have to disable tail call optimization when compiling.</p>
  
  <p>Although it might seem at first that this restriction would prevent the use of any form of looping in computation expressions, I initially thought that "stepping" would avoid that problem: A recursive function f in the computation expression does not call itself directly, instead it returns an Eventually value containing a lambda which calls f.</p>
  
  <p>Experiments indicate that I was right about while loops (they don't cause stack overflows when used in computation expressions), but not about recursive functions.</p>
  
  <p>To clarify, this works:</p>
  
  <pre><code>// Wait until "start" or "A" is pressed on one of the gamepads.
  // Set "player" when that happens.
  let player : PlayerIndex option ref = ref None
  while (!player).IsNone do
      for p in all_players do
          let state = GamePad.GetState(p)
          if state.IsConnected
              &amp;&amp; (state.Buttons.Start = ButtonState.Pressed
                  || state.Buttons.A = ButtonState.Pressed) then
              player := Some p
      do! sys.WaitNextFrame()
  </code></pre>
  
  <p>This causes a stack overflow:</p>
  
  <pre><code>// Wait until "start" is pressed on the controlling gamepad.
  let rec wait() = task {
      input.Update()
      if not (input.IsStartPressed()) then
          do! sys.WaitNextFrame()
          do! wait()
  }
  </code></pre>
  
  <p>In the second case, the stack trace shows a long sequence of calls to "bind@17-1", whose code is shown below. The line number appearing in the stack trace is line 17.</p>
  
  <pre><code>let rec bind k e =
      match e with
      | Completed r -&gt;
          Running(fun () -&gt; k r)
      | Running f -&gt;
          Running(fun () -&gt; f() |&gt; bind k)  // line 17
      | Blocked(dt, f) -&gt;
          Blocked(dt, fun () -&gt; f() |&gt; bind k)
      | BlockedNextFrame f -&gt;
          BlockedNextFrame(fun () -&gt; f() |&gt; bind k)
      | Yield f -&gt;
          Yield(fun () -&gt; f() |&gt; bind k)
  </code></pre>
  
  <p>Where am I wrong? Is my reasoning about "steppable recursion" being harmless w.r.t. stack overflows incorrect? Is there something wrong with my implementation of bind?</p>
  
  <p>Oh my head! Continuation-passing with recursion gives me headaches...</p>
  
  <p>EDIT: "steppable recursion being harmless w.r.t. stack overflows" has got a name, I have just learned. It's called a trampoline.</p>