Taller de Programación Funcional en JavaScript

44
Javier Vélez Reyes @javiervelezreye [email protected] Taller de Programación Funcional en JavaScript Enero 2016

Transcript of Taller de Programación Funcional en JavaScript

Page 1: Taller de Programación Funcional en JavaScript

JavierVélezReyes@javiervelezreye

[email protected]

TallerdeProgramaciónFuncionalenJavaScript

Enero2016

Page 2: Taller de Programación Funcional en JavaScript

@javiervelezreye2

PresentaciónTallerdeProgramaciónFuncionalenJavaScript

LicenciadoporlaUPMdesdeelaño2001ydoctoreninformá;caporlaUNEDdesdeelaño2009,Javierconjugasuslaborescomoprofesore inves;gador con la consultoría y la formación técnica paraempresa. Su línea de trabajo actual se centra en la innovación ydesarrollodetecnologíasparalaWeb.Ademásrealizaac;vidadesdeevangelización y divulgación en diversas comunidades IT y escoordinadordevariosgruposdeámbitolocalcomoNodeJSMadridoMadridJS.FormapartedelprogramaPolymerPolytechnicSpeakeryesmentordelcapítulodeMadriddeNodeSchool.

¿QuiénSoy?

[email protected]

@javiervelezreye

linkedin.com/in/javiervelezreyes

gplus.to/javiervelezreyes

jvelez77

javiervelezreyes

youtube.com/user/javiervelezreyes

Page 3: Taller de Programación Funcional en JavaScript

JavierVélezReyes@javiervelezreye

[email protected]

1Introducción§  Introducción§  Obje;vosdelaProgramaciónFuncional§  PrincipiosdeDiseñoFuncional

Introd

ucción

Tallerd

eProg

ramaciónFunciona

lenJS

Page 4: Taller de Programación Funcional en JavaScript

@javiervelezreye4

IntroducciónTallerdeProgramaciónFuncionalenJavaScript

Laprogramaciónfuncionalesunviejoconocidodentrodelmundodeldesarrollo.Noobstante,en losúl;mosañosestá cogiendo traccióndebido, entreotros factores, a la emergenciadearquitecturasreac;vas,alusodeesquemasfuncionalesenelmarcodeBigDatayalcrecientesoporte que se le da desde diversas plataformas vigentes de desarrollo. JavaScript ha sidosiempreun lenguajecon fuerte tendenciaaldiseño funcional.Eneste texto revisaremossusobje;vos y principios y discu;remos los mecanismos, técnicas y patrones empleadosactualmenteparaconstruirarquitecturasfuncionaleshaciendousodeJavaScript.

I.Introducción

ProgramaciónFuncional

ProgramaciónOrientadaaObjetos

Arquitecturascentradasenlatransformación

Variantesfuncionales

TransparenciaReferencial

Inmutabilidad

ComposiEvidad

PuntosdeExtensiónPolimórfica Arquitecturas

centradasenlaabstraccionesSusEtuEvidad

LiskovianaEncapsulaciónde

estadoArquitecturas

dirigidasporflujosdecontrol

Arquitecturasdirigidasporflujosde

datos

Page 5: Taller de Programación Funcional en JavaScript

@javiervelezreye5

IntroducciónTallerdeProgramaciónFuncionalenJavaScript

A.EspecificaciónDeclaraPva

II.ObjePvosdelaProgramaciónFuncional

La programación funcional persigue diseñar especificaciones de comportamiento abstractoquesecentrenenladescripcióndelascaracterís;casdeunproblemamásqueenunaformapar;cularde resolverlo.Deacuerdoaesto, seen;endeque la responsabilidaddeencontraruna solución para el problema descansa no tanto en manos del programador sino en laarquitecturafuncionalsubyacentequetomaencuentadichaespecificación.

Qué

Cómo

function total (type) { return basket.filter (function (e) { return e.type === type; }).reduce (function (ac, e) { return ac + e.amount * e.price; }, 0); }

function total (type) { var result = 0; for (var idx = 0; idx < basket.length; idx++) { var item = basket[idx]; if (basket[idx].type === type) result += item.amount * item.price; } return result; }

var basket = [ { product: 'oranges', type:'food', amount: 2, price:15 }, { product: 'bleach' , type:'home', amount: 2, price:15 }, { product: 'pears' , type:'food', amount: 3, price:45 }, { product: 'apples' , type:'food', amount: 3, price:25 }, { product: 'gloves' , type:'home', amount: 1, price:10 } ];

La descripción fluida del esElofuncional permite entender fácil-mentelaespecificación

Aunque operaEvamente es equivalente,el esElo imperaEvo es más confuso yresultamásdiRcildeentender

Objetos

Funcional

Page 6: Taller de Programación Funcional en JavaScript

@javiervelezreye6

IntroducciónTallerdeProgramaciónFuncionalenJavaScript

B.AbstracciónFuncional

II.ObjePvosdelaProgramaciónFuncional

La programación funcional persigue alcanzar una especificación de alto nivel que captureesquemas algorítmicos de aplicación transversal. Como veremos a con;nuación, así sefomenta la reu;lización y la adaptación idiomá;ca. Esto se consigue con arquitecturascentradasenlavariabilidadfuncionalycontrastaortogonalmenteconlaorientaciónaobjetos.

var vehicles = [new Car(), new Truck(), ...]; var garage = function (vehicles) { for (v in vehicles) vehicles[v].test(); }; garage(vehicles);

var phases = [ function body (v) {...}, function paint (v) {...} ]; var test = function (phases) { function (vehicle) { return phases.reduce(function (ac, fn) { return fn(ac); }, vehicle); } };

AbstracciónFuncional

AbstraccióndePposObjetos

Funcional

V1 V2 V3

Car Truck

Bike

vehicles

body

paint

v

EnFPlafuncióneslaunidaddeabstracciónyaquepermite definir esquemas algorítmicos quedependendefuncionespasadascomoparámetros

En OOP los algoritmosse distribuyen entreobjetos con implemen-tacionesvariantes

Page 7: Taller de Programación Funcional en JavaScript

@javiervelezreye7

IntroducciónTallerdeProgramaciónFuncionalenJavaScript

C.ReuPlizaciónFuncional

II.ObjePvosdelaProgramaciónFuncional

Como consecuencia de la capacidad de abstracción en la especificación declara;va, laprogramación funcionalalcanzacotaselevadasen la reu;lizaciónde funciones.Esteniveldereu;lizaciónalgorítmicanoseconsigueenotrosparadigmascomoenlaorientaciónaobjetos.

El esquema algorítmico se reuElizasobredisEntasestructurasdedatosycondisEntasaplicacionesfuncionales

