Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.

Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.

In most of the pure functional programming languages (Haskell, Clean, Erlang) there are no for or while loops, so iterating over lists needs to be done using recursive functions. Pure functional programming languages have language support and are optimized for list comprehension and list concatenation.Muitas linguagens de programação são em torno de recursão e apesar do JS ter muitos elementos funcionais não foi feita pra isso

In most of the pure functional programming languages (Haskell, Clean, Erlang) there are no for or while loops, so iterating over lists needs to be done using recursive functions. Pure functional programming languages have language support and are optimized for list comprehension and list concatenation.

Precisamos definir: Defining an exit condition, an atomic definition that exists by itself (also called a “base case”). Defining which part of the algorithm is recursive.(ou seja, quando a função deve chamar a si mesma)

A curried function takes one argument at a time and returns a function that takes the next argument. In Reason, functions can automatically be partially called:

Avoiding State Change (and mutable data) - one of the characteristics of functional programming is that functions do not change the state of the application, they rather create a new state from the old one.Declarations vs statements - in functional programming as in Mathematics a declarative approach is used for defining/describing functions.Idempotence - it means when invoking a function (any number of times) using the same arguments will always have the same result, this also goes hand in hand with avoiding state changeRecursion, however, is a natural match with pure functional programming - no state is needed to recurse, except for the (read-only) function arguments and a (write-only) return value. if re-written using iterative loops would be much more complex, unweildy or harder to read/maintain. Think about binary searching algorithms like tree-traversal.

However, not having side effects also means that recursion can be implemented more efficiently, and the compiler can optimize it more aggressively. I haven't studied any such compiler in depth myself, but as far as I can tell, most functional programming languages' compilers perform tail call optimization, and some may even compile certain kinds of recursive constructs into loops behind the scenes. GCC does a much better job of TCO than GHC, because you can't do TCO across the creation of a thunk.

Javascript is single threaded, which means that only one task can be run at any given time. When the Javascript interpreter on the page starts executing code it is running in an environment that is referred to as the Global Execution Context.

factorial(0) // The factorial of 0 is 1 by definition (base case)factorial(1) // This call depends on factorial(0)factorial(2) // This call depends on factorial(1)factorial(3) // This first call depends on factorial(2)

factorial(0) // The factorial of 0 is 1 by definition (base case)factorial(1) // This call depends on factorial(0)factorial(2) // This call depends on factorial(1)factorial(3) // This first call depends on factorial(2)

So the way computers generally implement this idea of a function that could call another function that could call another. In memory they reserve an area of memory that's given the name a stack frame, generally. It's a small area of memory that keeps track of all the variables, sometimes referred to as the variables that are on the stack. At some point, there's a physical limit to the system. At some point we've run out. Now when you weren't doing recursion. I

Various language features will trigger the creation of a new execution context (functions, eval, let blocks, closures, etc.). https://www.datchley.name/content/images/2015/11/Execution-Stack---JS.png Keep in mind that because of the scope chain, execution contexts will be able to access variables and functions delared in any parent (previous) scope. function calls add to the stack. . When the code in a given context is finished executing, that stack entry is destroyed and control is returned to the executable code from the previous stack execution context. https://www.datchley.name/content/images/2015/11/Single-Function--Iterative-Stack---JS.png

In functional languages (like Elm, Elixir, Haskell, etc), it is impossible to do imperative loops, so the only option is recursion. não porque elas querem mas porque elas precisam

Programacao funcional é legal mas js não foi feito pra ser uma lang funcional o suporte js é poop Since recursion is built into the language, the compiler will often make optimizations to guarantee that the call stack isn’t exceeded when processing large datasets Clojure: Nao suporta TCO pois JVM loop...recur: Note the similarity between this code and the Python fib_tail shown earlier. This is not a coincidence! Once the algorithm is expressed in tail form, it's pretty easy to convert it to an iteration pattern manually; if it wasn't easy, compilers wouldn't be able to do it automatically for the past 40 years! . Since the tail call carries the whole state around in arguments, we just imitate this using an explicit loop and state variables.

Here, Javascript recognizes the tail-call and can then reuse the existing stack frame to make the recursive call, removing any previously local variables and state from the old call. As it turns out in the general sense, creating a new stack frame and throwing an old stack frame array. , we could just reuse the same stack frame, we could just override it with. The memory, we could reuse that memory for the next stack frameDifferently to what happens with proper tail calls, tail call optimization actually improves the performance of tail recursive functions and makes running them faster. Tail call optimization is a technique used by the compiler to transform your recursive calls into a loop using jumps.

