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 Slide

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

    View Slide

  3. Recursion is
    cool

    View Slide

  4. Recursive data structures

    View Slide

  5. Recursive functions

    View Slide

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

    View Slide

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

    View Slide

  8. Stack Overflow

    View Slide

  9. Recursive functions
    ● Tend to cause StackOverflowException

    View Slide

  10. Tail recursion
    ● Make functions tailrec to avoid StackOverflow

    View Slide

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

    View Slide

  12. Tail recursion
    ● Make functions tailrec to avoid StackOverflow

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  20. Give up

    View Slide

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

    View Slide

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

    View Slide

  23. 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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

  27. Trampoline

    View Slide

  28. 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 Slide

  29. 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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

  33. Eval: trampoline

    View Slide

  34. Eval: trampoline

    View Slide

  35. [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 Slide

  36. View Slide

  37. View Slide

  38. Beautiful
    FP Programmers

    View Slide

  39. Run with Id

    View Slide

  40. Run with Eval

    View Slide

  41. Run with Eval
    Cool!
    FP Programmers

    View Slide

  42. Let’s implement stack safe foldRight with Eval

    View Slide

  43. Let’s implement stack safe foldRight with Eval

    View Slide

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

    View Slide

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

    View Slide

  46. Use Defer to defer Eval instance construction

    View Slide

  47. Use Defer to defer building Eval instance

    View Slide

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

    View Slide

  49. 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 Slide

  50. Thank you!

    View Slide