Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
JSExperience 7masters - Recursion & Trampolines
Search
Ana Luiza Portello
July 05, 2018
Programming
1
380
JSExperience 7masters - Recursion & Trampolines
Ana Luiza Portello
July 05, 2018
Tweet
Share
More Decks by Ana Luiza Portello
See All by Ana Luiza Portello
FRONTIN | Elas Programam - Programação Funcional no Front-end
anabastos
0
110
Workshop JSFP - SEMCOMP 2021
anabastos
0
290
Clojure é um Java melhor que Java - Codecon 2021
anabastos
0
160
Clojure 101 - Criciuma Dev
anabastos
0
340
TDC POA - GraphQL
anabastos
1
280
TDC Porto Alegre 2019 - JS Funcional com Ramda
anabastos
0
260
BackEndSP - GraphQL
anabastos
0
250
Git & Github - RLadies
anabastos
1
250
Programaria Summit - Performance FrontEnd
anabastos
1
240
Other Decks in Programming
See All in Programming
マスタデータ問題、マイクロサービスでどう解くか
kts
0
140
リリース時」テストから「デイリー実行」へ!開発マネージャが取り組んだ、レガシー自動テストのモダン化戦略
goataka
0
150
組み合わせ爆発にのまれない - 責務分割 x テスト
halhorn
1
160
從冷知識到漏洞,你不懂的 Web,駭客懂 - Huli @ WebConf Taiwan 2025
aszx87410
2
3.1k
gunshi
kazupon
1
120
開発に寄りそう自動テストの実現
goyoki
2
1.5k
Tinkerbellから学ぶ、Podで DHCPをリッスンする手法
tomokon
0
150
AIエンジニアリングのご紹介 / Introduction to AI Engineering
rkaga
8
3.4k
ローカルLLMを⽤いてコード補完を⾏う VSCode拡張機能を作ってみた
nearme_tech
PRO
0
190
Cell-Based Architecture
larchanjo
0
150
AIコーディングエージェント(NotebookLM)
kondai24
0
240
Basic Architectures
denyspoltorak
0
130
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.7k
Color Theory Basics | Prateek | Gurzu
gurzu
0
150
The Invisible Side of Design
smashingmag
302
51k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
3.5k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
91
Building Applications with DynamoDB
mza
96
6.9k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
9
1k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
0
970
[RailsConf 2023] Rails as a piece of cake
palkan
58
6.2k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.6k
Paper Plane (Part 1)
katiecoart
PRO
0
2.2k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
21
Transcript
ANA LUIZA BASTOS github.com/anabastos @naluhh @anapbastos Fullstack Developer na Quanto
e cientista da computação na PUC-SP anabastos.me
JSLADIES fb.com/jsladiesbr twitter.com/jsladiessp meetup.com/JsLadies-BR/ LAMBDA.IO t.me/lambdastudygroup github.com/lambda-study-group/ meetup.com/Lambda-I-O-Sampa- Meetup/
VISÃO GERAL SOBRE RECURSÃO & TRAMPOLINES
VAMOS FALAR SOBRE RECURSÃO
Recursão é quando uma função chama a si mesma até
uma condição parar o loop.
λ Programação Funcional
Fatorial 1! = 1 3! = 1 * 2 *
3 = 6
const iterativeFactorial = (n) => { let i let contador
= 0 for (i = 1; i <= n; i++) { contador *= i } return contador }
1. Qual parte do código é recursiva 2. Condição de
saída
const fac = (n) => { if (n == 0)
{ return 1 } return n * fac(n - 1) }
• EXPRESSIVO • PURO / EVITANDO MUDANÇA DE ESTADO(CONTADOR) •
IMUTABILIDADE DE DADOS • DECLARATIVO • IDEMPOTENCIA
JS é single threaded e orientado a stack
None
GC fac(3) GC fac(2) fac(3) GC fac(1) fac(2) fac(3) GC
fac(0) fac(1) fac(2) fac(3) GC call call call call
GC fac(3) GC fac(2) fac(3) GC fac(1) fac(2) fac(3) GC
fac(0) fac(1) fac(2) fac(3) GC 1 1* 1 = 1 1 * 2 = 2 2 * 3 = 6
GC fac(9999) GC fac(9998) fac(9999) GC fac(9997) fac(9998) fac(9999) GC
oh no ... fac(9998) fac(9999) GC StackOverFlow :(
Cruza os dedos? Senta e chora?
TAIL CALL OPTIMIZATION (TCO)
Truque antigo
GC fac(3) GC fac(2) fac(3) GC fac(1) fac(2) fac(3) GC
fac(0) fac(1) fac(2) fac(3) GC call call call call
TCO faz com que a gente evite explodir o stack
quando fazemos chamadas recursivas
PROPER TAIL CALLS (PTC)
Possibilita que sua função recursiva seja otimizada pela engine.
RECURSÃO EM CAUDA (TAIL CALL)
//Não é tail call :( const fac = (n) =>
n == 0 ? 1 : n * fac(n - 1)
A última coisa a ser feita na função é o
retorno da própria função.
Acumulador
const tailRecursiveFac = (n, acc = 1) => { return
n == 0 ? acc : tailRecursiveFac(n - 1, acc * n) }
ES6 http://www.ecma-international.org/ecma-262/6.0/#sec-tail-position- calls
None
Além disso existem casos de algoritmos que precisam de mais
de duas chamadas recursivas(multiple recursion) e não tem como colocar tudo no final
COMO LIDAR COM ISSO?
CONTINUATION PASSING STYLE (CPS)
Um estilo de programação em que o controle é passado
explicitamente em forma de continuação
Continuação é uma parte de código que ainda vai ser
executada em algum ponto do programa Callbacks por exemplo são continuations
Continuação não chama a si mesma, ela só expressa um
fluxo de computação onde os resultados fluem em uma direção. Aplicar continuações não é chamar funções é passar o controle do resultado.
LAZY EVALUATION
CALL-BY-NEED
> (1 + 3) * 2 8 > const expression
= () => (1 + 3) * 2 > expression() 8
Ou seja, o programa espera receber os dados antes de
continuar.
E daí?
CPS elimina a necessidade de um call stack pois os
valores estarão dentro da continuation sendo executada .
Acumulador para uma continuação
IDENTITY FUNCTION
const id = x => x
• O último parâmetro da função é sempre a continuation.
• Todas as funções precisam acabar chamando sua continuação com o resultado da execução da função.
const cpsFac = (n, con) => { return n ==
0 ? con(1) : cpsFac(n - 1, y => con(n + y)) } cpsFac(3, id) //6
TRAMPOLINES
Técnica stack safe para fazer chamadas tail-recursive em linguagens orientadas
a stack
Um trampoline é um loop que iterativamente invoca funções que
retornam thunks (continuation-passing style)
THUNKS
Função que encapsula outra função com os parâmetros que para
quando a execução dessa função for necessária.
function thunk(fn, args) { return fn(...args) }
Ao invés de chamar a tail call diretamente, cada método
retorna a chamada para um thunk para o trampolim chamar.
const trampoline = (thunk) => { while(thunk instanceof Function){ thunk
= thunk() } return thunk }
• É um loop que chama funções repetidamente • Cada
função é chamada de thunk. • O trampolim nunca chama mais de um thunk • É como se quebrasse o programa em pequenos thunks que saltam pra fora do trampolim, assim o stack não cresce.
const trampolineFac = (n) { const fac = (n, ac
= 1) => { return n == 0 ? ac : thunk(fac, n - 1, ac * n) } return trampoline(thunk(fac, n, 1)) }
GC fac(3) GC call GC fac(2) GC GC bounce bounce
:(
Trade off por stack safety Trocamos o trabalho de criar
stack frames com o de criar binding de funções.
Em muitos casos o trade-off de overhead por expressividade vale
a pena
Trampolines são mais apropriadas para funções complexas em que não
existem soluções iterativas e não conflitam com outras técnicas de mediar controle de fluxo(Promises).
• Kyle Simpson. Functional Light Programming. Cap 8. - github.com/getify/Functional-Light-JS
• Functional Programming Jargon - github.com/hemanth/functional-programming-jarg on • Structure and Interpretation of Computer Programs - Javascript Adaptation
• Compatibilidade TCO - kangax.github.io/compat-table/es6/#test-proper_tail_c alls_ • Yoyojs - npmjs.com/package/yoyojs
• Ramda Memoisation - ramdajs.com/docs/#memoize
t.me/lambdastudygroup github.com/lambda-study-group
OBRIGADA :) https://speakerdeck.com/anabastos