var users = [ { name: 'jvelez', sex: 'M', age: 35 }, { name: 'eperez', sex: 'F', age: 15 }, { name: 'jlopez', sex: 'M', age: 26 } ]; var adult = function (u) { return u.age > 18; }; var name = function (ac, u) { ac.push(u.name); return ac; }; get(users)(adult, name, []);

var get = function (collection) { return function (filter, reducer, base) { return collection .filter(filter) .reduce(reducer, base); }; };

var basket = [ { product: 'oranges', type: 'F', price:15 }, { product: 'bleach' , type: 'H', price:15 }, { product: 'pears' , type: 'F', price:45 }, ]; var food = function (p) { return p.type === 'F'; }; var total = function (ac, p) { return ac + p.price; }; get(basket)(food, total, 0);

Page 8: Taller de Programación Funcional en JavaScript

@javiervelezreye8

IntroducciónTallerdeProgramaciónFuncionalenJavaScript

D.AdaptaciónFuncional

II.ObjePvosdelaProgramaciónFuncional

Una de las virtudes de la programación funcional es la capacidad de poder transformar lamorfologíade las funcionesparaadaptarlasacadaescenariodeaplicaciónreal.Entérminosconcretosestosignificapodercambiarlasignaturadelafunciónyenespeciallaformaenquese proporcionan los parámetros de entrada y resultados de salida. Veremos que existenmecanismostécnicasypatronesparaar;cularesteproceso.

function greater (x, y) { return x > y; }

function greater (x, y) { return y > x; }

reverse

(function greater (x) { function (y) { return y > x; } })(18)

function greater (x) { function (y) { return y > x; } }

curry

parPal

Se invierte el ordende aplica-ción de los parámetros deformatransparente

Setransformalaevaluacióndela funciónparaquepuedaserevaluadaporfases

Se configura parcialmente lafunción para obtener elpredicadodeadulto

Page 9: Taller de Programación Funcional en JavaScript

@javiervelezreye9

IntroducciónTallerdeProgramaciónFuncionalenJavaScript

E.DinamicidadFuncional

II.ObjePvosdelaProgramaciónFuncional

La programación funcional permite diseñar funciones que sean capaces de construirabstracciones funcionales de forma dinámica en respuesta a la demanda del contexto deaplicación.Comoveremos, esteobje;vo se apoyaenmecanismosdeabstracción y tambiénabundaenlaadaptaciónfuncionalqueacabamosdedescribir.

isAdult('jlopez') isOld('jlopez') isYoung('jlopez')

function greater (x) { return function (y) { return y > x; } }

Se demanda un predicadofuncional que discrimine a losjubilados

Se demanda un predicadofuncional que discrimine a losadultos

Se demanda un predicadofuncional que discrimine a losjóvenes

La función greater es una factoríafuncional que define comporta-mientosdinamicamente

Proveedor

Clientes

var isOld = greater(65) var isYoung = greater(25)

var isAdult = greater(25)

Page 10: Taller de Programación Funcional en JavaScript

@javiervelezreye10

IntroducciónTallerdeProgramaciónFuncionalenJavaScript

A.PrincipiodeTransparenciaReferencial

III.PrincipiosdeDiseñoFuncional

Elprincipiodetransparenciareferencialpredicaqueentodaespecificaciónfuncionalcorrecta,cualquierfuncióndebepodersubs;tuirseencualquierámbitodeaplicaciónporsuexpresiónfuncional sin que ello afecte al resultado obtenido. La interpretación de este principio dediseño;enetreslecturascomplementarias.

FuncionesPuras

Dado que el predicado greater sólo depende desusparámetrosdeentradaxey, se tratadeunafunción pura. Por ello,manEene la transparenciareferencialpermiEendosususEtuciónsin impactoenlasemánEcadelcontextodeaplicación

var old = greater(65)

var old = (function greater (x) { function (y) { return y > x; } })(65);

Se dice que una función es pura – recuerda al es;lo decomportamiento matemá;co – si su valor de retorno sólodepende de los parámetros de entrada y no del estadoambiental (variables globales, variables retenidas en ámbitoléxico,operacionesdeE/S,etc.).

fEstado

Page 11: Taller de Programación Funcional en JavaScript

@javiervelezreye11

IntroducciónTallerdeProgramaciónFuncionalenJavaScript

A.PrincipiodeTransparenciaReferencial

III.PrincipiosdeDiseñoFuncional

Elprincipiodetransparenciareferencialpredicaqueentodaespecificaciónfuncionalcorrecta,cualquierfuncióndebepodersubs;tuirseencualquierámbitodeaplicaciónporsuexpresiónfuncional sin que ello afecte al resultado obtenido. La interpretación de este principio dediseño;enetreslecturascomplementarias.

ComportamientoIdempotente

pop + pop === 2 * pop

Se dice que una función es idempotente si siempre devuelve elmismo resultado para los mismos parámetros de entrada. Ennuestroejemplodeberíaverificarseestaigualdad:

function Stack () { var items = []; return { push: function (e) { items.push(e); }, pop: function () { return items.pop(); } }; }

function Stack () { return { stack: [] }; } function push (s, e) { return { stack: s.stack.concat(e), top: e }; } function pop (s) { var stack = [].concat(s.stack); var e = stack.pop(); return { stack: stack, top: e }; }

EsPloOrientadoaObjetos

EsPloFuncionalLa pila manEene el estadointernoylasoperacionespushypopnoresultanidempotentes

El estado se manEene externa-menteysepasacomoparámetroa cada operación con lo que elcomportamientoesidempotente

Page 12: Taller de Programación Funcional en JavaScript

@javiervelezreye12

IntroducciónTallerdeProgramaciónFuncionalenJavaScript

A.PrincipiodeTransparenciaReferencial

III.PrincipiosdeDiseñoFuncional

Elprincipiodetransparenciareferencialpredicaqueentodaespecificaciónfuncionalcorrecta,cualquierfuncióndebepodersubs;tuirseencualquierámbitodeaplicaciónporsuexpresiónfuncional sin que ello afecte al resultado obtenido. La interpretación de este principio dediseño;enetreslecturascomplementarias.

AgnosPcismodeEstado

La entrada acumula toda lainformación ambiental enformadeestado

clean

words

count

Entrada

Salida

FronterasArquitectónicas

Dentro de la arquitectura el estado esacarreado como parámetro a lo largodelacadenadetransformación

Cadaabstracciónenelámbitoarquitec-tónico es una función pura que hacedepender su salida exclusivamente desusparámetrosdeentrada

Todo problema de aplicación real se caracteriza por un estadointrínseco.Elagnos;cismodeestadononiegaestarealidad.Ensulugar,el principio debe interpretarse como que dentro de las fronteras delsistema el comportamiento funcional sólo puede depender de losparámetrosexplícitamentedefinidosencadafunción.

Page 13: Taller de Programación Funcional en JavaScript

@javiervelezreye13

IntroducciónTallerdeProgramaciónFuncionalenJavaScript

