SlideShare una empresa de Scribd logo
1 de 127
Descargar para leer sin conexión
Introducción a la programación
funcional en JavaScript
Hola!
Soy Ricardo Pallás
https://github.com/RPallas92/congreso-web-2016
Índice
1. Introducción (primeros ejercicios y
conceptos)
2. Trabajando con arrays sin bucles
3. Teoría de Categorías
4. Ejercicio final (App web vídeos: React + FP)
5. Conclusiones
1.
Introducción
Primeros ejercicios
y conceptos:
Funciones puras
¿Qué es la
programación
funcional?
‘’ La programación funcional es un paradigma de
programación que se basa en el uso de funciones
modeladas como funciones matemáticas.
La esencia es que los programas son la
combinación de expresiones. Una expresión puede
ser un valor concreto, variables y también
funciones.
¿Qué es una
función?
‘’
Una función es una relación entre un conjunto de
posibles entradas y un conjunto de posibles
salidas.
La función en sí misma, representa la relación.
Gaviotas
Unir: unir dos bandadas de gaviotas en una sola
Engendrar: la bandada se multiplica por el número de
gaviotas que engendra cada una
var Bandada = function(n) { this.gaviotas = n }
Bandada.prototype.unir = function(otra) {
this.gaviotas += otra.gaviotas;
return this;
}
Bandada.prototype.engendrar = function(otra) {
this.gaviotas = this.gaviotas * otra.gaviotas;
return this;
}
var bandada1 = new Bandada(4);
var bandada2 = new Bandada(2);
var bandada3 = new Bandada(0);
var resultado = bandada1.unir(bandada3)
.engendrar(bandada2).unir(bandada1.engendrar(bandada2)).gaviotas;
//=> 32
var unir = function(bandada_x, bandada_y) { return bandada_x + bandada_y; };
var engendrar = function(bandada_x, bandada_y) { return bandada_x * bandada_y; };
var bandada_a = 4;
var bandada_b = 2;
var bandada_c = 0;
var result = unir(
engendrar(bandada_b, unir(bandada_a, bandada_c)), engendrar(bandada_a, bandada_b)
);
//=>16
var sumar = function(x, y) { return x + y; };
var multiplicar = function(x, y) { return x * y; };
var bandada_a = 4;
var bandada_b = 2;
var bandada_c = 0;
var result = sumar(
multiplicar(bandada_b, sumar(bandada_a, bandada_c)), multiplicar(bandada_a, bandada_b)
);
//=>16
// associative
sumar(sumar(x, y), z) === sumar(x, sumar(y, z));
// commutative
sumar(x, y) === sumar(y, x);
// identity
sumar(x, 0) === x;
// distributive
multiplicar(x, sumar(y,z)) === sumar(multiplicar(x, y), multiplicar(x, z));
Funciones puras
Una función pura es una función que, dada la
misma entrada, siempre devuelve la misma
salida y no tiene ningún efecto colateral.
¿Qué es la programación funcional,
otra vez?
En gran medida, programas con
funciones puras: funciones que
reciben valores de entrada,
devuelve valores de salida, y no
hacen de más.
El problema: los efectos colaterales
Una función pura: libre de efectos
colaterales
function add(x,y) {
return x + y;
}
Una función impura: corrupta (no
declara todo lo que hace realmente)
function add(x,y) {
var z = x + y;
console.log('result of the sum: ', z);
return z;
}
// pure
xs.slice(0,3)
//=> [1,2,3]
xs.slice(0,3)
//=> [1,2,3]
xs.slice(0,3)
//=> [1,2,3]
// impure
xs.splice(0,3)
//=> [1,2,3]
xs.splice(0,3)
//=> [4,5]
xs.splice(0,3)
//=> []
var xs = [1,2,3,4,5]
// impure
var minimum = 21;
var checkAge = function(age) {
return age >= minimum;
}
// pure
var checkAge = function(age) {
var minimum = 21;
return age >= minimum;
}
// impure
var greeting = function(name) {
console.log("hi, " + name + "!")
}
// pure
var greeting = function(name) {
return "hi, " + name + "!";
}
console.log(greeting("Jonas"))
‘’
Una función es una relación entre un conjunto de
posibles entradas y un conjunto de posibles
salidas.
La función en sí misma, representa la relación.
Recordatorio
Una entrada, una salida
...
(-2, -1)
(0 , 0 )
(2 , 1 )
(4 , 2 )
(8 , 4 )
...
Dominio Rango
… -2 0 2 4 8 ... … -1 0 1 2 4 ...
Una entrada, una salida
var toLowerCase = {"A":"a", "B": "b", "C": "c", "D": "d", "E": "e", "D": "d"}
toLowerCase["C"]
//=> "c"
var isPrime = {1: false, 2: true, 3: true, 4: false, 5: true, 6: false}
isPrime[3]
//=> true
¿Y si hay múltiples argumentos?
//+ add :: [Number, Number] -> Number
var add = function(numbers) {
return numbers[0] + numbers[1]
}
¿Y si hay múltiples argumentos?
//+ add :: ? -> Number
var add = function() {
return arguments[0] + arguments[1]
}
‘’
Función “curried”:
“Una función que devuelve una
nueva función hasta que recibe todos
sus argumentos”
Currying
Currying
//+ add :: Number -> Number -> Number
var add = curry(function(x, y) {
return x + y
})
Currying
add
//=> function(x,y) { return x + y }
add(2,3)
//=> 5
add(2)
//=> function(y) { return 2 + y }
Currying
//+ get :: String -> {String: a} -> a
var get = curry(function(prop, obj) {
return obj[prop];
})
var user = {id: 15, name: "Jorge Aznar", email: "jaznar@email.com"}
get('email', user)
//=> jaznar@email.com
//+ email :: {String: a} -> a
var email = get('email')
//=> function(obj){ return obj[‘email’] }
email(user)
//=> jaznar@email.com
Currying
//+ filter :: (a -> Bool) -> [a] -> [a]
var filter = curry(function(f, xs) {
return xs.filter(f);
})
//+ odds :: [a] -> [a]
var odds = filter(isOdd)
odds([1,2,3])
//=> [1, 3]
Currying
var emails = map(email)
var users = [jesus, jorge, ja, jbalbas]
emails(users)
//=> ["jesus@lopez.org", "jorge@aznar.net",
"ja@samitier.com", "jota@balbas.es"]
Currying
//+ goodArticles :: [Article] -> [Article]
var goodArticles = function(articles) {
return _.filter(articles, function(article){
return _.isDefined(article)
})
}
//+ goodArticles :: [Article] -> [Article]
var goodArticles = filter(isDefined)
Currying
//+ getChildren :: DOM -> [DOM]
var getChildren = function(el) {
return el.childNodes
}
//+ getALLChildren :: [DOM] -> [[DOM]]
var getAllChildren = function(els) {
return _.map(els, function(el) {
return getChildren(el)
})
}
var getChildren = get('childNodes')
var getAllChildren = map(getChildren)
Composición
La composición de funciones es aplicar una
función a los resultados de otra
Composición
//+ compose :: (b -> c) -> (a -> b) -> a -> c
var compose = curry(function(f, g, x) {
return f(g(x))
})
Composición
//+ head :: [a] -> a
var head = function(x) { return x[0] }
//+ last :: [a] -> a
var last = compose(head, reverse)
last(['Java', 'JavaScript', 'PHP'])
//=> PHP
Composición
//+ wordCount :: String -> Number
var wordCount = function(sentence) {
var count = split(' ', sentence)
return length(count)
}
//+ wordCount :: String -> Number
var wordCount = compose(length, split(' '))
wordCount("Soy una frase de 6 palabras")
//=> 6
Composición
'B' <- 'b' <- 'Congreso Web'
compose(toUpperCase, last)('Congreso Web')
Composición
// Ley asociativa
compose(f, compose(g, h)) == compose(compose(f, g), h)
Composición
compose(toUpperCase, compose(head, reverse))
// ó
compose(compose(toUpperCase, head), reverse)
Composición
//+ lastUpper :: [String] -> String
var lastUpper = compose(toUpperCase, head, reverse)
lastUpper(['Java', 'PHP', 'JavaScript'])
//=> 'JAVASCRIPT'
//+ lastUpper :: [String] -> String
var loudLastUpper = compose(exclaim, toUpperCase, head, reverse)
loudLastUpper(['Java', 'PHP', 'JAVASCRIPT'])
//=> 'JAVASCRIPT!'
Composición
? <- map(['JavaScript', 'Rust']) <- ['JavaScript', 'Rust'] <- ['Rust', 'JavaScript']
compose(toUpperCase, map, reverse)(['Rust', 'JavaScript'])
Composición
['JAVASCRIPT', 'RUST'] <- ['JavaScript', 'Rust'] <- ['Rust', 'JavaScript']
compose(map(toUpperCase), reverse)(['Rust', 'JavaScript'])
2.
Trabajando con
arrays
Sin bucles, con
funciones puras
Inciso: Trabajar con colecciones (sin
bucles)
La mayoría de las operaciones que hacemos se
pueden conseguir con 5 funciones:
▣ map
▣ filter
▣ reduce
▣ concatAll
▣ zip
Prácticamente, todos los bucles se pueden
sustituir por estas funciones.
Ejercicios
Vamos a practicar el uso de las 5 funciones
https://github.com/RPallas92/congreso-web-2016
Directorio parte2
3.
Teoría de
Categorías
Primeros ejercicios
y conceptos:
Funciones puras
Teoría de Categorías
Es una rama abstracta de las matemáticas que
formaliza conceptos de diferentes ramas como
teoría de conjuntos, teoría de tipos, teoría de
grupos, lógica y más.
Principalmente, se trabaja con objetos,
morfismos y transformaciones. (Similitud con la
programación)
Categoría
Es una colección con los siguientes
componentes:
▣ Una colección de objetos
▣ Una colección de morfismos
▣ Una noción de composición de los morfismos
▣ Un morfismo en concreto, llamado identidad
Categoría
▣ La Teoría de Categorías es suficientemente
abstracta para modelar muchas cosas, pero
vamos a centrarnos en tipos y funciones
Categoría
Una colección de objetos:
▣ Los objetos serán tipos de datos. String,
Boolean, Number, Object.
▣ Boolean como el conjunto [true, false]
▣ Number como el conjunto de todos los
posibles valores numéricos
Categoría
Una colección de morfismos:
▣ Los morfismos serán las funciones normales
que escribimos diariamente.
Categoría
Una noción de composición de los morfismos:
▣ Nuestra función compose, presentada
anteriormente
▣ Que compose cumpla la ley asociativa no es
casualidad.
▣ Cualquier composición en la Teoría de
Categorías debe cumplirla
Categoría: Compsición
Categoría
Un morfismo concreto llamado identidad:
▣ Nueva función id
▣ Recibe una entrada, y la devuelve, nada más
var id = function(x) {
return x;
};
Almacena un valor, será utilizada más adelante
Identidad
// identity
compose(id, f) == compose(f, id) == f;
// true
▣ Esta propiedad se cumple para todas las
funciones unarias.
▣ Es como la identidad en los números
Identidad
// identity
compose(id, f) == compose(f, id) == f;
// true
▣ Esta propiedad se cumple para todas las
funciones unarias.
▣ Es como la identidad en los números
Nulls
Callbacks
Errors
Side effects
Objetos
▣ Contenedores/Wrappers para valores
▣ No tienen métodos
▣ No tienen propiedades
▣ Seguramente, no crees los tuyos propios
Objetos
var Container = function(val) {
this.val = val;
}
//+ Container :: a -> Container(a)
Container.of = function(x) {
return new Container(x);
};
Container.of(3)
//=> Container {val: 3}
Objetos
capitalize("flamethrower")
//=> "Flamethrower"
capitalize(Container.of("flamethrower"))
//=> [object Object]
Objetos
//+ map :: (a -> b) -> Container(a) -> Container(b)
Container.prototype.map = function(f) {
return Container.of(f(this.val));
}
Container.of("flamethrower").map(function(s){
return capitalize(s)
})
//=> Container(“Flamethrower”)
Objetos
//+ map :: (a -> b) -> Container(a) -> Container(b)
Container.prototype.map = function(f) {
return Container.of(f(this.val));
}
Container.of("flamethrower").map(capitalize)
//=> Container(“Flamethrower”)
Objetos
Container.of(3).map(add(1))
//=> Container(4)
[3].map(add(1))
//=> [4]
Objetos
Container.of([1,2,3]).map(reverse).map(first)
//=> Container(3)
Container.of("flamethrower").map(length).map(add(1))
//=> Container(13)
Objetos
//+ map :: Functor F => (a -> b) -> F a -> F b
var map = _.curry(function(f, obj) {
return obj.map(f)
})
Container.of(3).map(add(1)) // Container(4)
map(add(1), Container.of(3)) // Container(4)
Objetos
map(match(/cat/g), Container.of("catsup"))
//=> Container([“cat”])
map(compose(first, reverse),Container.of("dog"))
//=> Container(“g”)
‘’
“Un objeto o estructura
de datos que puede ser
mapeada”
▣ Funciones: map
FUNCTOR
Aquellos problemáticos null
//+ getElement :: String -> DOM
var getElement = document.querySelector
//+ getNameParts :: String -> [String]
var getNameParts = compose(split(' '), getText, getElement)
getNameParts('#full_name')
//=> ['José', 'Luis', 'Bárcenas', 'Gutiérrez']
Aquellos problemáticos null
//+ getElement :: String -> DOM
var getElement = document.querySelector
//+ getNameParts :: String -> [String]
var getNameParts = compose(split(' '), getText, getElement)
getNameParts('#fullname')
//=> BOOOOOOOOMM!!!!!!
Maybe
▣ Captura un null check
▣ Es posible que el valor no esté
▣ A veces tienen dos subclases: Just/Nothing
▣ En otros lenguajes se llama Option
Maybe
//+ map :: (a -> b) -> Maybe(a) -> Maybe(b)
var _Maybe.prototype.map = function(f) {
return this.val ? Maybe.of(f(this.val)) : Maybe.of(null);
}
map(capitalize, Maybe.of("flamethrower"))
//=> Maybe(“Flamethrower”)
Maybe
//+ map :: (a -> b) -> Maybe(a) -> Maybe(b)
var _Maybe.prototype.map = function(f) {
return this.val ? Maybe.of(f(this.val)) : Maybe.of(null);
}
map(capitalize, Maybe.of(null))
//=> Maybe(null)
Maybe
//+ firstMatch :: String -> String
var firstMatch = compose(first, match(/java/g))
firstMatch("python")
//=> BOOOM!!!
Maybe
//+ firstMatch :: String -> Maybe(String)
var firstMatch = compose(map(first), Maybe.of, match(/java/g))
firstMatch("python")
//=> Maybe(null)
Maybe
//+ firstMatch :: String -> Maybe(String)
var firstMatch = compose(map(first), Maybe.of, match(/java/g))
firstMatch("javascript")
//=> Maybe(“java”)
Either
▣ Utilizado para manejo de excepciones pura
▣ Es como Maybe, pero con un mensaje de
error embebido
▣ Tienen dos subclases: Left/Right
▣ Mapea la función sobre el Right, ignora el Left
Either
map(function(x) { return x + 1; }, Right.of(2))
//=> Right(3)
map(function(x) { return x + 1; }, Left.of(‘some message’))
//=> Left(‘some message’)
Either
//+ determineAge :: User -> Either(String, Number)
var determineAge = function(user){
return user.age ? Right.of(user.age) : Left.of("couldn’t get
age");
}
//+ yearOlder :: User -> Either(String, Number)
var yearOlder = compose(map(add(1)), determineAge)
yearOlder({age: 22})
//=> Right(23)
var jordiHurtado = {age: null}
yearOlder(jordiHurtado)
//=> Left("couldn’t get age")
IO
▣ Utilizado para lazy computation
▣ Utilizado para manejar los efectos colaterales
▣ Para ejectuar la operación, se debe llamar a
runIO
▣ map añade la función a una lista de
operaciones a ejecutar
IO
//+ email_io :: IO(String)
var email_io = new IO(function(){ return $("#email").val() })
//+ msg_io :: IO(String)
var msg_io = map(concat("Bienvenido "), email_io)
msg_io.unsafePerformIO()
//=> ”Bienvenido jbalbas@email.net”
unsafePerfomIO()
IO
//+ getBgColor :: JSON -> Color
var getBgColor = compose(get("background-color"), JSON.parse)
//+ bgPref :: _ -> IO(Color)
var bgPref = compose(map(getBgColor), Store.get("preferences"))
//+ app :: _ -> IO(Color)
var app = bgPref()
//=> IO()
app.unsafePerformIO()
//=> #efefef
IO
//+ email_io :: _ -> IO(String)
var email_io = new IO(function(){ return $("#email").val() }
//+ getValue :: String -> IO(String)
var getValue = function(sel){
return new IO(function(){ return $(sel).val() });
}
Task / Future
▣ Se utiliza para operaciones asíncronas
▣ Representa un valor en el tiempo
▣ Para ejecutar la operación, se debe llamar a
fork
▣ Fork recibe una función como valor
▣ Se llama a la función con el resultado del Task
una vez que lo tiene
Task / Future
//+ makeHtml :: Post -> HTML
var makeHtml = function(post){ return "<div>"+post.title+"</div>"};
//+ page_f :: Future(Html)
var page_f = map(makeHtml, http.get('/posts/2'))
page_f.fork(
function(err) { throw(err) },
function(page){ $('#container').html(page) }
)
Pointed Functors
▣ Es un Functor con un método of
▣ Of :: a -> F a
▣ Permite poner valores en un contexto mínimo
que retiene el valor (o contexto puro)
▣ También llamado pure
Pointed Functors
▣ Es un Functor con un método of
▣ Of :: a -> F a
▣ Permite poner valores en un contexto mínimo
que retiene el valor (o contexto puro)
▣ También llamado pure
Pointed Functors
Container.of(2)
// Container(2)
Maybe.of(reverse)
// Maybe(reverse)
Future.of(match(/dubstep/))
// Future(match(/dubstep/))
IO.of('hack')
// IO(function(){ return 'hack'})
Task / Future
//+ lineCount :: String -> Number
var lineCount = compose(length, split(/n/))
//+ fileLineCount :: String -> Future(Number)
var fileLineCount = compose(map(lineCount), readFile)
fileLineCount("mydoc.txt").fork(log, log)
//=> 34
Leyes de los functores
// identity
map(id) == id
// composition
compose(map(f), map(g)) == map(compose(f, g))
Pregunta
Haz una llamada a una api con una id, y obtén un
post (puede existir o no)
Respuesta
Future(Maybe(Post))
Mónadas
▣ Patrón de diseño utilizado para describir
computaciones como series de pasos (o
computaciones anidadas)
▣ Utilizadas para gestionar los efectos
colaterales
▣ O para controlar la complejidad
Funciones:
▣ join
▣ chain
Mónadas
▣ join :: M M a -> M a
▣ chain :: (a -> M b) -> M a -> M b
Una mónada es un Pointed Functor añadiendo
los métodos join y chain
Mónadas
join(Container.of(Container.of(2)))
//=> Container(2)
Mónadas
//+ getTrackingId :: Order -> Maybe(TrackingId)
var getTrackingId = compose(Maybe.of, get("tracking_id"))
//+ findOrder :: Number -> Maybe(Order)
var findOrder = compose(Maybe.of, Api.findOrder)
//+ getOrderTracking :: Number -> Maybe(Maybe(TrackingId))
var getOrderTracking = compose(map(getTrackingId), findOrder)
//+ renderPage :: Number -> Maybe(Maybe(Html))
var renderPage = compose(map(map(renderTemplate)), getOrderTracking)
Mónadas
//+ getTrackingId :: Order -> Maybe(TrackingId)
var getTrackingId = compose(Maybe.of, get("tracking_id"))
//+ findOrder :: Number -> Maybe(Order)
var findOrder = compose(Maybe.of, Api.findOrder)
//+ getOrderTracking :: Number -> Maybe(TrackingId)
var getOrderTracking = compose(join, map(getTrackingId), findOrder)
//+ renderPage :: Number -> Maybe(Html)
var renderPage = compose(map(renderTemplate), getOrderTracking)
Mónadas
//+ :: setSearchInput :: String -> IO(_)
var setSearchInput = function(x) { return new IO(function() { ("#input").val(x); }) }
//+ :: searchTerm :: IO(String)
var searchTerm = new IO(function() { getParam("term", location.search) })
//+ :: initSearchForm :: IO(IO(_))
var initSearchForm = map(setSearchInput, searchTerm)
initSearchForm.unsafePerformIO().unsafePerformIO();
Mónadas
//+ :: setSearchInput :: String -> IO(_)
var setSearchInput = function(x) { return new IO(function() { ("#input").val(x); }) }
//+ :: searchTerm :: IO(String)
var searchTerm = new IO(function() { getParam("term", location.search) })
//+ :: initSearchForm :: IO(IO(_))
var initSearchForm = map(setSearchInput, searchTerm)
join(initSearchForm).unsafePerformIO();
Mónadas
//+ sendToServer :: Params -> Future(Response)
var sendToServer = httpGet('/upload')
//+ uploadFromFile :: String -> Future(Response)
var uploadFromFile = compose(join, map(sendToServer), readFile)
uploadFromFile("/tmp/my_file.txt").fork(logErr, alertSuccess)
Mónadas
//+ sendToServer :: Params -> Future(Response)
var sendToServer = httpGet('/upload')
//+ uploadFromFile :: String -> Future(Response)
var uploadFromFile = compose(join, map(sendToServer), join, map(readFile), askUser)
uploadFromFile('what file?').fork(logErr, alertSuccess)
Mónadas
//+ chain :: (a -> M b) -> M a -> M b
var chain = function(f) {
return compose(join, map(f))
}
// también llamado flatMap
Mónadas
//+ sendToServer :: Params -> Future(Response)
var sendToServer = httpGet('/upload')
//+ uploadFromFile :: String -> Future(Response)
var uploadFromFile = compose(chain(sendToServer), chain(readFile), askUser)
uploadFromFile('what file?').fork(logErr, alertSuccess)
Functores aplicativos
▣ Ejecutar computaciones completas en un
contexto
▣ Permite aplicar un functor a otro
Funciones:
▣ ap
▣ liftA2
▣ liftA3
▣ lifA..N
Functores aplicativos
add(Container.of(2), Container.of(3));
//NaN
var container_of_add_2 = map(add, Container.of(2));
// Container(add(2))
Functores aplicativos
map(add(1), Container(2))
//=> Container(3)
add(Container.of(2), Container.of(3));
//NaN
map(add, Container(2))
//=> Container(add(2))
Functores aplicativos
▣ ap :: A (a -> b) -> A a -> A b
▣ Un functor aplicativo es un Pointed Functor
con un método ap
Functores aplicativos
Container.of(f).ap(Container(x))
//=> Container(f(x))
Container.of(f).ap(Container(x)).ap(Container(y))
//=> Container(f(x, y))
Functores aplicativos
Container.of(add).ap(Container(1)).ap(Container(3))
//=> Container(4)
Functores aplicativos
Maybe.of(add).ap(Maybe(1)).ap(Maybe(3))
//=> Maybe(4)
Maybe.of(add).ap(Maybe(1)).ap(Maybe(null))
//=> Maybe(null)
Functores aplicativos
var loadPage = _.curry(function(products, reviews){
render(products.zip(reviews)
})
Future.of(loadPage)
.ap(Api.get('/products'))
.ap(Api.get('/reviews'))
Functores aplicativos
var getVal = compose(Maybe, get('value'), document.querySelector)
var save = _.curry(function(email, pass){ return User(email, pass) })
Maybe.of(save).ap(getVal('#email')).ap(getVal('#password'))
//=> Maybe(user)
Functores aplicativos
var getVal = compose(Maybe, pluck('value'), document.querySelector)
var save = _.curry(function(email, pass){ return User(email, pass) })
liftA2(save, getVal('#email'), getVal('#password'))
//=> Maybe(user)
Fantasy Land
https://github.com/fantasyland/fantasy-land
4.
Ejercicio final
Aplicación de
ejemplo
Aplicación buscador de vídeos
Youtube
▣ Vista: React
▣ Manipulación de datos: Ramda
▣ Maybe: folktale/data.maybe
▣ Either: folktale/data.either
▣ Task: folktale/data.task
React
▣ Biblioteca para crear interfaces
de usuario en JavaScript
▣ Simple
▣ Declarativa
▣ Modular: componentes
reusables
▣ Utiliza la composición de los
componentes para crear nuevos
▣
https://facebook.github.io/react
Ramda
▣ Biblioteca para programación
funcional práctica en JavaScript
▣ Similar a lodash o undescore
▣ Todas las funciones están curried
▣ Parámetros de las funciones
ordenados para favorecer el curry
▣ Trabaja bien con implementaciones
Mónadas, functores, etc.
http://ramdajs.com
Folktale
▣ Suite de bibliotecas para programación
funcional genérica en JavaScript
▣ Utilizaremos su implementación de
□ Maybe
□ Either
□ Task (Future)
http://folktalejs.org
App vídeos YouTube
▣ Permite buscar vídeos “al vuelo”
▣ Muestra los vídeos como un grid
▣ Al hacer clic sobre uno, se abre su
página de YouTube
App vídeos YouTube
App vídeos YouTube
▣ Permite buscar vídeos “al vuelo”
▣ Muestra los vídeos como un grid
▣ Al hacer clic sobre uno, se abre su
página de YouTube
5.
Conclusiones
Conclusiones
▣ Crear funciones pequeñas (Divide and
conquer (and reuse))
▣ Composición de esas funciones
▣ Utilizar funciones puras
▣ Tener aislada la parte impura del
programa
▣ Estilo declarativo vs imperativo
¡Gracias!
¿Preguntas?
@pallasr
https://github.com/MostlyAdequate/mostly-
adequate-guide

Más contenido relacionado

La actualidad más candente

La actualidad más candente (19)

Php funciones en detalle
Php   funciones en detallePhp   funciones en detalle
Php funciones en detalle
 
Programando con Python
Programando con PythonProgramando con Python
Programando con Python
 
Funciones en php
Funciones en phpFunciones en php
Funciones en php
 
Hechos en clase
Hechos en claseHechos en clase
Hechos en clase
 
3152
31523152
3152
 
Ejercicios con Python parte 05
Ejercicios con Python parte 05Ejercicios con Python parte 05
Ejercicios con Python parte 05
 
Las funciones en JavaScript para la programación orientada a objetos
Las funciones en JavaScript para la programación orientada a objetosLas funciones en JavaScript para la programación orientada a objetos
Las funciones en JavaScript para la programación orientada a objetos
 
Arreglos en C++
Arreglos en C++Arreglos en C++
Arreglos en C++
 
1.2. kotlin (1)
1.2. kotlin (1)1.2. kotlin (1)
1.2. kotlin (1)
 
Package logica jo
Package logica joPackage logica jo
Package logica jo
 
Interpolaion c++
Interpolaion c++Interpolaion c++
Interpolaion c++
 
Ejercicios en Netbeans
Ejercicios en NetbeansEjercicios en Netbeans
Ejercicios en Netbeans
 
Curso Drupal. Creacion de modulos en Drupal
Curso Drupal. Creacion de modulos en DrupalCurso Drupal. Creacion de modulos en Drupal
Curso Drupal. Creacion de modulos en Drupal
 
7
77
7
 
05. Creando e implementando objetos y métodos
05. Creando e implementando objetos y métodos05. Creando e implementando objetos y métodos
05. Creando e implementando objetos y métodos
 
Ejercicios Python parte 4
Ejercicios Python parte 4Ejercicios Python parte 4
Ejercicios Python parte 4
 
Funcionesenlenguaje c
Funcionesenlenguaje cFuncionesenlenguaje c
Funcionesenlenguaje c
 
Twig, el nuevo motor de plantillas de Drupal 8
Twig, el nuevo motor de plantillas de Drupal 8Twig, el nuevo motor de plantillas de Drupal 8
Twig, el nuevo motor de plantillas de Drupal 8
 
Guia para examen java
Guia para examen javaGuia para examen java
Guia para examen java
 

Destacado

Siete problemas que ya han resuelto los ecommerce de referencia
Siete problemas que ya han resuelto los ecommerce de referenciaSiete problemas que ya han resuelto los ecommerce de referencia
Siete problemas que ya han resuelto los ecommerce de referenciaSemmantica
 
Cómo configurar el seo de tu drupal
Cómo configurar el seo de tu drupal  Cómo configurar el seo de tu drupal
Cómo configurar el seo de tu drupal Hiberus Tecnologia
 
Inciación a Drupal 8
Inciación a Drupal 8Inciación a Drupal 8
Inciación a Drupal 8Julian Valero
 
Taller SEO para Prestashop Congreso Web 16
Taller SEO para Prestashop Congreso Web 16Taller SEO para Prestashop Congreso Web 16
Taller SEO para Prestashop Congreso Web 16Victor Berroya
 
¿Cómo diseñar una estrategia SEO?
¿Cómo diseñar una estrategia SEO?¿Cómo diseñar una estrategia SEO?
¿Cómo diseñar una estrategia SEO?Lakil Essady
 
Taller Email Marketing por Javier Mayor en CW16
Taller Email Marketing por Javier Mayor en CW16Taller Email Marketing por Javier Mayor en CW16
Taller Email Marketing por Javier Mayor en CW16Hiberus Tecnologia
 
"Hackeando el algoritmo: innovación en redes sociales". Presentación del #CW16
"Hackeando el algoritmo: innovación en redes sociales". Presentación del #CW16"Hackeando el algoritmo: innovación en redes sociales". Presentación del #CW16
"Hackeando el algoritmo: innovación en redes sociales". Presentación del #CW16Inma Ferragud
 
Redes sociales profesionales: estrategias para pymes y negocios B2B
Redes sociales profesionales: estrategias para pymes y negocios B2BRedes sociales profesionales: estrategias para pymes y negocios B2B
Redes sociales profesionales: estrategias para pymes y negocios B2BMaría Lázaro
 
Aprende a medir tu ecommerce con GTM
Aprende a medir tu ecommerce con GTMAprende a medir tu ecommerce con GTM
Aprende a medir tu ecommerce con GTMCarlos Rabadán
 
Piratas, Corsarios y Bucaneros SEO ¿con quién compites por el TOP10 de Google?
Piratas, Corsarios y Bucaneros SEO ¿con quién compites por el TOP10 de Google?Piratas, Corsarios y Bucaneros SEO ¿con quién compites por el TOP10 de Google?
Piratas, Corsarios y Bucaneros SEO ¿con quién compites por el TOP10 de Google?MOV Marketing
 
SEO para E-COMMERCE por Natzir y Dani Pinillos
SEO para E-COMMERCE por Natzir y Dani PinillosSEO para E-COMMERCE por Natzir y Dani Pinillos
SEO para E-COMMERCE por Natzir y Dani PinillosNatzir Turrado
 
Wordpress para Bloggers: De cero a héroe
Wordpress para Bloggers: De cero a héroeWordpress para Bloggers: De cero a héroe
Wordpress para Bloggers: De cero a héroemisstechin
 
CW15-Charla-Clausura-CalvoConBarba
CW15-Charla-Clausura-CalvoConBarbaCW15-Charla-Clausura-CalvoConBarba
CW15-Charla-Clausura-CalvoConBarbaLucas Aisa
 
Lisandro Caravaca en Congreso Web Zaragoza 2015
Lisandro Caravaca en Congreso Web Zaragoza 2015Lisandro Caravaca en Congreso Web Zaragoza 2015
Lisandro Caravaca en Congreso Web Zaragoza 2015Lisandro Caravaca
 
CRM y Big Data: el nuevo cliente vitaminado
CRM y Big Data: el nuevo cliente vitaminadoCRM y Big Data: el nuevo cliente vitaminado
CRM y Big Data: el nuevo cliente vitaminadoAndres Karp
 
El Futuro del SEO y cómo llegar a él en el presente
El Futuro del SEO y cómo llegar a él en el presenteEl Futuro del SEO y cómo llegar a él en el presente
El Futuro del SEO y cómo llegar a él en el presenteFernando Angulo
 
Encuentra contenidos como un PRO. Congreso Web 2015 #CW15
Encuentra contenidos como un PRO. Congreso Web 2015 #CW15Encuentra contenidos como un PRO. Congreso Web 2015 #CW15
Encuentra contenidos como un PRO. Congreso Web 2015 #CW15Javier Leiva Aguilera
 
7 implementaciones avanzadas de Google Analytics que no aprovechas en tu nego...
7 implementaciones avanzadas de Google Analytics que no aprovechas en tu nego...7 implementaciones avanzadas de Google Analytics que no aprovechas en tu nego...
7 implementaciones avanzadas de Google Analytics que no aprovechas en tu nego...Semmantica
 

Destacado (20)

Siete problemas que ya han resuelto los ecommerce de referencia
Siete problemas que ya han resuelto los ecommerce de referenciaSiete problemas que ya han resuelto los ecommerce de referencia
Siete problemas que ya han resuelto los ecommerce de referencia
 
Cómo configurar el seo de tu drupal
Cómo configurar el seo de tu drupal  Cómo configurar el seo de tu drupal
Cómo configurar el seo de tu drupal
 
Inciación a Drupal 8
Inciación a Drupal 8Inciación a Drupal 8
Inciación a Drupal 8
 
Marketing con video #cw16
Marketing con video #cw16Marketing con video #cw16
Marketing con video #cw16
 
Taller SEO para Prestashop Congreso Web 16
Taller SEO para Prestashop Congreso Web 16Taller SEO para Prestashop Congreso Web 16
Taller SEO para Prestashop Congreso Web 16
 
¿Cómo diseñar una estrategia SEO?
¿Cómo diseñar una estrategia SEO?¿Cómo diseñar una estrategia SEO?
¿Cómo diseñar una estrategia SEO?
 
Taller Email Marketing por Javier Mayor en CW16
Taller Email Marketing por Javier Mayor en CW16Taller Email Marketing por Javier Mayor en CW16
Taller Email Marketing por Javier Mayor en CW16
 
"Hackeando el algoritmo: innovación en redes sociales". Presentación del #CW16
"Hackeando el algoritmo: innovación en redes sociales". Presentación del #CW16"Hackeando el algoritmo: innovación en redes sociales". Presentación del #CW16
"Hackeando el algoritmo: innovación en redes sociales". Presentación del #CW16
 
Redes sociales profesionales: estrategias para pymes y negocios B2B
Redes sociales profesionales: estrategias para pymes y negocios B2BRedes sociales profesionales: estrategias para pymes y negocios B2B
Redes sociales profesionales: estrategias para pymes y negocios B2B
 
Aprende a medir tu ecommerce con GTM
Aprende a medir tu ecommerce con GTMAprende a medir tu ecommerce con GTM
Aprende a medir tu ecommerce con GTM
 
Piratas, Corsarios y Bucaneros SEO ¿con quién compites por el TOP10 de Google?
Piratas, Corsarios y Bucaneros SEO ¿con quién compites por el TOP10 de Google?Piratas, Corsarios y Bucaneros SEO ¿con quién compites por el TOP10 de Google?
Piratas, Corsarios y Bucaneros SEO ¿con quién compites por el TOP10 de Google?
 
SEO para E-COMMERCE por Natzir y Dani Pinillos
SEO para E-COMMERCE por Natzir y Dani PinillosSEO para E-COMMERCE por Natzir y Dani Pinillos
SEO para E-COMMERCE por Natzir y Dani Pinillos
 
Seo basado en Analítica web
Seo basado en Analítica webSeo basado en Analítica web
Seo basado en Analítica web
 
Wordpress para Bloggers: De cero a héroe
Wordpress para Bloggers: De cero a héroeWordpress para Bloggers: De cero a héroe
Wordpress para Bloggers: De cero a héroe
 
CW15-Charla-Clausura-CalvoConBarba
CW15-Charla-Clausura-CalvoConBarbaCW15-Charla-Clausura-CalvoConBarba
CW15-Charla-Clausura-CalvoConBarba
 
Lisandro Caravaca en Congreso Web Zaragoza 2015
Lisandro Caravaca en Congreso Web Zaragoza 2015Lisandro Caravaca en Congreso Web Zaragoza 2015
Lisandro Caravaca en Congreso Web Zaragoza 2015
 
CRM y Big Data: el nuevo cliente vitaminado
CRM y Big Data: el nuevo cliente vitaminadoCRM y Big Data: el nuevo cliente vitaminado
CRM y Big Data: el nuevo cliente vitaminado
 
El Futuro del SEO y cómo llegar a él en el presente
El Futuro del SEO y cómo llegar a él en el presenteEl Futuro del SEO y cómo llegar a él en el presente
El Futuro del SEO y cómo llegar a él en el presente
 
Encuentra contenidos como un PRO. Congreso Web 2015 #CW15
Encuentra contenidos como un PRO. Congreso Web 2015 #CW15Encuentra contenidos como un PRO. Congreso Web 2015 #CW15
Encuentra contenidos como un PRO. Congreso Web 2015 #CW15
 
7 implementaciones avanzadas de Google Analytics que no aprovechas en tu nego...
7 implementaciones avanzadas de Google Analytics que no aprovechas en tu nego...7 implementaciones avanzadas de Google Analytics que no aprovechas en tu nego...
7 implementaciones avanzadas de Google Analytics que no aprovechas en tu nego...
 

Similar a Charla congreso web introducción programación funcional en JavaScript

Similar a Charla congreso web introducción programación funcional en JavaScript (20)

11 Funciones
11 Funciones11 Funciones
11 Funciones
 
Capítulo 6 funciones y procedimiento
Capítulo 6 funciones y procedimientoCapítulo 6 funciones y procedimiento
Capítulo 6 funciones y procedimiento
 
Funciones en C
Funciones en CFunciones en C
Funciones en C
 
FUNCIONES LENGUAJE C
FUNCIONES LENGUAJE CFUNCIONES LENGUAJE C
FUNCIONES LENGUAJE C
 
07 funciones
07 funciones07 funciones
07 funciones
 
Módulo 4 (sin estilo)
Módulo 4 (sin estilo)Módulo 4 (sin estilo)
Módulo 4 (sin estilo)
 
C ++
C ++C ++
C ++
 
El lenguaje C++ (1).ppt
El lenguaje C++ (1).pptEl lenguaje C++ (1).ppt
El lenguaje C++ (1).ppt
 
El lenguaje C++.ppt
El lenguaje C++.pptEl lenguaje C++.ppt
El lenguaje C++.ppt
 
Módulo 4
Módulo 4Módulo 4
Módulo 4
 
Módulo 4
Módulo 4Módulo 4
Módulo 4
 
Funciones en Lenguaje C
Funciones en Lenguaje CFunciones en Lenguaje C
Funciones en Lenguaje C
 
C# calculadora
C# calculadoraC# calculadora
C# calculadora
 
Unidad2
Unidad2Unidad2
Unidad2
 
Operaciones Básicas
Operaciones BásicasOperaciones Básicas
Operaciones Básicas
 
Lenguaje de programacion C++ 2
Lenguaje de programacion C++ 2Lenguaje de programacion C++ 2
Lenguaje de programacion C++ 2
 
Lenguajesdeprogramacion c nivel1-unidad2
Lenguajesdeprogramacion c nivel1-unidad2Lenguajesdeprogramacion c nivel1-unidad2
Lenguajesdeprogramacion c nivel1-unidad2
 
Operaciones Basicas C++
Operaciones Basicas C++Operaciones Basicas C++
Operaciones Basicas C++
 
Lenguajesdeprogramacion c nivel1-unidad2
Lenguajesdeprogramacion c nivel1-unidad2Lenguajesdeprogramacion c nivel1-unidad2
Lenguajesdeprogramacion c nivel1-unidad2
 
Lenguajes De Programacion C nivel1-unidad2
Lenguajes De Programacion C nivel1-unidad2Lenguajes De Programacion C nivel1-unidad2
Lenguajes De Programacion C nivel1-unidad2
 

Último

Reporte de simulación de flujo del agua en un volumen de control MNVA.pdf
Reporte de simulación de flujo del agua en un volumen de control MNVA.pdfReporte de simulación de flujo del agua en un volumen de control MNVA.pdf
Reporte de simulación de flujo del agua en un volumen de control MNVA.pdfMikkaelNicolae
 
sigof.sisfoh.gob.pe_consulta_hogares_ULE_busqueda_print.php (1).pptx
sigof.sisfoh.gob.pe_consulta_hogares_ULE_busqueda_print.php (1).pptxsigof.sisfoh.gob.pe_consulta_hogares_ULE_busqueda_print.php (1).pptx
sigof.sisfoh.gob.pe_consulta_hogares_ULE_busqueda_print.php (1).pptxsutti0808
 
CLASe número 4 fotogrametria Y PARALAJE.pptx
CLASe número 4 fotogrametria Y PARALAJE.pptxCLASe número 4 fotogrametria Y PARALAJE.pptx
CLASe número 4 fotogrametria Y PARALAJE.pptxbingoscarlet
 
Practica PLC MIcrologix 1400 con pantalla HMI y servomotor
Practica PLC MIcrologix 1400 con pantalla HMI y servomotorPractica PLC MIcrologix 1400 con pantalla HMI y servomotor
Practica PLC MIcrologix 1400 con pantalla HMI y servomotorkavowog624
 
clasificasion de vias arteriales , vias locales
clasificasion de vias arteriales , vias localesclasificasion de vias arteriales , vias locales
clasificasion de vias arteriales , vias localesMIGUELANGEL2658
 
MODIFICADO - CAPITULO II DISEÑO SISMORRESISTENTE DE VIGAS Y COLUMNAS.pdf
MODIFICADO - CAPITULO II DISEÑO SISMORRESISTENTE DE VIGAS Y COLUMNAS.pdfMODIFICADO - CAPITULO II DISEÑO SISMORRESISTENTE DE VIGAS Y COLUMNAS.pdf
MODIFICADO - CAPITULO II DISEÑO SISMORRESISTENTE DE VIGAS Y COLUMNAS.pdfvladimirpaucarmontes
 
Controladores Lógicos Programables Usos y Ventajas
Controladores Lógicos Programables Usos y VentajasControladores Lógicos Programables Usos y Ventajas
Controladores Lógicos Programables Usos y Ventajasjuanprv
 
4º Clase Laboratorio (2024) Completo Mezclas Asfalticas Caliente (1).pdf
4º Clase Laboratorio (2024) Completo Mezclas Asfalticas Caliente (1).pdf4º Clase Laboratorio (2024) Completo Mezclas Asfalticas Caliente (1).pdf
4º Clase Laboratorio (2024) Completo Mezclas Asfalticas Caliente (1).pdfnicolascastaneda8
 
Maquinaria Agricola utilizada en la produccion de Piña.pdf
Maquinaria Agricola utilizada en la produccion de Piña.pdfMaquinaria Agricola utilizada en la produccion de Piña.pdf
Maquinaria Agricola utilizada en la produccion de Piña.pdfdanielJAlejosC
 
Propuesta para la creación de un Centro de Innovación para la Refundación ...
Propuesta para la creación de un Centro de Innovación para la Refundación ...Propuesta para la creación de un Centro de Innovación para la Refundación ...
Propuesta para la creación de un Centro de Innovación para la Refundación ...Dr. Edwin Hernandez
 
01 MATERIALES AERONAUTICOS VARIOS clase 1.ppt
01 MATERIALES AERONAUTICOS VARIOS clase 1.ppt01 MATERIALES AERONAUTICOS VARIOS clase 1.ppt
01 MATERIALES AERONAUTICOS VARIOS clase 1.pptoscarvielma45
 
Ejemplos de cadenas de Markov - Ejercicios
Ejemplos de cadenas de Markov - EjerciciosEjemplos de cadenas de Markov - Ejercicios
Ejemplos de cadenas de Markov - EjerciciosMARGARITAMARIAFERNAN1
 
Ejemplos aplicados de flip flops para la ingenieria
Ejemplos aplicados de flip flops para la ingenieriaEjemplos aplicados de flip flops para la ingenieria
Ejemplos aplicados de flip flops para la ingenieriaAndreBarrientos3
 
ANALISIS Y DISEÑO POR VIENTO, DE EDIFICIOS ALTOS, SEGUN ASCE-2016, LAURA RAMIREZ
ANALISIS Y DISEÑO POR VIENTO, DE EDIFICIOS ALTOS, SEGUN ASCE-2016, LAURA RAMIREZANALISIS Y DISEÑO POR VIENTO, DE EDIFICIOS ALTOS, SEGUN ASCE-2016, LAURA RAMIREZ
ANALISIS Y DISEÑO POR VIENTO, DE EDIFICIOS ALTOS, SEGUN ASCE-2016, LAURA RAMIREZgustavoiashalom
 
CALCULO DE ENGRANAJES RECTOS SB-2024.pptx
CALCULO DE ENGRANAJES RECTOS SB-2024.pptxCALCULO DE ENGRANAJES RECTOS SB-2024.pptx
CALCULO DE ENGRANAJES RECTOS SB-2024.pptxCarlosGabriel96
 
TIPOS DE SOPORTES - CLASIFICACION IG.pdf
TIPOS DE SOPORTES - CLASIFICACION IG.pdfTIPOS DE SOPORTES - CLASIFICACION IG.pdf
TIPOS DE SOPORTES - CLASIFICACION IG.pdfssuser202b79
 
introducción a las comunicaciones satelitales
introducción a las comunicaciones satelitalesintroducción a las comunicaciones satelitales
introducción a las comunicaciones satelitalesgovovo2388
 
nomenclatura de equipo electrico en subestaciones
nomenclatura de equipo electrico en subestacionesnomenclatura de equipo electrico en subestaciones
nomenclatura de equipo electrico en subestacionesCarlosMeraz16
 
PERFORACIÓN Y VOLADURA EN MINERÍA APLICADO
PERFORACIÓN Y VOLADURA EN MINERÍA APLICADOPERFORACIÓN Y VOLADURA EN MINERÍA APLICADO
PERFORACIÓN Y VOLADURA EN MINERÍA APLICADOFritz Rebaza Latoche
 
libro de ingeniería de petróleos y operaciones
libro de ingeniería de petróleos y operacioneslibro de ingeniería de petróleos y operaciones
libro de ingeniería de petróleos y operacionesRamon Bartolozzi
 

Último (20)

Reporte de simulación de flujo del agua en un volumen de control MNVA.pdf
Reporte de simulación de flujo del agua en un volumen de control MNVA.pdfReporte de simulación de flujo del agua en un volumen de control MNVA.pdf
Reporte de simulación de flujo del agua en un volumen de control MNVA.pdf
 
sigof.sisfoh.gob.pe_consulta_hogares_ULE_busqueda_print.php (1).pptx
sigof.sisfoh.gob.pe_consulta_hogares_ULE_busqueda_print.php (1).pptxsigof.sisfoh.gob.pe_consulta_hogares_ULE_busqueda_print.php (1).pptx
sigof.sisfoh.gob.pe_consulta_hogares_ULE_busqueda_print.php (1).pptx
 
CLASe número 4 fotogrametria Y PARALAJE.pptx
CLASe número 4 fotogrametria Y PARALAJE.pptxCLASe número 4 fotogrametria Y PARALAJE.pptx
CLASe número 4 fotogrametria Y PARALAJE.pptx
 
Practica PLC MIcrologix 1400 con pantalla HMI y servomotor
Practica PLC MIcrologix 1400 con pantalla HMI y servomotorPractica PLC MIcrologix 1400 con pantalla HMI y servomotor
Practica PLC MIcrologix 1400 con pantalla HMI y servomotor
 
clasificasion de vias arteriales , vias locales
clasificasion de vias arteriales , vias localesclasificasion de vias arteriales , vias locales
clasificasion de vias arteriales , vias locales
 
MODIFICADO - CAPITULO II DISEÑO SISMORRESISTENTE DE VIGAS Y COLUMNAS.pdf
MODIFICADO - CAPITULO II DISEÑO SISMORRESISTENTE DE VIGAS Y COLUMNAS.pdfMODIFICADO - CAPITULO II DISEÑO SISMORRESISTENTE DE VIGAS Y COLUMNAS.pdf
MODIFICADO - CAPITULO II DISEÑO SISMORRESISTENTE DE VIGAS Y COLUMNAS.pdf
 
Controladores Lógicos Programables Usos y Ventajas
Controladores Lógicos Programables Usos y VentajasControladores Lógicos Programables Usos y Ventajas
Controladores Lógicos Programables Usos y Ventajas
 
4º Clase Laboratorio (2024) Completo Mezclas Asfalticas Caliente (1).pdf
4º Clase Laboratorio (2024) Completo Mezclas Asfalticas Caliente (1).pdf4º Clase Laboratorio (2024) Completo Mezclas Asfalticas Caliente (1).pdf
4º Clase Laboratorio (2024) Completo Mezclas Asfalticas Caliente (1).pdf
 
Maquinaria Agricola utilizada en la produccion de Piña.pdf
Maquinaria Agricola utilizada en la produccion de Piña.pdfMaquinaria Agricola utilizada en la produccion de Piña.pdf
Maquinaria Agricola utilizada en la produccion de Piña.pdf
 
Propuesta para la creación de un Centro de Innovación para la Refundación ...
Propuesta para la creación de un Centro de Innovación para la Refundación ...Propuesta para la creación de un Centro de Innovación para la Refundación ...
Propuesta para la creación de un Centro de Innovación para la Refundación ...
 
01 MATERIALES AERONAUTICOS VARIOS clase 1.ppt
01 MATERIALES AERONAUTICOS VARIOS clase 1.ppt01 MATERIALES AERONAUTICOS VARIOS clase 1.ppt
01 MATERIALES AERONAUTICOS VARIOS clase 1.ppt
 
Ejemplos de cadenas de Markov - Ejercicios
Ejemplos de cadenas de Markov - EjerciciosEjemplos de cadenas de Markov - Ejercicios
Ejemplos de cadenas de Markov - Ejercicios
 
Ejemplos aplicados de flip flops para la ingenieria
Ejemplos aplicados de flip flops para la ingenieriaEjemplos aplicados de flip flops para la ingenieria
Ejemplos aplicados de flip flops para la ingenieria
 
ANALISIS Y DISEÑO POR VIENTO, DE EDIFICIOS ALTOS, SEGUN ASCE-2016, LAURA RAMIREZ
ANALISIS Y DISEÑO POR VIENTO, DE EDIFICIOS ALTOS, SEGUN ASCE-2016, LAURA RAMIREZANALISIS Y DISEÑO POR VIENTO, DE EDIFICIOS ALTOS, SEGUN ASCE-2016, LAURA RAMIREZ
ANALISIS Y DISEÑO POR VIENTO, DE EDIFICIOS ALTOS, SEGUN ASCE-2016, LAURA RAMIREZ
 
CALCULO DE ENGRANAJES RECTOS SB-2024.pptx
CALCULO DE ENGRANAJES RECTOS SB-2024.pptxCALCULO DE ENGRANAJES RECTOS SB-2024.pptx
CALCULO DE ENGRANAJES RECTOS SB-2024.pptx
 
TIPOS DE SOPORTES - CLASIFICACION IG.pdf
TIPOS DE SOPORTES - CLASIFICACION IG.pdfTIPOS DE SOPORTES - CLASIFICACION IG.pdf
TIPOS DE SOPORTES - CLASIFICACION IG.pdf
 
introducción a las comunicaciones satelitales
introducción a las comunicaciones satelitalesintroducción a las comunicaciones satelitales
introducción a las comunicaciones satelitales
 
nomenclatura de equipo electrico en subestaciones
nomenclatura de equipo electrico en subestacionesnomenclatura de equipo electrico en subestaciones
nomenclatura de equipo electrico en subestaciones
 
PERFORACIÓN Y VOLADURA EN MINERÍA APLICADO
PERFORACIÓN Y VOLADURA EN MINERÍA APLICADOPERFORACIÓN Y VOLADURA EN MINERÍA APLICADO
PERFORACIÓN Y VOLADURA EN MINERÍA APLICADO
 
libro de ingeniería de petróleos y operaciones
libro de ingeniería de petróleos y operacioneslibro de ingeniería de petróleos y operaciones
libro de ingeniería de petróleos y operaciones
 

Charla congreso web introducción programación funcional en JavaScript

  • 1. Introducción a la programación funcional en JavaScript
  • 3. Índice 1. Introducción (primeros ejercicios y conceptos) 2. Trabajando con arrays sin bucles 3. Teoría de Categorías 4. Ejercicio final (App web vídeos: React + FP) 5. Conclusiones
  • 6. ‘’ La programación funcional es un paradigma de programación que se basa en el uso de funciones modeladas como funciones matemáticas. La esencia es que los programas son la combinación de expresiones. Una expresión puede ser un valor concreto, variables y también funciones.
  • 8. ‘’ Una función es una relación entre un conjunto de posibles entradas y un conjunto de posibles salidas. La función en sí misma, representa la relación.
  • 9. Gaviotas Unir: unir dos bandadas de gaviotas en una sola Engendrar: la bandada se multiplica por el número de gaviotas que engendra cada una
  • 10. var Bandada = function(n) { this.gaviotas = n } Bandada.prototype.unir = function(otra) { this.gaviotas += otra.gaviotas; return this; } Bandada.prototype.engendrar = function(otra) { this.gaviotas = this.gaviotas * otra.gaviotas; return this; } var bandada1 = new Bandada(4); var bandada2 = new Bandada(2); var bandada3 = new Bandada(0); var resultado = bandada1.unir(bandada3) .engendrar(bandada2).unir(bandada1.engendrar(bandada2)).gaviotas; //=> 32
  • 11. var unir = function(bandada_x, bandada_y) { return bandada_x + bandada_y; }; var engendrar = function(bandada_x, bandada_y) { return bandada_x * bandada_y; }; var bandada_a = 4; var bandada_b = 2; var bandada_c = 0; var result = unir( engendrar(bandada_b, unir(bandada_a, bandada_c)), engendrar(bandada_a, bandada_b) ); //=>16
  • 12. var sumar = function(x, y) { return x + y; }; var multiplicar = function(x, y) { return x * y; }; var bandada_a = 4; var bandada_b = 2; var bandada_c = 0; var result = sumar( multiplicar(bandada_b, sumar(bandada_a, bandada_c)), multiplicar(bandada_a, bandada_b) ); //=>16
  • 13. // associative sumar(sumar(x, y), z) === sumar(x, sumar(y, z)); // commutative sumar(x, y) === sumar(y, x); // identity sumar(x, 0) === x; // distributive multiplicar(x, sumar(y,z)) === sumar(multiplicar(x, y), multiplicar(x, z));
  • 14. Funciones puras Una función pura es una función que, dada la misma entrada, siempre devuelve la misma salida y no tiene ningún efecto colateral.
  • 15. ¿Qué es la programación funcional, otra vez? En gran medida, programas con funciones puras: funciones que reciben valores de entrada, devuelve valores de salida, y no hacen de más.
  • 16. El problema: los efectos colaterales
  • 17. Una función pura: libre de efectos colaterales function add(x,y) { return x + y; }
  • 18. Una función impura: corrupta (no declara todo lo que hace realmente) function add(x,y) { var z = x + y; console.log('result of the sum: ', z); return z; }
  • 19. // pure xs.slice(0,3) //=> [1,2,3] xs.slice(0,3) //=> [1,2,3] xs.slice(0,3) //=> [1,2,3] // impure xs.splice(0,3) //=> [1,2,3] xs.splice(0,3) //=> [4,5] xs.splice(0,3) //=> [] var xs = [1,2,3,4,5]
  • 20. // impure var minimum = 21; var checkAge = function(age) { return age >= minimum; } // pure var checkAge = function(age) { var minimum = 21; return age >= minimum; }
  • 21. // impure var greeting = function(name) { console.log("hi, " + name + "!") } // pure var greeting = function(name) { return "hi, " + name + "!"; } console.log(greeting("Jonas"))
  • 22. ‘’ Una función es una relación entre un conjunto de posibles entradas y un conjunto de posibles salidas. La función en sí misma, representa la relación. Recordatorio
  • 23. Una entrada, una salida ... (-2, -1) (0 , 0 ) (2 , 1 ) (4 , 2 ) (8 , 4 ) ... Dominio Rango … -2 0 2 4 8 ... … -1 0 1 2 4 ...
  • 24. Una entrada, una salida var toLowerCase = {"A":"a", "B": "b", "C": "c", "D": "d", "E": "e", "D": "d"} toLowerCase["C"] //=> "c" var isPrime = {1: false, 2: true, 3: true, 4: false, 5: true, 6: false} isPrime[3] //=> true
  • 25. ¿Y si hay múltiples argumentos? //+ add :: [Number, Number] -> Number var add = function(numbers) { return numbers[0] + numbers[1] }
  • 26. ¿Y si hay múltiples argumentos? //+ add :: ? -> Number var add = function() { return arguments[0] + arguments[1] }
  • 27. ‘’ Función “curried”: “Una función que devuelve una nueva función hasta que recibe todos sus argumentos” Currying
  • 28. Currying //+ add :: Number -> Number -> Number var add = curry(function(x, y) { return x + y })
  • 29. Currying add //=> function(x,y) { return x + y } add(2,3) //=> 5 add(2) //=> function(y) { return 2 + y }
  • 30. Currying //+ get :: String -> {String: a} -> a var get = curry(function(prop, obj) { return obj[prop]; }) var user = {id: 15, name: "Jorge Aznar", email: "jaznar@email.com"} get('email', user) //=> jaznar@email.com //+ email :: {String: a} -> a var email = get('email') //=> function(obj){ return obj[‘email’] } email(user) //=> jaznar@email.com
  • 31. Currying //+ filter :: (a -> Bool) -> [a] -> [a] var filter = curry(function(f, xs) { return xs.filter(f); }) //+ odds :: [a] -> [a] var odds = filter(isOdd) odds([1,2,3]) //=> [1, 3]
  • 32. Currying var emails = map(email) var users = [jesus, jorge, ja, jbalbas] emails(users) //=> ["jesus@lopez.org", "jorge@aznar.net", "ja@samitier.com", "jota@balbas.es"]
  • 33. Currying //+ goodArticles :: [Article] -> [Article] var goodArticles = function(articles) { return _.filter(articles, function(article){ return _.isDefined(article) }) } //+ goodArticles :: [Article] -> [Article] var goodArticles = filter(isDefined)
  • 34. Currying //+ getChildren :: DOM -> [DOM] var getChildren = function(el) { return el.childNodes } //+ getALLChildren :: [DOM] -> [[DOM]] var getAllChildren = function(els) { return _.map(els, function(el) { return getChildren(el) }) } var getChildren = get('childNodes') var getAllChildren = map(getChildren)
  • 35. Composición La composición de funciones es aplicar una función a los resultados de otra
  • 36. Composición //+ compose :: (b -> c) -> (a -> b) -> a -> c var compose = curry(function(f, g, x) { return f(g(x)) })
  • 37. Composición //+ head :: [a] -> a var head = function(x) { return x[0] } //+ last :: [a] -> a var last = compose(head, reverse) last(['Java', 'JavaScript', 'PHP']) //=> PHP
  • 38. Composición //+ wordCount :: String -> Number var wordCount = function(sentence) { var count = split(' ', sentence) return length(count) } //+ wordCount :: String -> Number var wordCount = compose(length, split(' ')) wordCount("Soy una frase de 6 palabras") //=> 6
  • 39. Composición 'B' <- 'b' <- 'Congreso Web' compose(toUpperCase, last)('Congreso Web')
  • 40. Composición // Ley asociativa compose(f, compose(g, h)) == compose(compose(f, g), h)
  • 41. Composición compose(toUpperCase, compose(head, reverse)) // ó compose(compose(toUpperCase, head), reverse)
  • 42. Composición //+ lastUpper :: [String] -> String var lastUpper = compose(toUpperCase, head, reverse) lastUpper(['Java', 'PHP', 'JavaScript']) //=> 'JAVASCRIPT' //+ lastUpper :: [String] -> String var loudLastUpper = compose(exclaim, toUpperCase, head, reverse) loudLastUpper(['Java', 'PHP', 'JAVASCRIPT']) //=> 'JAVASCRIPT!'
  • 43. Composición ? <- map(['JavaScript', 'Rust']) <- ['JavaScript', 'Rust'] <- ['Rust', 'JavaScript'] compose(toUpperCase, map, reverse)(['Rust', 'JavaScript'])
  • 44. Composición ['JAVASCRIPT', 'RUST'] <- ['JavaScript', 'Rust'] <- ['Rust', 'JavaScript'] compose(map(toUpperCase), reverse)(['Rust', 'JavaScript'])
  • 46. Inciso: Trabajar con colecciones (sin bucles) La mayoría de las operaciones que hacemos se pueden conseguir con 5 funciones: ▣ map ▣ filter ▣ reduce ▣ concatAll ▣ zip Prácticamente, todos los bucles se pueden sustituir por estas funciones.
  • 47. Ejercicios Vamos a practicar el uso de las 5 funciones https://github.com/RPallas92/congreso-web-2016 Directorio parte2
  • 49. Teoría de Categorías Es una rama abstracta de las matemáticas que formaliza conceptos de diferentes ramas como teoría de conjuntos, teoría de tipos, teoría de grupos, lógica y más. Principalmente, se trabaja con objetos, morfismos y transformaciones. (Similitud con la programación)
  • 50. Categoría Es una colección con los siguientes componentes: ▣ Una colección de objetos ▣ Una colección de morfismos ▣ Una noción de composición de los morfismos ▣ Un morfismo en concreto, llamado identidad
  • 51. Categoría ▣ La Teoría de Categorías es suficientemente abstracta para modelar muchas cosas, pero vamos a centrarnos en tipos y funciones
  • 52. Categoría Una colección de objetos: ▣ Los objetos serán tipos de datos. String, Boolean, Number, Object. ▣ Boolean como el conjunto [true, false] ▣ Number como el conjunto de todos los posibles valores numéricos
  • 53. Categoría Una colección de morfismos: ▣ Los morfismos serán las funciones normales que escribimos diariamente.
  • 54. Categoría Una noción de composición de los morfismos: ▣ Nuestra función compose, presentada anteriormente ▣ Que compose cumpla la ley asociativa no es casualidad. ▣ Cualquier composición en la Teoría de Categorías debe cumplirla
  • 56. Categoría Un morfismo concreto llamado identidad: ▣ Nueva función id ▣ Recibe una entrada, y la devuelve, nada más var id = function(x) { return x; }; Almacena un valor, será utilizada más adelante
  • 57. Identidad // identity compose(id, f) == compose(f, id) == f; // true ▣ Esta propiedad se cumple para todas las funciones unarias. ▣ Es como la identidad en los números
  • 58. Identidad // identity compose(id, f) == compose(f, id) == f; // true ▣ Esta propiedad se cumple para todas las funciones unarias. ▣ Es como la identidad en los números
  • 60. Objetos ▣ Contenedores/Wrappers para valores ▣ No tienen métodos ▣ No tienen propiedades ▣ Seguramente, no crees los tuyos propios
  • 61. Objetos var Container = function(val) { this.val = val; } //+ Container :: a -> Container(a) Container.of = function(x) { return new Container(x); }; Container.of(3) //=> Container {val: 3}
  • 63. Objetos //+ map :: (a -> b) -> Container(a) -> Container(b) Container.prototype.map = function(f) { return Container.of(f(this.val)); } Container.of("flamethrower").map(function(s){ return capitalize(s) }) //=> Container(“Flamethrower”)
  • 64. Objetos //+ map :: (a -> b) -> Container(a) -> Container(b) Container.prototype.map = function(f) { return Container.of(f(this.val)); } Container.of("flamethrower").map(capitalize) //=> Container(“Flamethrower”)
  • 67. Objetos //+ map :: Functor F => (a -> b) -> F a -> F b var map = _.curry(function(f, obj) { return obj.map(f) }) Container.of(3).map(add(1)) // Container(4) map(add(1), Container.of(3)) // Container(4)
  • 69. ‘’ “Un objeto o estructura de datos que puede ser mapeada” ▣ Funciones: map FUNCTOR
  • 70. Aquellos problemáticos null //+ getElement :: String -> DOM var getElement = document.querySelector //+ getNameParts :: String -> [String] var getNameParts = compose(split(' '), getText, getElement) getNameParts('#full_name') //=> ['José', 'Luis', 'Bárcenas', 'Gutiérrez']
  • 71. Aquellos problemáticos null //+ getElement :: String -> DOM var getElement = document.querySelector //+ getNameParts :: String -> [String] var getNameParts = compose(split(' '), getText, getElement) getNameParts('#fullname') //=> BOOOOOOOOMM!!!!!!
  • 72. Maybe ▣ Captura un null check ▣ Es posible que el valor no esté ▣ A veces tienen dos subclases: Just/Nothing ▣ En otros lenguajes se llama Option
  • 73. Maybe //+ map :: (a -> b) -> Maybe(a) -> Maybe(b) var _Maybe.prototype.map = function(f) { return this.val ? Maybe.of(f(this.val)) : Maybe.of(null); } map(capitalize, Maybe.of("flamethrower")) //=> Maybe(“Flamethrower”)
  • 74. Maybe //+ map :: (a -> b) -> Maybe(a) -> Maybe(b) var _Maybe.prototype.map = function(f) { return this.val ? Maybe.of(f(this.val)) : Maybe.of(null); } map(capitalize, Maybe.of(null)) //=> Maybe(null)
  • 75. Maybe //+ firstMatch :: String -> String var firstMatch = compose(first, match(/java/g)) firstMatch("python") //=> BOOOM!!!
  • 76. Maybe //+ firstMatch :: String -> Maybe(String) var firstMatch = compose(map(first), Maybe.of, match(/java/g)) firstMatch("python") //=> Maybe(null)
  • 77. Maybe //+ firstMatch :: String -> Maybe(String) var firstMatch = compose(map(first), Maybe.of, match(/java/g)) firstMatch("javascript") //=> Maybe(“java”)
  • 78. Either ▣ Utilizado para manejo de excepciones pura ▣ Es como Maybe, pero con un mensaje de error embebido ▣ Tienen dos subclases: Left/Right ▣ Mapea la función sobre el Right, ignora el Left
  • 79. Either map(function(x) { return x + 1; }, Right.of(2)) //=> Right(3) map(function(x) { return x + 1; }, Left.of(‘some message’)) //=> Left(‘some message’)
  • 80. Either //+ determineAge :: User -> Either(String, Number) var determineAge = function(user){ return user.age ? Right.of(user.age) : Left.of("couldn’t get age"); } //+ yearOlder :: User -> Either(String, Number) var yearOlder = compose(map(add(1)), determineAge) yearOlder({age: 22}) //=> Right(23) var jordiHurtado = {age: null} yearOlder(jordiHurtado) //=> Left("couldn’t get age")
  • 81. IO ▣ Utilizado para lazy computation ▣ Utilizado para manejar los efectos colaterales ▣ Para ejectuar la operación, se debe llamar a runIO ▣ map añade la función a una lista de operaciones a ejecutar
  • 82. IO //+ email_io :: IO(String) var email_io = new IO(function(){ return $("#email").val() }) //+ msg_io :: IO(String) var msg_io = map(concat("Bienvenido "), email_io) msg_io.unsafePerformIO() //=> ”Bienvenido jbalbas@email.net”
  • 84. IO //+ getBgColor :: JSON -> Color var getBgColor = compose(get("background-color"), JSON.parse) //+ bgPref :: _ -> IO(Color) var bgPref = compose(map(getBgColor), Store.get("preferences")) //+ app :: _ -> IO(Color) var app = bgPref() //=> IO() app.unsafePerformIO() //=> #efefef
  • 85. IO //+ email_io :: _ -> IO(String) var email_io = new IO(function(){ return $("#email").val() } //+ getValue :: String -> IO(String) var getValue = function(sel){ return new IO(function(){ return $(sel).val() }); }
  • 86. Task / Future ▣ Se utiliza para operaciones asíncronas ▣ Representa un valor en el tiempo ▣ Para ejecutar la operación, se debe llamar a fork ▣ Fork recibe una función como valor ▣ Se llama a la función con el resultado del Task una vez que lo tiene
  • 87. Task / Future //+ makeHtml :: Post -> HTML var makeHtml = function(post){ return "<div>"+post.title+"</div>"}; //+ page_f :: Future(Html) var page_f = map(makeHtml, http.get('/posts/2')) page_f.fork( function(err) { throw(err) }, function(page){ $('#container').html(page) } )
  • 88. Pointed Functors ▣ Es un Functor con un método of ▣ Of :: a -> F a ▣ Permite poner valores en un contexto mínimo que retiene el valor (o contexto puro) ▣ También llamado pure
  • 89. Pointed Functors ▣ Es un Functor con un método of ▣ Of :: a -> F a ▣ Permite poner valores en un contexto mínimo que retiene el valor (o contexto puro) ▣ También llamado pure
  • 90. Pointed Functors Container.of(2) // Container(2) Maybe.of(reverse) // Maybe(reverse) Future.of(match(/dubstep/)) // Future(match(/dubstep/)) IO.of('hack') // IO(function(){ return 'hack'})
  • 91. Task / Future //+ lineCount :: String -> Number var lineCount = compose(length, split(/n/)) //+ fileLineCount :: String -> Future(Number) var fileLineCount = compose(map(lineCount), readFile) fileLineCount("mydoc.txt").fork(log, log) //=> 34
  • 92. Leyes de los functores // identity map(id) == id // composition compose(map(f), map(g)) == map(compose(f, g))
  • 93. Pregunta Haz una llamada a una api con una id, y obtén un post (puede existir o no)
  • 95. Mónadas ▣ Patrón de diseño utilizado para describir computaciones como series de pasos (o computaciones anidadas) ▣ Utilizadas para gestionar los efectos colaterales ▣ O para controlar la complejidad Funciones: ▣ join ▣ chain
  • 96. Mónadas ▣ join :: M M a -> M a ▣ chain :: (a -> M b) -> M a -> M b Una mónada es un Pointed Functor añadiendo los métodos join y chain
  • 98. Mónadas //+ getTrackingId :: Order -> Maybe(TrackingId) var getTrackingId = compose(Maybe.of, get("tracking_id")) //+ findOrder :: Number -> Maybe(Order) var findOrder = compose(Maybe.of, Api.findOrder) //+ getOrderTracking :: Number -> Maybe(Maybe(TrackingId)) var getOrderTracking = compose(map(getTrackingId), findOrder) //+ renderPage :: Number -> Maybe(Maybe(Html)) var renderPage = compose(map(map(renderTemplate)), getOrderTracking)
  • 99. Mónadas //+ getTrackingId :: Order -> Maybe(TrackingId) var getTrackingId = compose(Maybe.of, get("tracking_id")) //+ findOrder :: Number -> Maybe(Order) var findOrder = compose(Maybe.of, Api.findOrder) //+ getOrderTracking :: Number -> Maybe(TrackingId) var getOrderTracking = compose(join, map(getTrackingId), findOrder) //+ renderPage :: Number -> Maybe(Html) var renderPage = compose(map(renderTemplate), getOrderTracking)
  • 100. Mónadas //+ :: setSearchInput :: String -> IO(_) var setSearchInput = function(x) { return new IO(function() { ("#input").val(x); }) } //+ :: searchTerm :: IO(String) var searchTerm = new IO(function() { getParam("term", location.search) }) //+ :: initSearchForm :: IO(IO(_)) var initSearchForm = map(setSearchInput, searchTerm) initSearchForm.unsafePerformIO().unsafePerformIO();
  • 101. Mónadas //+ :: setSearchInput :: String -> IO(_) var setSearchInput = function(x) { return new IO(function() { ("#input").val(x); }) } //+ :: searchTerm :: IO(String) var searchTerm = new IO(function() { getParam("term", location.search) }) //+ :: initSearchForm :: IO(IO(_)) var initSearchForm = map(setSearchInput, searchTerm) join(initSearchForm).unsafePerformIO();
  • 102. Mónadas //+ sendToServer :: Params -> Future(Response) var sendToServer = httpGet('/upload') //+ uploadFromFile :: String -> Future(Response) var uploadFromFile = compose(join, map(sendToServer), readFile) uploadFromFile("/tmp/my_file.txt").fork(logErr, alertSuccess)
  • 103. Mónadas //+ sendToServer :: Params -> Future(Response) var sendToServer = httpGet('/upload') //+ uploadFromFile :: String -> Future(Response) var uploadFromFile = compose(join, map(sendToServer), join, map(readFile), askUser) uploadFromFile('what file?').fork(logErr, alertSuccess)
  • 104. Mónadas //+ chain :: (a -> M b) -> M a -> M b var chain = function(f) { return compose(join, map(f)) } // también llamado flatMap
  • 105. Mónadas //+ sendToServer :: Params -> Future(Response) var sendToServer = httpGet('/upload') //+ uploadFromFile :: String -> Future(Response) var uploadFromFile = compose(chain(sendToServer), chain(readFile), askUser) uploadFromFile('what file?').fork(logErr, alertSuccess)
  • 106. Functores aplicativos ▣ Ejecutar computaciones completas en un contexto ▣ Permite aplicar un functor a otro Funciones: ▣ ap ▣ liftA2 ▣ liftA3 ▣ lifA..N
  • 107. Functores aplicativos add(Container.of(2), Container.of(3)); //NaN var container_of_add_2 = map(add, Container.of(2)); // Container(add(2))
  • 108. Functores aplicativos map(add(1), Container(2)) //=> Container(3) add(Container.of(2), Container.of(3)); //NaN map(add, Container(2)) //=> Container(add(2))
  • 109. Functores aplicativos ▣ ap :: A (a -> b) -> A a -> A b ▣ Un functor aplicativo es un Pointed Functor con un método ap
  • 113. Functores aplicativos var loadPage = _.curry(function(products, reviews){ render(products.zip(reviews) }) Future.of(loadPage) .ap(Api.get('/products')) .ap(Api.get('/reviews'))
  • 114. Functores aplicativos var getVal = compose(Maybe, get('value'), document.querySelector) var save = _.curry(function(email, pass){ return User(email, pass) }) Maybe.of(save).ap(getVal('#email')).ap(getVal('#password')) //=> Maybe(user)
  • 115. Functores aplicativos var getVal = compose(Maybe, pluck('value'), document.querySelector) var save = _.curry(function(email, pass){ return User(email, pass) }) liftA2(save, getVal('#email'), getVal('#password')) //=> Maybe(user)
  • 118. Aplicación buscador de vídeos Youtube ▣ Vista: React ▣ Manipulación de datos: Ramda ▣ Maybe: folktale/data.maybe ▣ Either: folktale/data.either ▣ Task: folktale/data.task
  • 119. React ▣ Biblioteca para crear interfaces de usuario en JavaScript ▣ Simple ▣ Declarativa ▣ Modular: componentes reusables ▣ Utiliza la composición de los componentes para crear nuevos ▣ https://facebook.github.io/react
  • 120. Ramda ▣ Biblioteca para programación funcional práctica en JavaScript ▣ Similar a lodash o undescore ▣ Todas las funciones están curried ▣ Parámetros de las funciones ordenados para favorecer el curry ▣ Trabaja bien con implementaciones Mónadas, functores, etc. http://ramdajs.com
  • 121. Folktale ▣ Suite de bibliotecas para programación funcional genérica en JavaScript ▣ Utilizaremos su implementación de □ Maybe □ Either □ Task (Future) http://folktalejs.org
  • 122. App vídeos YouTube ▣ Permite buscar vídeos “al vuelo” ▣ Muestra los vídeos como un grid ▣ Al hacer clic sobre uno, se abre su página de YouTube
  • 124. App vídeos YouTube ▣ Permite buscar vídeos “al vuelo” ▣ Muestra los vídeos como un grid ▣ Al hacer clic sobre uno, se abre su página de YouTube
  • 126. Conclusiones ▣ Crear funciones pequeñas (Divide and conquer (and reuse)) ▣ Composición de esas funciones ▣ Utilizar funciones puras ▣ Tener aislada la parte impura del programa ▣ Estilo declarativo vs imperativo