SlideShare uma empresa Scribd logo
1 de 66
ANA LUIZA BASTOS
github.com/anabastos
@naluhh
@anapbastos
Software Developer na Quanto e
cientista da computação da
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
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
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
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 que muitas
linguagens funcionais fazem
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
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
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 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.
Continuação é uma parte de
código que ainda vai ser executada
em algum ponto do programa
Callbacks por exemplo são continuations
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 pra fazer
chamadas tail-recursive em
linguagens orientadas a stack
Um único trampoline consegue expressar
todas as transferência de controle do
programa.
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 sum = (ac, n) => {
return n == 0
? ac
: thunk(sum, ac * n, n -
1)
}
return trampoline(thunk(sum, n, 0))
}
GC
sum(3)
GC GC
sum(2)
GC GC
:(
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-
jargon
● Structure and Interpretation of Computer
Programs - Javascript Adaptation
● Compatibilidade TCO -
kangax.github.io/compat-table/es6/#test-
proper_tail_calls_
● Yoyojs - npmjs.com/package/yoyojs
● Ramda Memoisation -
ramdajs.com/docs/#memoize
t.me/lambdastudygroup
github.com/lambda-study-group
OBRIGADA :)
https://speakerdeck.com/anabastos

Mais conteúdo relacionado

Mais procurados

2 controle fluxo
2 controle fluxo2 controle fluxo
2 controle fluxoprofwtelles
 
Usando POP com Programação Funcional
Usando POP com Programação FuncionalUsando POP com Programação Funcional
Usando POP com Programação FuncionalTales Andrade
 
Programação reativa com RxJS e Angular
Programação reativa com RxJS e AngularProgramação reativa com RxJS e Angular
Programação reativa com RxJS e AngularWendel Nascimento
 
Debugging tips and tricks
Debugging tips and tricksDebugging tips and tricks
Debugging tips and tricksTales Andrade
 
Lotus - TCG : Uma ferramenta para geração e seleção de casos de teste funcion...
Lotus - TCG : Uma ferramenta para geração e seleção de casos de teste funcion...Lotus - TCG : Uma ferramenta para geração e seleção de casos de teste funcion...
Lotus - TCG : Uma ferramenta para geração e seleção de casos de teste funcion...Laryssa Muniz
 
Resumo das Instruções de Desvio Incondicionais MIPS 32 bits
Resumo das Instruções de Desvio Incondicionais MIPS 32 bitsResumo das Instruções de Desvio Incondicionais MIPS 32 bits
Resumo das Instruções de Desvio Incondicionais MIPS 32 bitsElaine Cecília Gatto
 
Linguagem C - Funções e ponteiros
Linguagem C - Funções e ponteiros Linguagem C - Funções e ponteiros
Linguagem C - Funções e ponteiros Karoline Tavares
 
Algoritmos C/C++ - Aula 02
Algoritmos C/C++ - Aula 02Algoritmos C/C++ - Aula 02
Algoritmos C/C++ - Aula 02Leandro Rezende
 
Resumo linguagem c para microcontroladores PIC usando MikroC
Resumo linguagem c para microcontroladores PIC usando MikroCResumo linguagem c para microcontroladores PIC usando MikroC
Resumo linguagem c para microcontroladores PIC usando MikroCFabio Souza
 
Conjunto de instruções mips - instruções de desvio
Conjunto de instruções mips - instruções de desvioConjunto de instruções mips - instruções de desvio
Conjunto de instruções mips - instruções de desvioElaine Cecília Gatto
 
Estruturas de dados com C++ e STL
Estruturas de dados com C++ e STLEstruturas de dados com C++ e STL
Estruturas de dados com C++ e STLMarcos Castro
 
Maratona de Programação com STL
Maratona de Programação com STLMaratona de Programação com STL
Maratona de Programação com STLMarcos Castro
 

Mais procurados (20)

2 controle fluxo
2 controle fluxo2 controle fluxo
2 controle fluxo
 
C pic
C picC pic
C pic
 