B.PrincipiodeInmutabilidaddeDatos

III.PrincipiosdeDiseñoFuncional

En el modelo de programación impera;va, la opera;va de computo se en;ende como unproceso secuencial y paula;no de transformación del estadomantenido por la arquitecturahardware de la máquina. En programación funcional – y en virtud de la transparenciareferencial – las funciones no dependen del estado ambiental. De ello se colige que elconceptodevariableentendidocomodepositoactualizabledeinformaciónnoexiste.

var x = 1 ... x = x + 1

x@(0) = 1 ... x@(t+1) = x@(t) + 1

En programación imperaEva las variables seenEenden como depósitos de información enmemoriaquepuedenactualizarseduranteelEempode vida del programa. La dimensión Eempo quedaocultayestodificultaelrazonamiento

Laprogramaciónfuncionalponeestrésenqueloscambiosen los datos de un programa deben manifestarse comofuncionessobreladimensiónEempo.Estosignificaqueelconceptodevariablescomodepositodeinformaciónylasoperaciones de actualización sobre ellas no estánpermiEdas

ImperaPvo P.Funcional

En términos prác;cos la aplicación se esteprincipio se traduce en que las funciones nuncadeben actualizar los parámetros de entrada sinogenerarapar;rdeellosresultadosdesalida

function push (s, e) { return s.push(e); } function push(s, e) { return s.concat(e); }

Semodificas

Nosemodificas

EsPloImperaPvo

EsPloFuncional

Page 14: Taller de Programación Funcional en JavaScript

@javiervelezreye14

IntroducciónTallerdeProgramaciónFuncionalenJavaScript

C.PrincipiodeComputaciónCentradaenColecciones

III.PrincipiosdeDiseñoFuncional

Adiferenciade loqueocurreenotrosparadigmascomoenorientaciónaobjetosdonde losdatos seorganizan en formade grafos relacionales, enprogramación funcional éstos debenmodelarsecomocolecciones–arraysodiccionariosenJavaScript–paraqueselespuedasacarpleno par;do1. Se dice que el modelo de computación de la programación funcional estácentradoencolecciones.

SetUn conjunto se modela comoun array o un diccionario debooleanos

1 3

4

[true, false, true, true]

BagUna bolsa se modela como unundiccionariodecontadores

a b

c

{a: 2, b: 3, c: 1}

a b b

BinaryTreeUn array se aplana como unacolección anidada de arrays de3 posiciones, árbol izquierdo,nodo,árbolderecho

1

5 2

HeapUna cola con prioridad es undiccionariodearraysounarraydearrays

{1: [a, c], 2: [b, c, d], 3: [f]}

7 6 4 3

[ [ [[],3,[]], 2, [[],4,[]]], 1, [[[],6,[]], 5, [[],7,[]]] ]

a c

b d e

f

1

2

3 [ [a, c], [b, c, d], [f] ]

1 Los diccionarios son una aproximación derepresentación aceptable en tanto quepuedenprocesarsecomocoleccionesdeparesclave-valor

Page 15: Taller de Programación Funcional en JavaScript

@javiervelezreye15

IntroducciónTallerdeProgramaciónFuncionalenJavaScript

D.PrincipiodeDiseñoDirigidoporCapas

III.PrincipiosdeDiseñoFuncional

Laconstruccióndearquitecturasfuncionalessigueunprocesodediseñodirigidoporcapasoniveles de especificación. Desde las abstracciones más generales encontradas en libreríasfuncionalesseconstruyeunnivel idiomá;coqueproponeunesquemaabstractodesoluciónparaelproblemapropuestoysóloentoncesseconcretaeneldominiopar;culardelproblema.

var users = [{ name: 'jlopez', sex: 'M', age: 26 } ...]; var male = function (u) { return u.age > 18; }; var name = function (ac, u) { ac.push(u.name); return ac; }; get(users)(male, name, []);

var get = function (collection) { return function (filter, reducer, base) { return collection .filter(filter) .reduce(reducer, base); }; };

map reduce filter ...

NiveldeDominioSe contextualiza el esquemaanterior dentro del dominio deaplicación concretando condatosyfuncionesespecíficas

NivelIdiomáPcoSe crea un esquema funcionalque resuelve la familia deproblemas al que pertenece elproblemaplanteado

NiveldeLibreríaSe uElizan funciones generalesconunaltoniveldeabstracción

NiveldeAb

stracción

ReuPlizaciónTransversalaDominio

Page 16: Taller de Programación Funcional en JavaScript

JavierVélezReyes@javiervelezreye

[email protected]

2JavaScriptcomoLenguajeFuncional

§  DefiniciónFuncionalporCasos§  DefiniciónporRecursión§  ExpresionesFuncionalesdeInvocaciónInmediataIIFE§  DefiniciónenOrdenSuperior§  Clausuras&RetencióndeVariables JavaScrip

tcom

oLeng

uajeFun

cion

al

Tallerd

eProg

ramaciónFunciona

lenJS

Page 17: Taller de Programación Funcional en JavaScript

@javiervelezreye17

JavaScriptcomoLenguajeFuncionalTallerdeProgramaciónFuncionalenJavaScript

Comoyahemoscomentado,losprocesosdeprogramaciónfuncionalconsistenesencialmenteen la definición de una colección de declaraciones funcionales que puedan adaptarse adis;ntosnivelesdeabstracciónyaplicarseconjugadamentepararesolverproblemasdeformadeclara;va. Para ar;cular estas tareas de definición el paradigma funcional ofrece unacoleccióndemecanismosesencialesquerevisamosenestecapítulo.

I.Introducción

TécnicasPF

PatronesPF

Elnivelde lenguajeestá formadopor la colección de mecanismosdeprogramaciónqueproporcionaellenguajedeformanaEva

NiveldeLenguaje

Las deficiencias que por suconcepción presenta el lenguajese deben suplir a este nivel poraplicación de técnicas y patronesde diseño que revisaremos enpróximoscapítulos

NivelIdiomáPcoApp App App

Defin

iciónpo

rcasos

recursividad

Expresione

sIIFE

Orden

Sup

erior

Clausuras

RetenciónVariables

SobrecargaFun

cion

al

Defin

iciónpo

rPatrone

s

JSFuncional

Page 18: Taller de Programación Funcional en JavaScript

@javiervelezreye18

JavaScriptcomoLenguajeFuncionalTallerdeProgramaciónFuncionalenJavaScript

A.DefiniciónFuncionalporCasos

II.MecanismosdeProgramaciónFuncional

La forma más sencilla de definir una función es diseñando explícitamente la colección devaloresderetornoquedebedevolverparacadaposibleparámetrodeentrada.Aunqueestemecanismo parece poco flexible aisladamente, cuando se conjuga con otras formas dedefiniciónresultadeaplicaciónfrecuente.