Como fazer o tco funfar?

So it's kind of like PTC is the umbrella and TCO is the way that an engine might choose to do different sorts of optimizations, make things not slow.

At the time of writing, Safari is the only browser to have shipped PTC. Node implemented tail calls in version 6.5, but it was hidden behind a flag (later they removed support for PTC altogether in Node 8). The folks at Apple that drive Safari, they don't put features into their browser unless there is a really good reason why they want to. So my suspicion is that either something that's already shipped or something that's shipping soon on their road map, distinctly and directly requires them to have PTC support.he reason it's not in the other engines is not because it's too hard for them. They don't want to implement it. They've decided that implementing this feature, even though they voted to put it in the spec, they've decided that implementing this feature is gonna unnecessarily hamper other performance things that they wanna do.And so, they're pushing back on the TC39 committee saying, we wanna take that out of this spec. And the WebKit folks are like, well, we already shipped it like six months ago. So, we don't wanna take it out of the spec, we like it, we think it's good.

If the engine just started doing that, that would actually make every function in your program, every single time recursive or not slower. So just implementing that feature that they could run in the recursive case in fixed memory would make all functions, even non-recursive ones, run slower.

A continuation is an object that captures the current state of a program Easier: it is the work that remains to be done A common representation is a function I takes only one parameter with the result of previous computations

FORMA DE SIMULARAVALIACAO DEVAGAR AVALIACAO PREGUICOSA

Call-by-ned: evaluation mechanism that delays the evaluation of an expression until its value is needed.

Continuations are often seen in asynchronous programming when the program needs to wait to receive data before it can continue. The response is often passed off to the rest of the program, which is the continuation, once it's been received.unbounded continuations can be treated as first-class values in a language, they become so powerful that they can be used to implement pretty much any control-flow feature you can imagine - exceptions, threads, coroutines and so on. This is precisely what continuations are sometimes used for in the implementation of functional languages, where CPS-transform is one of the compilation stages. (lida com cps call/cc)

Even though most programming languages don't support real, unbounded continuations, bounded continuations is another deal. A bounded continuation is just a function that returns to its caller Applying unbounded continuations is not just calling a function - it's passing control without hope of return. Just like coroutines, or longjmp in C. Unbounded continuations do not return to their caller. They express a flow of computation where results flow in one direction, without ever returning

So, if I was in the very first call, that is I passed in only one number, then that would be calling the identity function with whatever I passed in, and just passing back the value directly. But if I was deeper into my stack of recursion, then I would just be passing sum into some function that had been passed to me, that had been passed to me, that had been passed. [00:02:57] So, what does that non-base case look like? You notice again, instead of calling sum plus recur, I call recur with my list of nums, that's my running array list if you will, but my last position there is a function. It's another continuation, a continuation that takes a v and calls whatever the current continuation is with that plus the sum. And since it does not rely on stack value, any values will be captured inside of the continuation. We can make even more than one continuation to execute on a different execution path or even on the different CPU with no problem with mutable state.

dessa forma usamos esse thunk pra emular uma avaliação lazy, que linguagens como js nao suportam por padrão. So the sole purpose of the trampoline function is to control the execution in an iterative way, and that ensures the stack to have only a single stack frame on the stack at any given time.

A curried function takes one argument at a time and returns a function that takes the next argument. In Reason, functions can automatically be partially called:

A curried function takes one argument at a time and returns a function that takes the next argument. In Reason, functions can automatically be partially called:

A curried function takes one argument at a time and returns a function that takes the next argument. In Reason, functions can automatically be partially called:

Here, Javascript recognizes the tail-call and can then reuse the existing stack frame to make the recursive call, removing any previously local variables and state from the old call. As it turns out in the general sense, creating a new stack frame and throwing an old stack frame array. , we could just reuse the same stack frame, we could just override it with. The memory, we could reuse that memory for the next stack frameDifferently to what happens with proper tail calls, tail call optimization actually improves the performance of tail recursive functions and makes running them faster. Tail call optimization is a technique used by the compiler to transform your recursive calls into a loop using jumps.

In my own performance profiling I found that the overhead from using the trampoline wasn’t nearly as large as I thought it would be. There’s no question about it — the trampoline is slower than an iterative loop. However, in many cases where a recursive solution can be cleaner and less error-prone, the performance overhead may be worth the readability benefits.