Usando POP com Programação Funcional
Usando POP com Programação FuncionalUsando POP com Programação Funcional
Usando POP com Programação Funcional
 
Programação reativa com RxJS e Angular
Programação reativa com RxJS e AngularProgramação reativa com RxJS e Angular
Programação reativa com RxJS e Angular
 
Debugging tips and tricks
Debugging tips and tricksDebugging tips and tricks
Debugging tips and tricks
 
Lotus - TCG : Uma ferramenta para geração e seleção de casos de teste funcion...
Lotus - TCG : Uma ferramenta para geração e seleção de casos de teste funcion...Lotus - TCG : Uma ferramenta para geração e seleção de casos de teste funcion...
Lotus - TCG : Uma ferramenta para geração e seleção de casos de teste funcion...
 
Resumo das Instruções de Desvio Incondicionais MIPS 32 bits
Resumo das Instruções de Desvio Incondicionais MIPS 32 bitsResumo das Instruções de Desvio Incondicionais MIPS 32 bits
Resumo das Instruções de Desvio Incondicionais MIPS 32 bits
 
Linguagem C - Funções e ponteiros
Linguagem C - Funções e ponteiros Linguagem C - Funções e ponteiros
Linguagem C - Funções e ponteiros
 
Instruçao repeat
Instruçao repeatInstruçao repeat
Instruçao repeat
 
Modularização
ModularizaçãoModularização
Modularização
 
Algoritmos C/C++ - Aula 02
Algoritmos C/C++ - Aula 02Algoritmos C/C++ - Aula 02
Algoritmos C/C++ - Aula 02
 
First rela micro pro
First rela micro proFirst rela micro pro
First rela micro pro
 
Resumo linguagem c para microcontroladores PIC usando MikroC
Resumo linguagem c para microcontroladores PIC usando MikroCResumo linguagem c para microcontroladores PIC usando MikroC
Resumo linguagem c para microcontroladores PIC usando MikroC
 
Apostila turbo pascal
Apostila turbo pascalApostila turbo pascal
Apostila turbo pascal
 
Conjunto de instruções mips - instruções de desvio
Conjunto de instruções mips - instruções de desvioConjunto de instruções mips - instruções de desvio
Conjunto de instruções mips - instruções de desvio
 
Estruturas de dados com C++ e STL
Estruturas de dados com C++ e STLEstruturas de dados com C++ e STL
Estruturas de dados com C++ e STL
 
Recursividade
RecursividadeRecursividade
Recursividade
 
Switchcase
SwitchcaseSwitchcase
Switchcase
 
Maratona de Programação com STL
Maratona de Programação com STLMaratona de Programação com STL
Maratona de Programação com STL
 
Cap07 parte 1
Cap07 parte 1Cap07 parte 1
Cap07 parte 1
 

Semelhante a Recursão e trampolines em JS

Recursividade em linguagem C
Recursividade em linguagem CRecursividade em linguagem C
Recursividade em linguagem CLeonardo Lima
 
mod3-programação-estruturada
mod3-programação-estruturadamod3-programação-estruturada
mod3-programação-estruturadadiogoa21
 
RevisãoCompactaFuncoesPonteiro.pptx
RevisãoCompactaFuncoesPonteiro.pptxRevisãoCompactaFuncoesPonteiro.pptx
RevisãoCompactaFuncoesPonteiro.pptxClaudia Ferlin
 
DOJO - TDD com C++
DOJO - TDD com C++DOJO - TDD com C++
DOJO - TDD com C++thiagodp
 
TDD em C++
TDD em C++TDD em C++
TDD em C++thiagodp
 
Lógica de programação pascal
Lógica de programação   pascalLógica de programação   pascal
Lógica de programação pascalJocelma Rios
 
4º Aula do Grupo de estudos sobre funções
4º Aula do Grupo de estudos sobre funções4º Aula do Grupo de estudos sobre funções
4º Aula do Grupo de estudos sobre funçõesFellyph Cintra
 
