Recursion: Proper Tail Calls & Tail Call Optimization (ES6)

Поделиться
HTML-код
  • Опубликовано: 28 янв 2025

Комментарии • 27

  • @secretagentx-9908
    @secretagentx-9908 5 лет назад +3

    I believe tail call optimization was removed from Node.js after v7 due to issues with debugging but please please please someone tell me I am wrong. Tell me TCO is still available in node...

    • @NWCalvank
      @NWCalvank  5 лет назад

      It looks like you're right! We lost one of my favourite features

    • @secretagentx-9908
      @secretagentx-9908 5 лет назад

      @@NWCalvank Say it aint so! Looks like its trampolines from now on then.

  • @LS-cb7lg
    @LS-cb7lg 4 года назад

    i swear this is the best video to this that i could find, every other channel tries to explain this using fibonacci or something that is too complicated for my small brain to understand at 1 am.

  • @TTYounga
    @TTYounga 4 года назад

    Thank you this was great! It was concise and straightforward to understand.

  • @TheRaiderNation
    @TheRaiderNation 5 лет назад

    Thanks for this video! Fantastic explanation.

  • @mjjuneja
    @mjjuneja 4 года назад

    @NWCalvank I tried your example on chrome's console. But the stack seems to be getting collected throughout unless poping begins. So how exactly is it benifitial?

  • @tomdane5007
    @tomdane5007 6 лет назад

    I didn't know JS had destructuring! That is awesome. JS feels more and more like haskell!

    • @NWCalvank
      @NWCalvank  6 лет назад +1

      Destructuring is my one true love

  • @mykhailoklym4417
    @mykhailoklym4417 5 лет назад

    Great video dud!

  • @producdevity
    @producdevity 7 лет назад +1

    Great explanation!
    The only thing that's kinda annoying is that the keyboard is very load when listening with headphone.. maybe place it more far away from the keyboard?

    • @NWCalvank
      @NWCalvank  7 лет назад +1

      Thanks for the feedback. I'll try to get a proper microphone/setup in the next couple weeks

  • @ahmedshahd1735
    @ahmedshahd1735 3 года назад

    thanks bro

  • @MrGoodKill_FR
    @MrGoodKill_FR 6 лет назад

    So, this is not yet supported?
    kangax.github.io/compat-table/es6/#test-proper_tail_calls_(tail_call_optimisation)

  • @josephastrahan6403
    @josephastrahan6403 6 лет назад

    How does the compiler engine know that it doesn't need the result from before (in your tail call example)? It's still calling the same function name, so wouldn't this still affect the stack? Is the compiler smart enough to know that 'count' was all you really cared about? (and if that is the case, is that because 'count' was being returned instead of the result of the 'function' size being returned?

    • @NWCalvank
      @NWCalvank  5 лет назад +3

      I'll attempt to explain in a way that I think answers the question. Let me know if it's not quite what you were asking...
      So, there are two things going on: Proper Tail Calls (PTC) and Tail Call Optimization (TCO).
      PTC is done by the developer. He/she implements PTC by placing the recursive call in the tail call position. When implemented properly, there is a new instance of the function that has all of the arguments that it needs in order to do its job.
      TCO is done by the JS engine. I can't speak to how this is implemented because it's not my area of expertise. But the idea is that the engine can recognize a PTC, initialize the function with its arguments, and then remove the previous instance of that function (because it is no longer needed).
      So, yes, the JS engine is 'smart enough' to recognize that the previous instance of the function is no longer needed. This is because there is no longer a reference to it.
      If we had something like:
      const sum = ([x, y, ...ys]) => ys.length === 0 ? x + y : sum([ x + y, ...ys ])
      We know that:
      sum([45, 10]) // returns 55
      It doesn't matter how we got to that final function call. The rest of the 'stack' is irrelevant.
      So, even if we went:
      sum([1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ])
      to
      sum([3, 3, 4, 5, 6, 7, 8, 9, 10 ])
      to
      sum([6, 4, 5, 6, 7, 8, 9, 10 ])
      ...
      to
      sum([45, 10 ])
      Each of those calls is independent. So, the engine can remove those old instances. Does that make sense?

  • @Danielo515
    @Danielo515 6 лет назад

    Do you know if this is implemented on node? I guess no, since node relies on V8

    • @NWCalvank
      @NWCalvank  6 лет назад +1

      I'm not aware of the support for TCO in Node, no. I typically only end up using recursion in very specific situations in JS, anyway. And, fortunately, I've known the data size or have been implementing something that doesn't have memory concerns anytime I have chosen recursion :)

  • @lutaseb
    @lutaseb 7 лет назад +1

    as usual, awesome. I assume setting an implicit count variable is kind f useless since you won't do anything with it. It becomes usefull when passing explicitly a variable at function call

    • @NWCalvank
      @NWCalvank  7 лет назад +1

      Implementing this with a count variable would mean initializing it at zero and then mutating it, which we want to avoid in functional programming.
      Does that make sense?

  • @kyoungd
    @kyoungd 6 лет назад

    Good one.