La definición por casos se expresadeclarandoexplícitamenteelvalorquedebe devolver la función para cadaposible valor de los parámetros deentrada

function f (parámetros) { return caso-1 ? resultado-1 : caso-2 ? resultado-2 : resultado-defecto; }

El uso anidado del operadorcondicional permite expresar lospares caso-resultado como unaúnicaexpresiónderetorno

ÚnicaExpresión

EnumeraciónExplícitadecasos

function comparator(x) { return x > 0 ? 1 : x === 0 ? 0 : -1 ; }

function even(n) { return n % 2; }

Se uEliza el operador condicionalanidado para definir cada casofuncional

La definición mediante una únicaexpresión es el escenario mássencillodedefiniciónporcasos

Page 19: Taller de Programación Funcional en JavaScript

@javiervelezreye19

JavaScriptcomoLenguajeFuncionalTallerdeProgramaciónFuncionalenJavaScript

B.DefiniciónporRecursión

II.MecanismosdeProgramaciónFuncional

Ladefinicióndefuncionesporrecursiónconsisteen la invocaciónde lapropia funcióncomopartedelprocesodedefinición.Elesquemadedefiniciónrecursivoseapoyaenelmecanismoanterior para dis;nguir entre casos base – aquéllos que devuelven un resultado final – deaquélloscasosrecursivos–dondeelvalorderetornovuelveainvocaralapropiafunción.

function f (parámetros) { return caso-base-1 ? resultado-base-1 : caso-base-2 ? resultado-base-2 : caso-recursivo-1 ? resultado-recursivo-1 : caso-recursivo-2 ? resultado-recursivo-2 : resultado-defecto ; }

Loscasosbasesonelfinaldelprocesorecursivoysesuponensoluciones inmediatas aproblemassencillos

CasosbaseLos casos recursivos sediseñan invocando a lapropia función sobrevalores de parámetrosque convergen a loscasosbase

Casosrecursivos

Asegúrese de que cada resultadorecursivo converge a alguno de loscasosbase

II.RegladeconvergenciaI.RegladecoberturaAsegúrese de que todos los casosbasedelproblemahansido incluidosexplícitamente en la definición de lafunción

Para diseñar cada caso recursivoasumaquelafunciónpordefinirestáya defin ida para va lo res deparámetrosmáspróximosaloscasosbase

III.Regladeautodefinición

Page 20: Taller de Programación Funcional en JavaScript

@javiervelezreye20

JavaScriptcomoLenguajeFuncionalTallerdeProgramaciónFuncionalenJavaScript

B.DefiniciónporRecursión

II.MecanismosdeProgramaciónFuncional

Enfuncióndecómoseexpresanloscasosrecursivosdeunafunciónpodemosdis;nguirentredos;posdesituaciones.Enlarecursióndirecta,loscasosrecursivosdelafunciónseexpresanen términos de llamadas a ella misma. En la recursión indirecta, la función invoca a otrafunciónquerecurresobrelaprimera.

RecursiónDirecta

function factorial (n) { return n === 0 ? 1 : n * factorial(n - 1); }

factorial(4) = 4 * factorial(3) = 4 * 3 * factorial(2) = 4 * 3 * 2 * factorial(1) = 4 * 3 * 2 * 1 * factorial(0) = 4 * 3 * 2 * 1 * 1 = 24

RecursiónIndirecta

function even (n) { return n === 0 ? true : !odd(n-1); } function odd (n) { return n === 0 ? false : !even(n-1); }

even(4) = !odd(3) = !!even(2) = !!!odd(1) = !!!!even(0) = !!!!true = true

Los casos recursivos convergenhacialoscasosbasereduciendoeltamaño del problema en unaunidadacadapaso

Laconvergenciahacialoscasosbaseva incluyendo un operador denegación que se resuelven al llegaralcasobase

Page 21: Taller de Programación Funcional en JavaScript

@javiervelezreye21

JavaScriptcomoLenguajeFuncionalTallerdeProgramaciónFuncionalenJavaScript

B.DefiniciónporRecursión

II.MecanismosdeProgramaciónFuncional

Dadoque la programación funcional no disponede estructuras de control de flujo, la únicaformade resolver problemas que requierenun computo itera;vo es expresarlas a par;r deunaformulaciónrecursiva.Aunquepuederesultarenprincipiomáscomplejo,laexpresividadfuncional aumenta con este ;po de expresiones. Además hay problemas que ;enen unaresolucióninherentementerecursiva.

ProblemadelasTorresdeHanoi

Moverdiscosdeunoenunoparadejarlosenlamisma posición de A en C usando B comoauxiliar. Los discos por encima de uno dadodebensersiempredemenortamañoqueéste.

function hanoi (n, origen, aux, destino) { if (n === 1) mover(origen, destino); else { hanoi(n-1, origen, destino, aux); mover(origen, destino); hanoi(n-1, aux, origen, destino); } } function mover (origen, destino) { destino.push (origen.pop()); } var A = [4, 3, 2, 1], B = [], C = [] hanoi(A, B, C);

A B C

n-1

1

n-1

1

2

3

Page 22: Taller de Programación Funcional en JavaScript

@javiervelezreye22

JavaScriptcomoLenguajeFuncionalTallerdeProgramaciónFuncionalenJavaScript

C.ExpresionesFuncionaleseInvocaciónInmediata

II.MecanismosdeProgramaciónFuncional

Noenpocasocasiones lanecesidaddedefinirunafunciónserestringeaunsolousoqueserealiza a con;nuación de su definición. Si encerramos una definición de función entreparéntesisyaplicamosa laexpresión resultanteeloperadorde invocación– losparámetrosactuales a su vez entre parentesis y separados por comas – obtenemos una expresiónfuncionaldeinvocacióninmediataIIFE.

(function f (parámetros-formales) { <<cuerpo de declaración funcional>> })(parámetros-actuales);

La expresión funcional se invocadirectamente por aplicación de losparámetrosactuales

La definición funcional se encierraentreparéntesisparaconverErlaenunaexpresiónevaluable

ExpresiónFuncional InvocaciónInmediata