Mini-curso Programação Paralela e Distribuída
Mini-curso Programação Paralela e DistribuídaMini-curso Programação Paralela e Distribuída
Mini-curso Programação Paralela e DistribuídaDeivid Martins
 
TDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a Coroutines
TDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a CoroutinesTDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a Coroutines
TDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a Coroutinestdc-globalcode
 
Algoritmos e Estrutura de Dados - Aula 04
Algoritmos e Estrutura de Dados - Aula 04Algoritmos e Estrutura de Dados - Aula 04
Algoritmos e Estrutura de Dados - Aula 04thomasdacosta
 
Estrutura de linguagem C++
Estrutura de linguagem C++Estrutura de linguagem C++
Estrutura de linguagem C++Verônica Veiga
 
Atualização Java 8 (2014)
Atualização Java 8 (2014)Atualização Java 8 (2014)
Atualização Java 8 (2014)Helder da Rocha
 

Semelhante a Recursão e trampolines em JS (20)

Recursividade em linguagem C
Recursividade em linguagem CRecursividade em linguagem C
Recursividade em linguagem C
 
mod3-programação-estruturada
mod3-programação-estruturadamod3-programação-estruturada
mod3-programação-estruturada
 
RevisãoCompactaFuncoesPonteiro.pptx
RevisãoCompactaFuncoesPonteiro.pptxRevisãoCompactaFuncoesPonteiro.pptx
RevisãoCompactaFuncoesPonteiro.pptx
 
Aula1
Aula1Aula1
Aula1
 
SubProgramas
SubProgramasSubProgramas
SubProgramas
 
Funções e procedimentos
Funções e procedimentosFunções e procedimentos
Funções e procedimentos
 
Sobrecarga operadores
Sobrecarga operadoresSobrecarga operadores
Sobrecarga operadores
 
10-Matlab.pdf
10-Matlab.pdf10-Matlab.pdf
10-Matlab.pdf
 
DOJO - TDD com C++
DOJO - TDD com C++DOJO - TDD com C++
DOJO - TDD com C++
 
TDD em C++
TDD em C++TDD em C++
TDD em C++
 
Lógica de programação pascal
Lógica de programação   pascalLógica de programação   pascal
Lógica de programação pascal
 
Comandos e expressões
Comandos e expressõesComandos e expressões
Comandos e expressões
 
4º Aula do Grupo de estudos sobre funções
4º Aula do Grupo de estudos sobre funções4º Aula do Grupo de estudos sobre funções
4º Aula do Grupo de estudos sobre funções
 
Mini-curso Programação Paralela e Distribuída
Mini-curso Programação Paralela e DistribuídaMini-curso Programação Paralela e Distribuída
Mini-curso Programação Paralela e Distribuída
 
TDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a Coroutines
TDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a CoroutinesTDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a Coroutines
TDC2018SP | Trilha Android - Assincronismo no Android, de RxJava a Coroutines
 
Algoritmos - Aula 07 A - Lacos
Algoritmos - Aula 07 A - LacosAlgoritmos - Aula 07 A - Lacos
Algoritmos - Aula 07 A - Lacos
 
Threads 09: Paralelismo
Threads 09: ParalelismoThreads 09: Paralelismo
Threads 09: Paralelismo
 
Algoritmos e Estrutura de Dados - Aula 04
Algoritmos e Estrutura de Dados - Aula 04Algoritmos e Estrutura de Dados - Aula 04
Algoritmos e Estrutura de Dados - Aula 04
 
Estrutura de linguagem C++
Estrutura de linguagem C++Estrutura de linguagem C++
Estrutura de linguagem C++
 
Atualização Java 8 (2014)
Atualização Java 8 (2014)Atualização Java 8 (2014)
Atualização Java 8 (2014)
 

Mais de iMasters

O que você precisa saber para modelar bancos de dados NoSQL - Dani Monteiro
O que você precisa saber para modelar bancos de dados NoSQL - Dani MonteiroO que você precisa saber para modelar bancos de dados NoSQL - Dani Monteiro
O que você precisa saber para modelar bancos de dados NoSQL - Dani MonteiroiMasters
 
