$30 off During Our Annual Pro Sale. View Details »
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
330
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
Microservices rules: What good looks like
cer
PRO
0
870
宅宅自以為的浪漫:跟 AI 一起為自己辦的研討會寫一個售票系統
eddie
0
480
CloudNative Days Winter 2025: 一週間で作る低レイヤコンテナランタイム
ternbusty
7
2k
[SF Ruby Conf 2025] Rails X
palkan
0
470
LLM Çağında Backend Olmak: 10 Milyon Prompt'u Milisaniyede Sorgulamak
selcukusta
0
100
認証・認可の基本を学ぼう前編
kouyuume
0
180
dnx で実行できるコマンド、作ってみました
tomohisa
0
140
AIエンジニアリングのご紹介 / Introduction to AI Engineering
rkaga
4
1.4k
251126 TestState APIってなんだっけ?Step Functionsテストどう変わる?
east_takumi
0
300
20 years of Symfony, what's next?
fabpot
2
330
Reactive Thinking with Signals and the new Resource API
manfredsteyer
PRO
0
170
Navigation 3: 적응형 UI를 위한 앱 탐색
fornewid
1
190
Featured
See All Featured
Code Review Best Practice
trishagee
73
19k
GraphQLとの向き合い方2022年版
quramy
50
14k
Learning to Love Humans: Emotional Interface Design
aarron
274
41k
GitHub's CSS Performance
jonrohan
1032
470k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
Code Reviewing Like a Champion
maltzj
527
40k
Making the Leap to Tech Lead
cromwellryan
135
9.7k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
380
Stop Working from a Prison Cell
hatefulcrawdad
273
21k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.2k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.3k
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