var cfg = (function config(user) { // getting config from DB return {...} })('jvelez');

Uncpicoejemplode IIFE sedacuandosepretendenrealizarcálculoscomplejosotareasqueseefectuaránunasolavezalolargodelcódigo

LaventajadeesteEpodeconstruccionesesquelafunciónseliberadelamemoriatrassuejecución

Page 23: Taller de Programación Funcional en JavaScript

@javiervelezreye23

JavaScriptcomoLenguajeFuncionalTallerdeProgramaciónFuncionalenJavaScript

D.DefiniciónenOrdenSuperior

II.MecanismosdeProgramaciónFuncional

EnJavaScriptlasfuncionessonciudadanosdeprimerorden.Estoquieredecirqueatodoslosefectos no existe ningún;podediferencia entre una función y cualquier valor de otro;poprimi;vo. Esto permite a una función recibir otras funciones como parámetros o devolverfuncionescomoretorno.Estemecanismoseleconoceconelnombredeordensuperior.

FuncionescomoParámetrosaOtrasFunciones

El paso de funciones como parámetros a una funciónpermite que el comportamiento de ésta sea adaptada pormediodelainyeccióndecódigovarianteencadainvocación.Esta aproximación contrasta con la programación por ;posvariantespropiadelaorientaciónaobjetos.

FuncionescomoRetornodeOtrasFunciones

Lasfuncionessoncapacesdegenerardinámicamentefuncionesquedevuelvencomoresultado.Estoesdeespecial interés cuando la función devuelta es elresultado de transformar una función recibida comoargumento.Esteprocesojus;ficaelnombredeordensuperioryaqueseoperaconfuncionesgenéricas.

function once (fn) { var called = false; return function () { if (!called) { called = true; return fn.apply(this, arguments); } } }

var greater = function (x, y) {...}; var less = function (x, y) {...}; var even = function (x) {...}; [1, 4, 3, 2].sort(greater); [1, 4, 3, 2].sort(less); [1, 4, 3, 2].filter(even);

Page 24: Taller de Programación Funcional en JavaScript

@javiervelezreye24

JavaScriptcomoLenguajeFuncionalTallerdeProgramaciónFuncionalenJavaScript

E.Clausuras&RetencióndeVariables

II.MecanismosdeProgramaciónFuncional

Las funciones que, por medio de los mecanismos de orden superior, devuelven funcionescomoresultadosepuedenexpresarentérminosdevariableslocalesoparámetrospresentesenelentornofuncionaldondesedefinen.Laretencióndevariableseselmecanismomedianteel cual dichas variables y parámetros sonmantenidos durante todo el ;empode vida de lafunciónderetorno.Este;podefuncionessedenominanclausuras.

function Logger(cls) { var pre = 'Logger'; var post = '...'; return function (message) { console.log ('%s[%s] - [%s]%s', pre, cls, message, post); } }

var log = Logger('My Script'); Log('starting'); log(1234); log('end');

function (message) {...}

pre post cls

Clausura

Las clausuras son un mecanismos deconstrucciónfuncionalquecapturadeformapermanenteunestadodeconfiguraciónquecondicionasucomportamiento

VariablesRetenidasAl extraer una función fuera de su ámbitoléxicodedefinición semanEeneel contextodevariablesyparámetrosquedichafunciónuEliza.

Page 25: Taller de Programación Funcional en JavaScript

JavierVélezReyes@javiervelezreye

[email protected]

3TécnicasdeProgramaciónFuncional

§  Abstracción§  Encapsulación§  InmersiónporRecursiónyAcumulación§  EvaluaciónParcial§  ComposiciónFuncional&ComposiciónMonádica TécnicasdeProg

ramaciónFunciona

l

Tallerd

eProg

ramaciónFunciona

lenJS

Page 26: Taller de Programación Funcional en JavaScript

@javiervelezreye26

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

Apar;rde losmecanismosqueofrece JavaScript como lenguajedeprogramación sepuedeescribirsoewarebiencentradoenelparadigmafuncional.Noobstante,paraelloesnecesarioconocerunacoleccióndetécnicasbásicasquedescribenformascanónicasdehacer frenteaproblemasrecurrentes.A lo largodeestecapítuloharemosunarevisiónde las técnicasmásrelevantes.

I.Introducción

Lastécnicasdeabstracciónpermitendefinirespecificacionesfuncionalescondiferentesgradosdegeneralidadyreu;lizacióntransversal

AbstracciónEnfuncionallaencapsulacióndeestadoesunmalavecesnecesarioyenmuchasocasionespuedereemplazarseporencapsulacióndecomportamiento

EncapsulaciónLastécnicasdeinmersiónsonunacon-jugacióndeabstracción,encapsulaciónyrecursividadparaobtenercontroldeflujodirigidopordatos

Inmersión

Laevaluaciónparcialpermiteevaluarunafunciónenvariasfasesreduciendopaula;namenteelnúmerodevariableslibres

EvaluaciónParcialLacomposiciónfuncionalpermitear;cularprocesosdesecuenciamientodefuncionesdefinidascomoexpresionesanalí;cas

ComposiciónFuncionalLatransformaciónmonádicapersigueadaptarfuncionesparaconver;rlasentransformacionespurasquesoportenprocesosdecomposición

TransformaciónMonádica

Lainversióndecontrolpermitepermutarentrelasarquitecturasfuncionalescentradasenlosdatosylascentradasenlastransformaciones

InversióndeControl

Page 27: Taller de Programación Funcional en JavaScript

@javiervelezreye27

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

A.TécnicasdeAbstracción

II.TécnicasdeProgramaciónFuncional

Una de las técnica de programación funcionalmás comúnmente u;lizadas, en alineamientoconlosprincipiosdediseñopresentadosanteriormente,eslaabstracciónfuncional.Lastareasdeabstraccióndebenentendersecomounprocesodetransformaciónenelqueladefinicióndeunafunciónsereexpresaentérminosmásgeneralesparadarcoberturaaunabanicomásampliodeescenariosdeaplicación.Podemosdis;nguirtresdimensionesdeabstracción.

AbstracciónenAnchura

Suma convencional de dos nú-meros pasados como para-metros

add(x, y)

add

Combinamediante la función ctodos los parámetros a parErdeunodadoenposiciónp

reduceFrom(p, c)(x, y, …)

reduceFrom

Suma todos los parámetros dela función independientementedelaaridad

addAll(x, y, z, …)

addAll

Suma todos los parámetros delafunciónaparErdeaquélqueocupaunaposiciónp

add(p)(x, y, z, …)

addFromAbstracciónenComportamiento

AbstracciónenAlcance

Page 28: Taller de Programación Funcional en JavaScript

@javiervelezreye28

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

B.TécnicasdeEncapsulación

II.TécnicasdeProgramaciónFuncional

Medianteelusodeclausurasylaretencióndevariablesesposiblecapturar,durantelafasedediseñooejecución,ciertainformaciónqueresultadeu;lidadparaadaptarelcomportamientode la funcióna lo largodel;empo.Esposibledis;nguirentreencapsulacióndeestadoydecomportamiento.

EncapsulacióndeEstado.PilaUndo

function Stack () { var items = []; var history = []; return { push: function (e) { history.push([].concat(items)); items.push(e); }, pop: function () { history.push([].concat(items)); return items.pop(); }, undo: function () { if (history.length > 0) items = history.pop(); } }; }

Lasvariablesquecapturanelestadoquedanretenidas dentro de la clausura lo quepermite arEcularmodelos de programaciónfuncionalqueevolucionanconelEempo

RetencióndeEstado

Ojo! Las funciones que dependen del estado son enrealidadunamalaprácEcadeprogramacióndeacuerdoalosprincipiosdediseñodelparadigma

DependenciadeEstado

1

2

3

1

1 2

2 31

items history

undo

Page 29: Taller de Programación Funcional en JavaScript

@javiervelezreye29

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

B.TécnicasdeEncapsulación

II.TécnicasdeProgramaciónFuncional

Medianteelusodeclausurasylaretencióndevariablesesposiblecapturar,durantelafasedediseñooejecución,ciertainformaciónqueresultadeu;lidadparaadaptarelcomportamientode la funcióna lo largodel;empo.Esposibledis;nguirentreencapsulacióndeestadoydecomportamiento.

EncapsulacióndeComportamiento.PilaUndofunction Stack () { var items = []; var history = []; return { push: function push (e) { history.push(function(){items.pop()}); items.push(e); }, pop: function pop () { var e = items.pop(); history.push(function(){items.push(e);}); return e; }, undo: function undo() { if (history.length > 0) history.pop()(), } }; }

Dentro de cada operación, se registran en elhistórico las operaciones inversas para luegoinvocarlasdesdelaoperacióndeshacer

Enestecasolavariabledehistóricocapturala colección de operaciones inversas quepermiten deshacer las transacciones segúnhanidosucediendo

RetencióndeComportamiento

OperacionesInversas

1

2

3

pop

items history

undopop pop

poppoppop

Page 30: Taller de Programación Funcional en JavaScript

@javiervelezreye30

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

B.TécnicasdeEncapsulación

II.TécnicasdeProgramaciónFuncional

Medianteelusodeclausurasylaretencióndevariablesesposiblecapturar,durantelafasedediseñooejecución,ciertainformaciónqueresultadeu;lidadparaadaptarelcomportamientode la funcióna lo largodel;empo.Esposibledis;nguirentreencapsulacióndeestadoydecomportamiento.

EncapsulacióndeComportamiento.Bus

function Bus () { var fns = {}; return { receive: function (e, fn) { fns[e] = fn; }, send: function (e, ctx) { return fns[e].apply(null, ctx); } }; } var bus = Bus(); bus.receive('add', function (x,y) {return x+y;}); bus.receive('sub', function (x,y) {return x-y;}); bus.send('add', [3,2]); bus.send('sub', [7,3]);

bus

fn

sub x-y

x+yadd

event

El productor emite con laoperaciónsenduneventoalosreceptores

send

send('add', [3,2])

El consumidor ser eg i s t r a en l o seventosdeinterés

receive receive('add', +)

3+2

Page 31: Taller de Programación Funcional en JavaScript

@javiervelezreye31

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

C.DiseñoporInmersión

II.TécnicasdeProgramaciónFuncional

Dado que la programación funcional no soporta los esquemas itera;vos propios de laprogramaciónimpera;va,esprecisoorientarloscálculosalarecurrenciaapoyándoseparaelloenparámetrosauxiliares.Lastécnicasdeinmersiónconjuganencapsulaciónyabstracciónconelusodeparámetrosauxiliares.Podemosdis;nguirdiferentes;posdeinmersión.

function find (v, e) { var aux = function (v, e, p) { return (p > v.length) ? -1 : (v[p] === e) ? p : aux(v, e, p + 1); }; return aux(v, e, 0); }

I.InmersiónporRecorrido

function addAll (v) { return (function aux(v, p) { if (p === v.length-1) return v[p]; else return v[p] + aux (v, p+1); }) (v, 0); }

LainmersiónderecorridoexEendelafunción introduciendo un nuevoparámetrocuyopropósitoesllevarlacuenta del punto hasta el que se haavanzadoenelvector.

aux([1,2,3], 0) = 1 + aux([1,2,3], 1) = 1 + 2 + aux ([1,2,3], 2) = 1 + 2 + 3 = 6

La técnica se apoya es unaabstracción que quedasumergidadentrodelamásespecíficaporencapsulación

321

p >

Page 32: Taller de Programación Funcional en JavaScript

@javiervelezreye32

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

C.DiseñoporInmersión

II.TécnicasdeProgramaciónFuncional

Dado que la programación funcional no soporta los esquemas itera;vos propios de laprogramaciónimpera;va,esprecisoorientarloscálculosalarecurrenciaapoyándoseparaelloenparámetrosauxiliares.Lastécnicasdeinmersiónconjuganencapsulaciónyabstracciónconelusodeparámetrosauxiliares.Podemosdis;nguirdiferentes;posdeinmersión.

II.InmersiónporAcumulación

La acumulación se aplicaaquí para obtener recursi-vidad final buscando laeficienciaenmemoria

321

p,ac >

function addAll (v) { return (function aux(v, p, ac) { if (p === v.length) return ac; else return aux (v, p+1, v[p]+ac); })(v, 0, 0); }

function even (v) { return (function aux(v, p, ac){ if (p === v.length) return ac; else { if (v[p] % 2 === 0) ac.push(v[p]); return aux(v, p+1, ac); } })(v, 0, []); }

Se uEliza la técnica de acumulaciónpara consolidad un vector formadopor el subconjunto de los elementosparesdelvector

Reducción

TailRecursion

aux([1,2,3], 0, 0) = aux([1,2,3], 1, 1) = aux ([1,2,3], 2, 3) = aux ([1,2,3], 3, 6) = 6

Page 33: Taller de Programación Funcional en JavaScript

@javiervelezreye33

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

D.EvaluaciónParcial

II.TécnicasdeProgramaciónFuncional

El uso de clausuras permite transformar una función para que pueda evaluarse demaneraparcial resolviendo sólo algunos de sus parámetros. El resultado es una nueva función conmenosgradosdelibertaddondelosparametrosyaevaluadossefijanaunvalorconcretoyelrestoquedancomovariableslibres.

function color(rr) { return function (gg) { return function (bb) { return [rr, gg, bb] ; }; }; }

I.DimensionesContractuales

A diferencia de lo que ocurre en otrosparadigmas, el diseño funcional deabstracciones;enedosdimensionesdedefinición, la dimensión espacial y ladimensióntemporal.

En la dimensión temporalcada fase conduce a unaetapa de resolución parcialdeparámetros

La dimensión espacial vinculaconvencionalmente valores actualesaparámetros

Desde la fase 1 a la fase 2 seresuelve el parámetro rr yquedan dos dimensiones libresdemovimiento(gg,bb) II.ReducciónDimensional

Cada fase de aplicación temporal deparámetros conduce a una reduccióndimensionalenelespaciodelproblema.

bb

gg

rr bb

gg

rr = cc

color('cc')('a3')('45')

Page 34: Taller de Programación Funcional en JavaScript

@javiervelezreye34

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

D.EvaluaciónParcial

II.TécnicasdeProgramaciónFuncional

Elusodelaevaluaciónparcialpermitequeelprogramadorvayaresolviendodeformafaseadala evaluación de una función a medida que va disponiendo de los argumentos actualesnecesarios.Enestoscasos,eldiseñodelafuncióndebecuidarseparagaran;zarqueelordenenelquesedemandanlosparámetrosalolargodel;empocorrespondeconelesperadoenelcontextoprevistodeuso.

Ejemplo.EvaluaciónporFases

function schema (scheme) { var uri = { scheme : scheme }; return function (host) { uri.host = host; return function (port) { uri.port = port; return function (path) { uri.path = path; return function () { return uri; }; }; }; }; }

Se arEcula un proceso de construcción porfasesquepermiteinyectarlaspartesdeunaUri.EsteesquemarecuerdaalpatrónBuilderdeOOPperousandoúnicamentefunciones

var host = schema('http'); var port = host('foo.com'); var path = port(80); var uri = path('index.html'); uri();

Aunque la aplicación de esteesquema induce un estrictoorden en la resolución para-métrica permite resolver porfaseselprocesoconstrucEvoamedida que se dispone de losdatos

Page 35: Taller de Programación Funcional en JavaScript

@javiervelezreye35

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

D.EvaluaciónParcial

II.TécnicasdeProgramaciónFuncional

Otro escenario protogpico del uso de la evaluación parcial se da en la comunicación entrefuncionesproveedorasyclientes.Elproveedorresuelveparcialmenteunafunciónreduciendoasí el número de dimensiones y la entrega en respuesta a la demanda de un cliente queresolveráelrestodedimensionesconargumentosactualesensucesivasinvocaciones.Enestecaso, el diseño funcional debe fasearse teniendo en cuenta la intervención primera delproveedoryposteriordelcliente.

TransferenciaProveedor-Consumidor

function RuleEngine (ctx) { return function eval(rule) { return function () { var args = [].slice.call(arguments); if (rule.trigger.apply(ctx, args)) return rule.action.apply(ctx, args); }; }; } var rE = RuleEngine({age: 18, login: false});

rE ({ trigger: function (age) { return age > this.age; }, action: function () { return this.login = true; } })(19); rE ({ trigger: function () { return this.login; }, action: function () { return 'Bienvenido!'; } })();

Elproveedorresuelveparcialmenteunafunciónevalylaentregacomoresultadoalafuncióncliente

La función obtenida del proveedorpermite al cliente evaluar reglas queseapoyanenlasvariablesretenidas

rE ctx

function eval(rule) {}

Proveedor

RuleEngineRuleEngine(ctx)

Cliente

Page 36: Taller de Programación Funcional en JavaScript

@javiervelezreye36

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

E.ComposiciónFuncional

II.TécnicasdeProgramaciónFuncional

Dado que en programación funcional las abstracciones sonmeras transformaciones que nopuedenar;cularunalgoritmosecuencial,esfrecuentemodelarelsecuenciamientoenbasealacomposición.Deestamanera,elvalorderetornodeuna funciónsirvedeentradapara lafunciónsubsiguiente.

function clean (s){ return s.trim(); } function words (s){ return s.split(' '); } function count (s){ return s.length; } count( words( clean('La FP en JS Mola!!!') ) );

clean

words

count

s

5 LacascadadecomposiciónfuncionalserecorreensenEdoinversoalnatural.Losdatoscomienzanporlafunciónmásinterna(clean)yatraviesanlacadenadecomposiciónascendentementehastalacima(count).Enelcapítulosiguienteestudiaremospatronesqueconducenaunalecturadescendentemásnatural

La organización composiEva de funcionesconduce a arquitecturas centradas en lastransformaciones que los datos atraviesan encascada

Page 37: Taller de Programación Funcional en JavaScript

@javiervelezreye37

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

E.ComposiciónFuncional

II.TécnicasdeProgramaciónFuncional

Enocasioneslaformaenlaquesedefinenlasabstraccionesfuncionalesnoescompa;bleconlosprocesosdecomposición.Parapoderar;cularadecuadamentedichosprocesosdebemostenerencuentadosreglasdetransformaciónfuncionalquepuedesernecesarioaplicarparaconseguirfuncionescomposi;vas.

El Epo del parámetro de entrada de unafuncióndebesercompaEbleconelEpodelvalor de retorno devuelto por la funciónanterior para que la composición puedaarEcularseconéxito

II.CompaPbilidadRango-Dominio

I.DominioSimpleDado que una función f devuelve un únicovalorderetorno,elnúmerodeparámetrosqueaceptaunafuncióngcuandosecomponeconfdebe ser exactamente uno. ParamiEgar esteproblemaesposible encapsular los resultadosde f en una estructura de datos y/o resolvertodos los parámetros de g menos uno pormediodeevaluaciónparcial

F

GT

U ElEpodesalidaTdebesercompaEbleconel Epo de entrada U. En términos OOPdiríamosqueTdebesersubEpodeU

count( words( clean(s) ) );

[String]-> Number String -> [String] String -> String

neg( square( {stack:[3]} ) );

function square(r) { var e = r.stack.pop(); return { value: e*e, stack: r.stack }; } function neg(r) { r.stack.push(-r.value); return r; }

Page 38: Taller de Programación Funcional en JavaScript

@javiervelezreye38

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

F.TransformaciónMonádica

II.TécnicasdeProgramaciónFuncional

Eldiseñodefuncionesdebehacersegaran;zandolaausenciadeefectoscolateralesdemaneraquecadafunciónsólodependadesusparámetrosdeentrada.Sinembargo,enelmundoreales frecuente requerir que una función realice operaciones que dependan del entorno(dependenciasdeestado,operacionesdeE/S,etc.).Lastécnicasdetransformaciónmonádicagaran;zanlaausenciadeefectoscolateralesalavezqueconservanlacapacidadcomposi;va.

Supongamos que tenemos unalibrería de funciones matemáEcasde un solo parámetro que operancon números y devuelven unnúmero.PormoEvosdedepuraciónestas funciones emiten mensajes alaconsola

function inv (x) { console.log('invertir'); return 1/x; } function sqr (x) { console.log('cuadrado'); return x*x; } function inc (x) { console.log('incremento'); return x+1; } function dec (x) { console.log('decremento'); return x-1; }

Dado que la traza por consola seconsidera un efecto colateralindeseable se transforman lasfuncionesenpurasparametrizandolatrazacomovaloranexodesalida

function inv (x) { return { value: 1/x, log: ['invertir'] }; } function sqr (x) { return { value: x*x, log: ['cuadrado'] }; } function inc (x) { return { value: x+1, log: ['incrementar'] }; } function dec (x) { return { value: x-1, log: ['decrementar'] }; }

Ejemplo.MonadaEscritor

Page 39: Taller de Programación Funcional en JavaScript

@javiervelezreye39

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

F.TransformaciónMonádica

II.TécnicasdeProgramaciónFuncional

Eldiseñodefuncionesdebehacersegaran;zandolaausenciadeefectoscolateralesdemaneraquecadafunciónsólodependadesusparámetrosdeentrada.Sinembargo,enelmundoreales frecuente requerir que una función realice operaciones que dependan del entorno(dependenciasdeestado,operacionesdeE/S,etc.).Lastécnicasdetransformaciónmonádicagaran;zanlaausenciadeefectoscolateralesalavezqueconservanlacapacidadcomposi;va.

Ahora las funciones son puras pero han perdido sucapacidad composiEva puesto que incumplen laregla de compaEbilidad Rango-Dominio. Esnecesario, en primer lugar, crear una función unitque eleve valores unitarios desde el Epo simple(Number)alEpomonádico(valor+log)

Ahora podemos crear una función bind que permita componernuestras funciones anteriores sin necesidad de alterarlas. Estafunción recibeun valormonádico (entrada+ logacumulado) yunadenuestrasfunciones.Lafunciónbindprimerodesenvuelvelamonada,despuésaplicalafunciónpasadacomoparámetroyanexa la traza de la misma al log acumulado. Finalmentedevuelvelaestructuramonádicaconlosresultadosobtenidos

function unit (value) { return { value: value, log : [] }; }

Ejemplo.MonadaEscritor

function bind (m, fn) { var r = fn(m.value); return { value : r.value, log : m.log.concat(r.log) }; return this; }

Page 40: Taller de Programación Funcional en JavaScript

@javiervelezreye40

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

F.TransformaciónMonádica

II.TécnicasdeProgramaciónFuncional

Eldiseñodefuncionesdebehacersegaran;zandolaausenciadeefectoscolateralesdemaneraquecadafunciónsólodependadesusparámetrosdeentrada.Sinembargo,enelmundoreales frecuente requerir que una función realice operaciones que dependan del entorno(dependenciasdeestado,operacionesdeE/S,etc.).Lastécnicasdetransformaciónmonádicagaran;zanlaausenciadeefectoscolateralesalavezqueconservanlacapacidadcomposi;va.

Con las funciones de transformación monádicaunit & bind hemos creado una solución paragaranEzar la composición funcional eliminandolosefectoscolateralesdetrazaporpantalla

Ejemplo.MonadaEscritor

bind( bind( unit(3), sqr ), neg );

unit

sqr

inc

3

{ value: 10, log: [ 'cuadrado', 'incremento'] }

ElvalorprimiEvo3,setransformaprimeroalEpomonádicoyluegosecomponeconlafunciónsqreincpormediodelaasistenciaqueproporcionalafunciónbind

Page 41: Taller de Programación Funcional en JavaScript

@javiervelezreye41

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

F.TransformaciónMonádica

II.TécnicasdeProgramaciónFuncional

Eldiseñodefuncionesdebehacersegaran;zandolaausenciadeefectoscolateralesdemaneraquecadafunciónsólodependadesusparámetrosdeentrada.Sinembargo,enelmundoreales frecuente requerir que una función realice operaciones que dependan del entorno(dependenciasdeestado,operacionesdeE/S,etc.).Lastécnicasdetransformaciónmonádicagaran;zanlaausenciadeefectoscolateralesalavezqueconservanlacapacidadcomposi;va.

ExistenmuchosEposdeefectoscolateralesquepuedenevitarse por medio de la aplicación de técnicas decomposición monádica. Dado que cada Epo de efectocolateral requiere una lógica unit y bind específica esbuenaideaexpresarestastécnicascomoobjetosdondeunitsecodifiquecomoconstructorybindcomométodomiembrodelprotoEpo

Ejemplo.MonadaEscritor

function Writer (value) { this.value = value; this.log = []; } Writer.prototype.bind = function (fn) { var m = fn(this.value); var result = new Writer(m.value); result.log = this.log.concat(m.log); return result; };

var r = new Writer(3) .bind(sqr) .bind(inc);

Aunque desde un punto de vista pragmáEcoesta operaEva resulta cómoda y naturaldebemosserconscientesdequeseapoyaenencapsulacióndeestado

Page 42: Taller de Programación Funcional en JavaScript

@javiervelezreye42

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

G.InversióndeControl

II.TécnicasdeProgramaciónFuncional

Lasprogramaciónfuncionalpermitear;culardos;posdearquitecturascomplementarias.Lasarquitecturascentradasenlosdatosfijanunacoleccióndedatosdeentradayhacenatravesaren torno a ellos una colección de transformaciones funcionales. Ortogonalmente, lasarquitecturascentradasenlatransformaciónestablecenunacadenacomposi;vadefuncionesqueesatravesadapordiversascoleccionesdedatos.Lastécnicasdeinversióndecontrolsonunapasarelaparaconver;runesquemaarquitectónicoenelcontrarioyviceversa.

data('La FP en JS Mola!!!') .do(clean) .do(words) .do(count);

function data (value) { return { value: value, do: function (fn) { this.value = fn(this.value); return this; } }; }

count words clean S 5

ArquitecturasCentradasenlosDatos

Lasarquitecturascentradasenlosdatosfijanunconjunto de datos y permiten realizartransformaciones pasadas como parámetros enordensuperior

Page 43: Taller de Programación Funcional en JavaScript

@javiervelezreye43

TécnicasdeProgramaciónFuncionalTallerdeProgramaciónFuncionalenJavaScript

G.InversióndeControl

II.TécnicasdeProgramaciónFuncional

Lasprogramaciónfuncionalpermitear;culardos;posdearquitecturascomplementarias.Lasarquitecturascentradasenlosdatosfijanunacoleccióndedatosdeentradayhacenatravesaren torno a ellos una colección de transformaciones funcionales. Ortogonalmente, lasarquitecturascentradasenlatransformaciónestablecenunacadenacomposi;vadefuncionesqueesatravesadapordiversascoleccionesdedatos.Lastécnicasdeinversióndecontrolsonunapasarelaparaconver;runesquemaarquitectónicoenelcontrarioyviceversa.ArquitecturasCentradasenlaTransformación

Lasarquitecturascentradasenlatransformaciónestablecen una cadena de composición detransformaciones funcionales por las queatraviesandisEntascoleccionesdedatos

clean words countS 5

function clean (s) { return s.trim(); } function words (s) { return s.split(' '); } function count (s) { return s.length; } count( words( clean('La FP en JS Mola!!!') ) );

En el siguiente capítulo estudiaremos patronesdedicados a establecer transformaciones paraconverEr arquitecturas centradas en los datos aarquitecturas centradas en transformación yviceversa

Page 44: Taller de Programación Funcional en JavaScript

JavierVélezReyes@javiervelezreye

[email protected]

TallerdeProgramaciónFuncionalenJavaScript

Enero2016