Is it possible to use continuations to make foldRight tail recursive?

前端 未结 4 393
臣服心动
臣服心动 2021-01-02 07:34

The following blog article shows how in F# foldBack can be made tail recursive using continuation passing style.

In Scala this would mean that:

4条回答
  •  忘掉有多难
    2021-01-02 07:43

    Why is this not a problem with F#?

    F# has all tail calls optimized.

    And is there any way to work around this with Scala?

    You can do TCO using other techniques like trampolines but you lose interop because it changes the calling convention and it is ~10× slower. This is one of the three reasons I don't use Scala.

    EDIT

    Your benchmark results indicate that Scala's trampolines are a lot faster than they were the last time I tested them. Also, it is interesting to add equivalent benchmarks using F# and for larger lists (because there's no point in doing CPS on small lists!).

    For 1,000x on a 1,000-element list on my netbook with a 1.67GHz N570 Intel Atom, I get:

    List.fold     0.022s
    List.rev+fold 0.116s
    List.foldBack 0.047s
    foldContTC    0.334s
    

    For 1x 1,000,000-element list, I get:

    List.fold     0.024s
    List.rev+fold 0.188s
    List.foldBack 0.054s
    foldContTC    0.570s
    

    You may also be interested in the old discussions about this on the caml-list in the context of replacing OCaml's non-tail-recursive list functions with optimized tail recursive ones.

提交回复
热议问题