Postgres: wanted, beloved or dreaded? - Fabio Telles
Postgres: wanted, beloved or dreaded? - Fabio TellesPostgres: wanted, beloved or dreaded? - Fabio Telles
Postgres: wanted, beloved or dreaded? - Fabio TellesiMasters
 
Por que minha query esta lenta? - Suellen Moraes
Por que minha query esta lenta? - Suellen MoraesPor que minha query esta lenta? - Suellen Moraes
Por que minha query esta lenta? - Suellen MoraesiMasters
 
Relato das trincheiras: o dia a dia de uma consultoria de banco de dados - Ig...
Relato das trincheiras: o dia a dia de uma consultoria de banco de dados - Ig...Relato das trincheiras: o dia a dia de uma consultoria de banco de dados - Ig...
Relato das trincheiras: o dia a dia de uma consultoria de banco de dados - Ig...iMasters
 
ORMs heróis ou vilões dentro da arquitetura de dados? - Otávio gonçalves
ORMs heróis ou vilões dentro da arquitetura de dados? - Otávio gonçalvesORMs heróis ou vilões dentro da arquitetura de dados? - Otávio gonçalves
ORMs heróis ou vilões dentro da arquitetura de dados? - Otávio gonçalvesiMasters
 
SQL e NoSQL trabalhando juntos: uma comparação para obter o melhor de ambos -...
SQL e NoSQL trabalhando juntos: uma comparação para obter o melhor de ambos -...SQL e NoSQL trabalhando juntos: uma comparação para obter o melhor de ambos -...
SQL e NoSQL trabalhando juntos: uma comparação para obter o melhor de ambos -...iMasters
 
Arquitetando seus dados na prática para a LGPD - Alessandra Martins
Arquitetando seus dados na prática para a LGPD - Alessandra MartinsArquitetando seus dados na prática para a LGPD - Alessandra Martins
Arquitetando seus dados na prática para a LGPD - Alessandra MartinsiMasters
 
O papel do DBA no mundo de ciência de dados e machine learning - Mauro Pichil...
O papel do DBA no mundo de ciência de dados e machine learning - Mauro Pichil...O papel do DBA no mundo de ciência de dados e machine learning - Mauro Pichil...
O papel do DBA no mundo de ciência de dados e machine learning - Mauro Pichil...iMasters
 
Desenvolvimento Mobile Híbrido, Nativo ou Web: Quando usá-los - Juliana Chahoud
Desenvolvimento Mobile Híbrido, Nativo ou Web: Quando usá-los - Juliana ChahoudDesenvolvimento Mobile Híbrido, Nativo ou Web: Quando usá-los - Juliana Chahoud
Desenvolvimento Mobile Híbrido, Nativo ou Web: Quando usá-los - Juliana ChahoudiMasters
 
Use MDD e faça as máquinas trabalharem para você - Andreza Leite
 Use MDD e faça as máquinas trabalharem para você - Andreza Leite Use MDD e faça as máquinas trabalharem para você - Andreza Leite
Use MDD e faça as máquinas trabalharem para você - Andreza LeiteiMasters
 
Entendendo os porquês do seu servidor - Talita Bernardes
Entendendo os porquês do seu servidor - Talita BernardesEntendendo os porquês do seu servidor - Talita Bernardes
Entendendo os porquês do seu servidor - Talita BernardesiMasters
 
Backend performático além do "coloca mais máquina lá" - Diana Arnos
Backend performático além do "coloca mais máquina lá" - Diana ArnosBackend performático além do "coloca mais máquina lá" - Diana Arnos
Backend performático além do "coloca mais máquina lá" - Diana ArnosiMasters
 
Dicas para uma maior performance em APIs REST - Renato Groffe
Dicas para uma maior performance em APIs REST - Renato GroffeDicas para uma maior performance em APIs REST - Renato Groffe
Dicas para uma maior performance em APIs REST - Renato GroffeiMasters
 
