Taller de Programación Funcional en JavaScript
-
Upload
javier-velez-reyes -
Category
Software
-
view
4.670 -
download
5
Transcript of Taller de Programación Funcional en JavaScript
JavierVélezReyes@javiervelezreye
TallerdeProgramaciónFuncionalenJavaScript
Enero2016
@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?
@javiervelezreye
linkedin.com/in/javiervelezreyes
gplus.to/javiervelezreyes
jvelez77
javiervelezreyes
youtube.com/user/javiervelezreyes
JavierVélezReyes@javiervelezreye
1Introducción§ Introducción§ Obje;vosdelaProgramaciónFuncional§ PrincipiosdeDiseñoFuncional
Introd
ucción
Tallerd
eProg
ramaciónFunciona
lenJS
@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
@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
@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
@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);
@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
@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)
@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
@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
@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.
@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
@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
@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
JavierVélezReyes@javiervelezreye
2JavaScriptcomoLenguajeFuncional
§ DefiniciónFuncionalporCasos§ DefiniciónporRecursión§ ExpresionesFuncionalesdeInvocaciónInmediataIIFE§ DefiniciónenOrdenSuperior§ Clausuras&RetencióndeVariables JavaScrip
tcom
oLeng
uajeFun
cion
al
Tallerd
eProg
ramaciónFunciona
lenJS
@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
@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
@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
@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
@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
@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
@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);
@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.
JavierVélezReyes@javiervelezreye
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
@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
@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
@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
@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
@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
@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 >
@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
@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')
@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
@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
@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
@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; }
@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
@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; }
@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
@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
@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
@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
JavierVélezReyes@javiervelezreye
TallerdeProgramaciónFuncionalenJavaScript
Enero2016