Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Write stack safe non-tailrec recursive functions

Write stack safe non-tailrec recursive functions

Recrusive function is cool, but it sometimes cause stack overflow in naive implementation. I'll explain how to write any recursive functions in stack safe way.

Jun Tomioka

June 29, 2019
Tweet

More Decks by Jun Tomioka

Other Decks in Technology

Transcript

  1. Write stack safe non-tailrec
    recursive functions
    @jooohn1234

    View full-size slide

  2. Jun Tomioka
    @jooohn1234
    Software Engineer at M3, Inc.

    View full-size slide

  3. Recursion is
    cool

    View full-size slide

  4. Recursive data structures

    View full-size slide

  5. Recursive functions

    View full-size slide

  6. Recursive functions
    ● Describe WHAT it is rather than HOW it’d be
    done

    View full-size slide

  7. Recursive functions
    ● Describe WHAT it is rather than HOW it’d be
    done
    Cool!
    FP Programmers

    View full-size slide

  8. Stack Overflow

    View full-size slide

  9. Recursive functions
    ● Tend to cause StackOverflowException

    View full-size slide

  10. Tail recursion
    ● Make functions tailrec to avoid StackOverflow

    View full-size slide

  11. Tail recursion
    ● Make functions tailrec to avoid StackOverflow
    Cool!
    FP Programmers

    View full-size slide

  12. Tail recursion
    ● Make functions tailrec to avoid StackOverflow

    View full-size slide

  13. Tail recursion
    ● Make functions tailrec to avoid StackOverflow
    It’s… cool!
    FP Programmers

    View full-size slide

  14. Tail recursion?
    ● Make functions tailrec to avoid StackOverflow
    … but can we?

    View full-size slide

  15. Tail recursion?
    ● Make functions tailrec to avoid StackOverflow
    … but can we?

    View full-size slide

  16. Tail recursion?
    ● Make functions tailrec to avoid StackOverflow
    … but can we?
    It’s…
    still cool I believe!
    FP Programmers

    View full-size slide

  17. Tail recursion?
    ● How many unique paths from S to G are there?
    S
    G

    View full-size slide

  18. Tail recursion?
    ● Can you make this recursive function tailrec?

    View full-size slide

  19. Tail recursion?
    ● Can you make this recursive function tailrec?
    ・・・
    FP Programmers

    View full-size slide

  20. Tail-recursion’s limitation
    ● It tends to be difficult to convert recursive
    functions that depend on results of multiple
    recursive calls.

    View full-size slide

  21. Tail-recursion’s limitation
    ● It tends to be difficult to convert recursive
    functions that depend on results of multiple
    recursive calls.

    View full-size slide

  22. Tail-recursion’s limitation
    ● It tends to be difficult to convert recursive
    functions that depend on results of multiple
    recursive calls.
    Monad!
    FP Programmers

    View full-size slide

  23. The Monad version of recursion
    ● This function still describes the problem’s
    structure intuitively, doesn’t it?

    View full-size slide

  24. The Monad version of recursion
    ● This function still describes the problem’s
    structure intuitively, doesn’t it?
    Cool!
    FP Programmers

    View full-size slide

  25. The Monad version of recursion
    ● Of course just rewriting the recursive function
    with Monad doesn’t mean it is stack safe.

    View full-size slide

  26. Trampoline
    ● > a trampoline is a loop that iteratively invokes
    thunk-returning functions
    ○ https://en.wikipedia.org/wiki/Trampoline_(computing)
    #High-level_programming
    ○ “Trampoline” in computer science has a lot of
    meanings. This is just one of them.

    View full-size slide

  27. Trampoline
    ● A trampoline loop evaluates values one by one
    until it returns final result.
    ● We can write this evaluation loop as tailrec!
    Eval evaluate
    Eval
    Result
    OR
    loop

    View full-size slide

  28. Eval
    * We typically implement “Defer”, “Suspend” or something like that to avoid stack
    overflow when building the Eval.

    View full-size slide

  29. Eval
    * We typically implement “Defer”, “Suspend” or something like that to avoid stack
    overflow when building the Eval.
    Represents single value

    View full-size slide

  30. Eval
    * We typically implement “Defer”, “Suspend” or something like that to avoid stack
    overflow when building the Eval.
    Has following evaluation

    View full-size slide

  31. Eval: trampoline

    View full-size slide

  32. Eval: trampoline

    View full-size slide

  33. [Optional] Memoization
    ● This is not the essence, but memoization to
    reduce running time
    ● In many cases, we can make such “What it is”
    style of recursive functions faster by using
    memoization

    View full-size slide

  34. Beautiful
    FP Programmers

    View full-size slide

  35. Run with Eval

    View full-size slide

  36. Run with Eval
    Cool!
    FP Programmers

    View full-size slide

  37. Let’s implement stack safe foldRight with Eval

    View full-size slide

  38. Let’s implement stack safe foldRight with Eval

    View full-size slide

  39. Let’s implement stack safe foldRight with Eval
    !!!
    FP Programmers

    View full-size slide

  40. Let’s implement stack safe foldRight with Eval
    This recursive call of loop
    causes stack overflow before
    stack safe trampoline
    evaluation

    View full-size slide

  41. Use Defer to defer Eval instance construction

    View full-size slide

  42. Use Defer to defer building Eval instance

    View full-size slide

  43. Use Defer to defer building Eval instance
    Stack safe!
    FP Programmers

    View full-size slide

  44. Recap
    ● Recursive functions is cool especially when it
    describes ”what” rather than ”how”
    ● We can apply the trampoline technique to
    avoid stack overflow when tail-recursion is not
    effective

    View full-size slide