7 dicas de desempenho que equivalem por 21 - Danielle Monteiro
7 dicas de desempenho que equivalem por 21 - Danielle Monteiro7 dicas de desempenho que equivalem por 21 - Danielle Monteiro
7 dicas de desempenho que equivalem por 21 - Danielle MonteiroiMasters
 
Quem se importa com acessibilidade Web? - Mauricio Maujor
Quem se importa com acessibilidade Web? - Mauricio MaujorQuem se importa com acessibilidade Web? - Mauricio Maujor
Quem se importa com acessibilidade Web? - Mauricio MaujoriMasters
 
Service Mesh com Istio e Kubernetes - Wellington Figueira da Silva
Service Mesh com Istio e Kubernetes - Wellington Figueira da SilvaService Mesh com Istio e Kubernetes - Wellington Figueira da Silva
Service Mesh com Istio e Kubernetes - Wellington Figueira da SilvaiMasters
 
Erros: Como eles vivem, se alimentam e se reproduzem? - Augusto Pascutti
Erros: Como eles vivem, se alimentam e se reproduzem? - Augusto PascuttiErros: Como eles vivem, se alimentam e se reproduzem? - Augusto Pascutti
Erros: Como eles vivem, se alimentam e se reproduzem? - Augusto PascuttiiMasters
 
Elasticidade e engenharia de banco de dados para alta performance - Rubens G...
Elasticidade e engenharia de banco de dados para alta performance  - Rubens G...Elasticidade e engenharia de banco de dados para alta performance  - Rubens G...
Elasticidade e engenharia de banco de dados para alta performance - Rubens G...iMasters
 
Construindo aplicações mais confiantes - Carolina Karklis
Construindo aplicações mais confiantes - Carolina KarklisConstruindo aplicações mais confiantes - Carolina Karklis
Construindo aplicações mais confiantes - Carolina KarklisiMasters
 
Monitoramento de Aplicações - Felipe Regalgo
Monitoramento de Aplicações - Felipe RegalgoMonitoramento de Aplicações - Felipe Regalgo
Monitoramento de Aplicações - Felipe RegalgoiMasters
 

Mais de iMasters (20)

O que você precisa saber para modelar bancos de dados NoSQL - Dani Monteiro
O que você precisa saber para modelar bancos de dados NoSQL - Dani MonteiroO que você precisa saber para modelar bancos de dados NoSQL - Dani Monteiro
O que você precisa saber para modelar bancos de dados NoSQL - Dani Monteiro
 
Postgres: wanted, beloved or dreaded? - Fabio Telles
Postgres: wanted, beloved or dreaded? - Fabio TellesPostgres: wanted, beloved or dreaded? - Fabio Telles
Postgres: wanted, beloved or dreaded? - Fabio Telles
 
Por que minha query esta lenta? - Suellen Moraes
Por que minha query esta lenta? - Suellen MoraesPor que minha query esta lenta? - Suellen Moraes
Por que minha query esta lenta? - Suellen Moraes
 
Relato das trincheiras: o dia a dia de uma consultoria de banco de dados - Ig...
Relato das trincheiras: o dia a dia de uma consultoria de banco de dados - Ig...Relato das trincheiras: o dia a dia de uma consultoria de banco de dados - Ig...
Relato das trincheiras: o dia a dia de uma consultoria de banco de dados - Ig...
 
ORMs heróis ou vilões dentro da arquitetura de dados? - Otávio gonçalves
ORMs heróis ou vilões dentro da arquitetura de dados? - Otávio gonçalvesORMs heróis ou vilões dentro da arquitetura de dados? - Otávio gonçalves
ORMs heróis ou vilões dentro da arquitetura de dados? - Otávio gonçalves
 
SQL e NoSQL trabalhando juntos: uma comparação para obter o melhor de ambos -...
SQL e NoSQL trabalhando juntos: uma comparação para obter o melhor de ambos -...SQL e NoSQL trabalhando juntos: uma comparação para obter o melhor de ambos -...
SQL e NoSQL trabalhando juntos: uma comparação para obter o melhor de ambos -...
 
Arquitetando seus dados na prática para a LGPD - Alessandra Martins
Arquitetando seus dados na prática para a LGPD - Alessandra MartinsArquitetando seus dados na prática para a LGPD - Alessandra Martins
Arquitetando seus dados na prática para a LGPD - Alessandra Martins
 
O papel do DBA no mundo de ciência de dados e machine learning - Mauro Pichil...
O papel do DBA no mundo de ciência de dados e machine learning - Mauro Pichil...O papel do DBA no mundo de ciência de dados e machine learning - Mauro Pichil...
O papel do DBA no mundo de ciência de dados e machine learning - Mauro Pichil...
 
Desenvolvimento Mobile Híbrido, Nativo ou Web: Quando usá-los - Juliana Chahoud
Desenvolvimento Mobile Híbrido, Nativo ou Web: Quando usá-los - Juliana ChahoudDesenvolvimento Mobile Híbrido, Nativo ou Web: Quando usá-los - Juliana Chahoud
Desenvolvimento Mobile Híbrido, Nativo ou Web: Quando usá-los - Juliana Chahoud
 
Use MDD e faça as máquinas trabalharem para você - Andreza Leite
 Use MDD e faça as máquinas trabalharem para você - Andreza Leite Use MDD e faça as máquinas trabalharem para você - Andreza Leite
Use MDD e faça as máquinas trabalharem para você - Andreza Leite
 
Entendendo os porquês do seu servidor - Talita Bernardes
Entendendo os porquês do seu servidor - Talita BernardesEntendendo os porquês do seu servidor - Talita Bernardes
Entendendo os porquês do seu servidor - Talita Bernardes
 
Backend performático além do "coloca mais máquina lá" - Diana Arnos
Backend performático além do "coloca mais máquina lá" - Diana ArnosBackend performático além do "coloca mais máquina lá" - Diana Arnos
Backend performático além do "coloca mais máquina lá" - Diana Arnos
 
Dicas para uma maior performance em APIs REST - Renato Groffe
Dicas para uma maior performance em APIs REST - Renato GroffeDicas para uma maior performance em APIs REST - Renato Groffe
Dicas para uma maior performance em APIs REST - Renato Groffe
 
7 dicas de desempenho que equivalem por 21 - Danielle Monteiro
7 dicas de desempenho que equivalem por 21 - Danielle Monteiro7 dicas de desempenho que equivalem por 21 - Danielle Monteiro
7 dicas de desempenho que equivalem por 21 - Danielle Monteiro
 
Quem se importa com acessibilidade Web? - Mauricio Maujor
Quem se importa com acessibilidade Web? - Mauricio MaujorQuem se importa com acessibilidade Web? - Mauricio Maujor
Quem se importa com acessibilidade Web? - Mauricio Maujor
 
Service Mesh com Istio e Kubernetes - Wellington Figueira da Silva
Service Mesh com Istio e Kubernetes - Wellington Figueira da SilvaService Mesh com Istio e Kubernetes - Wellington Figueira da Silva
Service Mesh com Istio e Kubernetes - Wellington Figueira da Silva
 
Erros: Como eles vivem, se alimentam e se reproduzem? - Augusto Pascutti
Erros: Como eles vivem, se alimentam e se reproduzem? - Augusto PascuttiErros: Como eles vivem, se alimentam e se reproduzem? - Augusto Pascutti
Erros: Como eles vivem, se alimentam e se reproduzem? - Augusto Pascutti
 
Elasticidade e engenharia de banco de dados para alta performance - Rubens G...
Elasticidade e engenharia de banco de dados para alta performance  - Rubens G...Elasticidade e engenharia de banco de dados para alta performance  - Rubens G...
Elasticidade e engenharia de banco de dados para alta performance - Rubens G...
 
Construindo aplicações mais confiantes - Carolina Karklis
Construindo aplicações mais confiantes - Carolina KarklisConstruindo aplicações mais confiantes - Carolina Karklis
Construindo aplicações mais confiantes - Carolina Karklis
 
Monitoramento de Aplicações - Felipe Regalgo
Monitoramento de Aplicações - Felipe RegalgoMonitoramento de Aplicações - Felipe Regalgo
Monitoramento de Aplicações - Felipe Regalgo
 

Recursão e trampolines em JS

Notas do Editor

  1. Uma visão geral sobre recursão e trampolines
  2. Antes de falar sobre recursão vamos falar sobre recursão
  3. 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
  4. 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.
  5. 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)
  6. 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:
  7. 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 change Recursion, 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.
  8. 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.
  9. 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)
  10. 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)
  11. 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
  12. 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
  13. 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.
  14. 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 frame Differently 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.
  15. Como fazer o tco funfar?
  16. 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.
  17. http://25.media.tumblr.com/7dbfc8ccf3d93aa83aa98a2d9e269c58/tumblr_mx55sc2PYy1qbx12bo2_500.gif
  18. 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:
  19. hey’re always the last thing to be done and evaluated before the return and the return value of this called function is returned by the calling function.
  20. Pra refatorar eu preciso fazer um acumulador
  21. Retorna uma função com um argumento a mais chamado argumento Assim o retorno sempre será a própria função
  22. http://25.media.tumblr.com/7dbfc8ccf3d93aa83aa98a2d9e269c58/tumblr_mx55sc2PYy1qbx12bo2_500.gif
  23. 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.
  24. Conceito legal de programação
  25. CPS desugars function return, exceptions and first-class continuations; function call turns into a single jump instruction
  26. SCHEME?
  27. 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
  28. FORMA DE SIMULAR AVALIACAO DEVAGAR AVALIACAO PREGUICOSA
  29. Call-by-ned: evaluation mechanism that delays the evaluation of an expression until its value is needed.
  30. 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) const printAsString = (num) => console.log(`Given ${num}`) const addOneAndContinue = (num, cc) => { const result = num + 1 cc(result) } addOneAndContinue(2, printAsString) // 'Given 3' const continueProgramWith = (data) => { // Continues program with data } readFileAsync('path/to/file', (err, response) => { if (err) { // handle error return } continueProgramWith(response) }) 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
  31. 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.
  32. Pra refatorar eu preciso fazer um acumulador
  33. Funcao identdade, que é um termo pra uma função que torna tudo que você poe dentro dela
  34. Para extrair o valor final
  35. Junta alguns conceitos ja abordados
  36. is common in functional programming and provides us a way to call our function in tail position without growing the stack.
  37. As used in some Lisp implementations
  38. http://25.media.tumblr.com/7dbfc8ccf3d93aa83aa98a2d9e269c58/tumblr_mx55sc2PYy1qbx12bo2_500.gif
  39. 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. Remember how I said, when discussing unbounded continuations, that in "regular" languages like Python we're just cheating and simulating continuations with function calls? Trampolines is what make this viable without blowing the stack def fact_cps_thunked(n, cont): if n == 0: return cont(1) else: return lambda: fact_cps_thunked( n - 1, lambda value: lambda: cont(n * value)) e o que é esse thunk? é uma expresão em uma função de argumetnos. Esse encapsulamento "atrasa" a avaliacao da expressao ate o ponto em que a funcao é chamada algo como > 2 * (3 + 4) // 14 > const f = () => 2 * (3 + 4) > f() // 14
  40. 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:
  41. 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:
  42. 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:
  43. 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 frame Differently 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.
  44. http://25.media.tumblr.com/7dbfc8ccf3d93aa83aa98a2d9e269c58/tumblr_mx55sc2PYy1qbx12bo2_500.gif
  45. 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.
  46. http://www.crockford.com/javascript/little.html
  47. http://25.media.tumblr.com/7dbfc8ccf3d93aa83aa98a2d9e269c58/tumblr_mx55sc2PYy1qbx12bo2_500.gif
  48. http://25.media.tumblr.com/7dbfc8ccf3d93aa83aa98a2d9e269c58/tumblr_mx55sc2PYy1qbx12bo2_500.gif