Paradigma de programación en JavaScript

Paradigma de programación en JavaScript

¿Qué es un paradigma de programación?

El modelo o mapa de como vemos el mundo real, eso es un paradigma, es una manera de ver y hacer las cosas. Siguiendo esta lógica, un paradigma de programación no es más que una forma de ver y crear código de programación.

Los paradigmas son poderosos porque crean los cristales o las lentes a través de los cuales vemos el mundo.

Stephen R. Covey

Existe tres principales paradigmas de programación utilizados en la actualidad y que en JavaScript siempre han existido desde su primera versión.

  • Paradigma de programación Estructurada
  • Orientada a objetos
  • Funcional

Ahora bien, si nos apegamos a la frase de Stephen R. Covey, sobre que los paradigmas crean las lentes a través de los cuales vemos el mundo. Imaginemos que los tres paradigmas anteriores, cada uno, son un par de lentes que nos ponemos a la hora de programar y que podemos cambiar esos lentes según nuestras necesidades visuales (de programación o solución de problemas).

Paradigma de programación estructurada

Origen

En el año 1954 apareció el lenguaje de programación FORTRAN, luego en 1958 ALGOL y en 1959 COBOL. Tiempo después Edsger Wybe Dijkstra en 1968 descubre el paradigma de programación estructurada, decimos que “descubre” porque en realidad no lo inventaron. Aunque este paradigma de programación se formalizó tiempo después de la aparición de estos lenguajes de programación, era posible hacer programación estructurada en ellos.

Dijkstra reconoció que la programación era difícil, y los programadores no lo hacemos muy bien, de lo cual estoy totalmente de acuerdo. Un programa de cualquier complejidad tiene muchos detalles para el cerebro humano. De hecho la neurociencia nos indica que la mente enfocada solo puede trabajar con cuatro datos a la vez, cuanto mucho. Por esta razón, si se descuida un pequeño detalle creamos programas que parecen funcionar bien, pero que fallan en formas que uno nunca se imagina.

Pruebas

La solución de Dijkstra fue utilizar pruebas, solo que estas pruebas usaban mucho las matemáticas, lo cual era bastante difícil de implementar. Durante su investigación encontró que ciertos usos de GOTO hacían difícil descomponer un programa grande en piezas más pequeñas, no se podía aplicar “divide y vencerás”, necesario para crear pruebas razonables.

Secuencia, selección e iteración

Patrones de la programación estructurada
Patrones de la programación estructurada

Böhm y Jacopini probaron dos años antes que todos los programas pueden ser construidos por solo tres estructuras: secuencia, selección e iteración. Dijkstra ya conocía estas tres estructuras y descubrió que estas mismas son las necesarias para hacer que cualquier parte del programa sea probado. Es aquí donde se formaliza el paradigma de programación estructurada.

Edsger nos indica que es una mala práctica usar GOTO y sugiere usar mejor las siguientes estructuras de control:

  • If, then, else (selección)
  • do, while, until (iteración o repetición)

Descomposición de pequeñas unidades fáciles de probar

Hoy en día la mayoría de los lenguajes de programación utilizan la programación estructurada, JavaScript utiliza este tipo de programación. El ejemplo más sencillo son las condiciones if.

const EDAD_MINIMA = 18;
if (edad >= EDAD_MINIMA) {
	// hacer algo porque es mayor que 18
} else {
	// Hacer otra cosa en caso contraio
}

Y si lo aislamos en una función, tenemos una descomposición de funcionalidades o unidades que pueden ser probadas con mayor facilidad. En la siguiente sección veremos la importancia de tener una unidad completamente probable

const EDAD_MINIMA = 18;
function esMayorEdad(edad) {
  if (edad >= EDAD_MINIMA) {
     return true;
  } else {
     return false;
  }
}

Con esta condición tenemos un control directo de lo que puede suceder si la edad es mayor o igual a 18, y también en el caso de que la edad sea menor.

Tampoco seamos tan estrictos, seguro que la sentencia GOTO tiene sus méritos y tal vez era muy eficiente en algunos casos, pero pienso que para evitar malos usos que probablemente causaban desastres, Dijkstra recomendó dejar de usar GOTO.

Pruebas, divide y vencerás

La programación estructurada nos permite aplicar la filosofía de “divide y vencerás”, porque nos permite crear pruebas de pequeñas unidades, hasta tener todo el programa cubierto. La solución matemática de Wybe Dijkstra nunca se construyo, precisamente por su dificulta de implementación. Y lamentablemente en nuestros días aún existen programadores que no creen que las pruebas formales sirven para crear software de alta calidad.

Y digo crear, porque verificar el correcto funcionamiento después de crear, no es más que una simple medición y se pierde la oportunidad de reducir tiempo y dinero.

Método científico, experimentos e impirismo

Método científico, experimentos y pruebas
Método científico, experimentos y pruebas, por ThisIsEngineering Raeng en unsplash

La buena noticia es que el método matemático no es la única forma de verificar nuestro código, también tenemos el método científico. El cual no puede probar que las cosas sean absolutamente correctas desde el punto de vista matemático. Lo que si se puede hacer es crear experimentos y obtener resultados suficientes para verificar que nuestras teorías funcionan. Dado que nuestras teorías funcionan sobre estos experimentos, entonces concluimos que son lo suficientemente “correctas” para nuestros propósitos de validación.

Si la teoría es fácilmente validada como falsa, entonces es momento de modificarla o cambiarla. Así es el método científico y así es como actualmente se hacen las pruebas:

Primero establecemos nuestra teoría (escribimos la prueba), después construimos los experimentos (escribimos código de producción) y finalmente verificamos (corremos la prueba) y repetimos este ciclo hasta tener evidencia suficiente.

¿Esto no te suena a una práctica ágil actual llamada TDD?

Las pruebas muestran la presencia, no la ausencia, de defectos

Edsger Wybe Dijkstra dijo “Las pruebas muestran la presencia, no la ausencia, de defectos”. Ósea, un programa puede ser probado incorrecto mediante pruebas, pero no puede ser probado correcto. Todo lo que podemos hacer con nuestras pruebas es validar que nuestro programa funciona lo suficiente bien para nuestros objetivos. Pero nunca podemos estar cien por ciento seguros de la ausencia de defectos.

Si nunca podemos estar cien por ciento seguros que nuestro código es correcto, aun con sus pruebas, ¿Qué nos hace pensar que sin pruebas entregamos un programa con la suficiente validez para afirmar que no se comete conscientemente alguna negligencia?

El control directo

La programación estructurada nos enseña sobre el control directo, es decir, controlar el flujo secuencial de las operaciones a través de las estructuras de control, sin descuidar la recomendación de Wybe Dijkstra sobre GOTO. Esta recomendación también es aplicable a sentencias que cambian drásticamente el flujo normal de las operaciones, por ejemplo un break dentro de un ciclo for anidado, ese break rompe el control directo porque complica abruptamente el entendimiento del algoritmo. Tampoco seamos puristas, seguro habrá casos que necesites de estas sentencias, pero de primera instancia, trata de evitarlas.

En conclusión, el paradigma de programación estructurada nos enseña:

El control directo, claro y explicito de lo que hace un pedazo de código

Paradigma de programación orientada a objetos

¿Surgido de funciones?

El paradigma de programación orientada a objetos se descubrió en 1966 por Ole Johan Dahl y Kristen Nygaard cuando desarrollaban simula 67. Dos años antes de la programación estructurada y su adopción por la comunidad de programadores fue tiempo después. En 1967 se lanzó Simula 67, Simula fue el primer lenguaje de programación orientado a objetos,  básicamente le agregó clases y objetos a ALGOL, inicialmente Simula iba a ser una especie de extensión de ALGOL.

Durante el desarrollo de Simula, se observó que la ejecución de una función de ALGOL necesita de ciertos datos, los cuales se podían mover a una estructura de árbol. Esta estructura de árbol es un Heap.

El heap permitía declarar variables locales de la función que pueden existir incluso después de que la función regrese un valor. ¿Esto último no les suena a lo que es closure en JavaScript?

La función padre se convierte en un constructor, las variables locales se convierten en las propiedades y las funciones hijas (anidadas) en sus métodos. De hecho este patrón es aún muy utilizado por Javacript para crear módulos y usar herencia funcional. También esto describe como funcionan las clases en Javascript, por detrás son funciones.

Esparcimiento del polimorfismo

Todo esto ayudó mucho a que se implementará el polimorfismo en los lenguajes de programación orientados a objetos. Ole Johan Dahl y Kristen Nygaard inventaron la notación:

objeto.funcion(parametro)

La ejecución de funcion que pertenece a objeto, pero más importante, le pasamos un mensaje a través de parámetros desde la primera parte del código a la segunda parte localizada en un objeto diferente.

La biología molecular y el paso de mensajes

Paso de mensajes entre células
Paso de mensajes entre células, Imagen modificada de “Signaling molecules and cellular receptors: Figure 1,” por OpenStax College, Biology (CC BY 3.0).

Tiempo después se creó Smalltalk, un lenguaje de programación orientado a objetos mucho más sofisticado y moderno, a cargo de este proyecto estaba Alan Kay. A esta persona se le atribuye la definición formal de la programación orientada a objetos.

La principal influencia en la programación orientada objetos de Alan Kay fue la biología, él es licenciado en biología. Aunque es obvio que fue influenciado por Simula, la influencia de LISP (lenguaje de programación funcional) no es tan obvia.

Desde un inicio él pensaba en los objetos como células interconectadas en una red, de la cual se podrían comunicar mediante mensajes.

Alan Kay comentó lo siguiente:

Lamento que hace tiempo haya acuñado el término Objetos para la programación porque hizo que las personas se enfocaran en la parte menos importante. La gran idea es “Envío de mensajes“.

Alan Kay

Mi Ingles es malo así que pueden revisar el texto original aquí.

Mejor composición de objetos sobre herencia de clases

Smalltalk permitió también la creación de Self, creado en Xerox Parc y luego migrado a Sun Microsystems Labs. Se dice que Self es una evolución de smalltalk.

En este lenguaje de programación se introdujo la idea de prototipos, eliminando la utilización de clases para crear objetos, este lenguaje utiliza los objetos mismos para permitir que un objeto reutilice las funcionalidades de otro.

Self es un lenguaje rápido y en general se le conoce por su gran rendimiento, self hizo un buen trabajo en sistemas de recolección de basura y también utilizaba una maquina virtual para administrar su ejecución y memoria.

La máquina virtual Java HotSpot se pudo crear gracias a Self. Lars Bak uno de los últimos contribuidores de Self, se encargó de la creación del motor de Javascript V8. Debido a la influencia de Self tenemos hoy en día el motor de JavaScript V8, el cual lo utiliza node.js, mongoDB y Google Chrome internamente.

Self seguía una de las recomendaciones del libro Design Patterns: Elements of Reusable Object-Oriented Software, mucho antes de que saliera publica esta recomendación:

Mejor composición de objetos a herencia de clases.

Design Patterns: Elements of Reusable Object-Oriented Software

Ejemplo

Actualmente Javascript utiliza prototipos para la reutilización de código, se podría decir que usa composición, en lugar de herencia. Veamos un ejemplo:

const persona = {
    saludar () {
      return 'Hola'
    }
};
// se crea un programador con el prototipo igual al objeto persona
const programador = Object.create(persona);
programador.programar  = () => 'if true';
const saludo = programador.saludar();
const codigo = programador.programar();
console.log(saludo); // 'Hola'
console.log(codigo); // 'if true'

El objeto programador se basa en el prototipo de `persona`. No hereda, solo reutiliza directamente la funcionalidad de `persona`.

JavaScript surge poquito después de JAVA, en el mismo año. JavaScript tomo influencias de Self, y a su vez Self fue influido por smalltalk.

La sintaxis de clases actuales en Javascript no es más que una fachada, bueno un poco más exacto son una evolución de las funciones constructoras, pero internamente, su base, son las funciones y los prototipos.

La comunicación con el paso de mensajes

Como ya vimos, el origen de la programación orientada objetos tiene su origen en las funciones, y la idea principal siempre ha sido la comunicación entre objetos a través del paso de mensajes. Podemos decir que La programación orientada a objetos nos habla del paso de mensajes como pieza clave para la comunicación de objetos, por ejemplo, cuando un método de un objeto invoca el método de otro.

objeto.funcion(parametro);

En conclusión, el paradigma de programación orientado a objetos, nos enseña:

El paso de mensajes para la comunicación entre objetos

Paradigma de programación funcional

Cálculo lambda

Imagen tomada de https://www.slideshare.net/FASTPresentations/introduction-to-lambda-calculus-using-smalltalk-by-facundo-javier-gelatti

La programación funcional es el paradigma de programación más viejo, de hecho su descubrimiento fue mucho antes de la programación para computadoras, fue descubierto en 1936 por Alonzo Church, cuando invento el cálculo lambda, base del mismo problema a resolver de su alumno Alan Turing.

Como dato curioso el símbolo del cálculo lambda es:

λ

El primer lenguaje basado en programación funcional fue LISP, creado por John McCarthy. Como vimos anteriormente, Alan Kay también tomo influencias de LISP para crear Smalltalk, con esto podemos comprobar que los paradigmas de programación pueden estar unidos y su relación entre ellos surge de la idea de como resolver problemas de manera más eficiente, no están peleados, ni separados, buscan el mismo objetivo y de alguna manera evolucionan en conjunto.

La base del cálculo lambda es la inmutabilidad, más adelante revisaremos este concepto.

Similitudes con los paradigmas OO y estructurada

Como vimos en el paradigma de programación estructurada, podemos descomponer nuestros programas en unidades más pequeñas llamadas procedimientos o funciones. Dado que la programación funcional es el paradigma más viejo, podemos decir que el paradigma de programación estructurada también se apoya en la programación funcional.

Ahora bien, si analizamos un poco la notación objeto.funcion(x) que vimos en la sección del paradigma de programación orientada a objetos, no es muy diferente de funcion(objeto, parametros), estas dos lineas de abajo son iguales, la idea fundamental es el paso de mensajes, como nos indica Alan Kay.

objeto.funcion(parametro);
funcion(objeto, parametro);

Smalltalk usa el “El Modelo Actor”, el cual dice que los actores se comunican entre ellos a través de mensajes.

Por otro lado tenemos a LISP, el cual tiene un “Modelo despachador de funciones” que actualmente le llamamos lenguaje funcional, estos modelos son idénticos, porque las funciones y métodos lo que hacen es enviar mensajes entre actores.

Un ejemplo de esto es cuando una función llama a otra función o cuando se invoca el método de un objeto, lo que sucede es que existen actores y se comunican entre ellos a través de mensajes.

De nuevo el paso de mensajes

Entonces podemos recalcar que la idea principal de la POO es el envío de mensajes y que no es muy diferente de la programación funcional, de hecho según lo que ya establecimos en las secciones anteriores, POO nació de una base funcional. Y aquí es importante remarcar lo que dijo Alan Kay Co-creador de SmallTalk:

Lamento que hace tiempo haya acuñado el término Objetos para la programación porque hizo que las personas se enfocaran en la parte menos importante. La gran idea es “Envío de mensajes“.

Alan Kay

A partir de los modelos de comunicación entre mensajes de Smalltalk y LISP, se creó Scheme.

Scheme tiene la bondad de usar Tail recursion y closure para obtener un lenguaje funcional, closure permite tener acceso a las variables de una función externa aun cuando esta ya haya regresado algún valor. Esto es el mismo principio que origino a la programación orientada a objetos a cargo de Ole Johan Dahl y Kristen Nygaard. ¿Recuerdan la pregunta de closure en Javascript?

Javascript usa mucho closure en su paradigma de programación funcional. JavaScript tomó influencias de Scheme, a su vez Scheme fue influido por LISP.

Sin efectos colaterales

La base del cálculo lambda es la inmutabilidad, por consiguiente, la inmutabilidad también es la base del paradigma de programación funcional.

Nosotros como programadores funcionales debemos seguir este principio y limitar las mutaciones de objetos lo más que se pueda para evitar efectos colaterales.

Repito, la idea principal de la programación funcional es la inmutabilidad, la cual te permite crear tus programas con menos errores al no producir efectos colaterales difíciles de controlar.

Como ejemplo, supongamos que tenemos un objeto persona y queremos “cambiar” el nombre, lo más obvio seria modificar la propiedad nombre directamente, pero que pasa si ese objeto es utilizado en otra parte y se espera que nombre sea “Jaime”, es por eso que en lugar de cambiar la propiedad nombre, solo creamos un nuevo objeto persona con diferente nombre, sin modificar el original.

function cambiarNombre(nombre, persona) {
  return {
    nombre: nombre,
    edad: persona.edad
  }
}
const jaime = { nombre: 'Jaime', edad: 30 };
const juan = cambiarNombre('Juan', jaime);
console.log(jaime); // { nombre: 'Jaime', edad: 30 }
console.log(juan); // { nombre: 'Juan', edad: 30 }

Aquí encontrarás más detalles sobre los principios fundamentales de programación funcional:

Introducción a programación funcional

Por último, el paradigma de programación funcional nos enseña:

Sin efectos colaterales, para una expresión clara y menos propensa a errores

Conclusión

Es importante destacar que si los tres paradigmas de programación fueron implementados entre los años 1958 con LISP (programación funcional) y Simula (programación Orientado a objetos) en 1966, y el descubrimiento del paradigma de programación estructurado en 1968, en solo un lapso de 10 años existió la innovación de los paradigmas de programación, y realmente nuevos paradigmas no han surgido, al menos que no sean basados en estos tres principales.

Ahora mismo ya han pasado más de 60 años, lo que nos dice de la importancia y la firmeza que tienen a pesar del tiempo transcurrido.

  • Paradigma de programación funcional (1958, ya implementado en un lenguaje de programación para computadoras, recordemos que fue descubierto en 1936)
  • Orientado objetos (1966)
  • Estructurada (1968)

La implementación de estos tres paradigmas desde el inicio en el interior de JavaScript han hecho que este lenguaje de programación tenga el éxito global de hoy en día. Y nos comprueba lo valioso de combinar los paradigmas al escribir nuestros programas.

JavaScript es en lenguaje de programación multiparadigma, por lo que se puede combinar los paradigmas para crear un código mucha más eficiente y expresivo usando:

  • El control directo, claro y explicito de lo que hace un pedazo de código
  • El paso de mensajes para la comunicación entre objetos
  • Sin efectos colaterales, para una expresión clara y menos propensa a errores

Referencias

https://en.wikipedia.org/wiki/Structured_programming

https://en.wikipedia.org/wiki/Structured_program_theorem

http://wiki.c2.com/?AlanKayOnMessaging

https://www.slideshare.net/FASTPresentations/introduction-to-lambda-calculus-using-smalltalk-by-facundo-javier-gelatti

Libro Clean architecture

Introducción a programación funcional

Introducción a programación funcional

Origen

El origen de la programación funcional data del año 1936, cuando un matemático llamado Alonzo Church necesitaba resolver un problema complejo, del cual no hablaremos aquí, pero Alonzo creó una solución, el cálculo lambda. De esta forma nació la programación funcional, incluso mucho antes de la primera computadora digital programable y de los primeros programas escritos en ensamblador.

La programación funcional es mucho más antigua que la programación estructurada y la programación orientada a objetos. Te recomiendo también revisar esta información sobre el paradigma de programación funcional.

Sin efectos colaterales

Todo lo que necesitas saber sobre programación funcional es que “No tiene efectos colaterales“, es decir, que sus elementos (funciones) son inmutables.

Lo anterior significa que una función no se mete en lo absoluto con datos que existen fuera de ella, si puede utilizar los datos enviados como parámetros, pero no debe modificarlos, todos los datos deben ser inmutables, ¿Por qué?, pues porque así hacemos las cosas más simples y con menos errores, más adelante tenemos un ejemplo. A este comportamiento se le llama puro.

Sin efectos colaterales nos permite entender todas las demás características de la programación funcional, por mencionar algunas principales:

  • Funciones puras
  • Inmutabilidad
  • Funciones de alto nivel
  • Funciones currificadas
  • Recursividad
  • Menos errores de programación porque no realiza efectos colaterales.

Toda función teniendo ciertos parámetros, cuando se ejecuta, obtendremos un resultado basado en esos parámetros, y si volvemos a utilizar los mismos parametros, entonces la función regresara el mismo valor. Esto es debido a que una función no depende de más datos externos que puedan ser modificados, así tendremos más seguridad y nuestro código se vuelve más entendible.

Javascript es un lenguaje de programación muy potente y multiparadigma, soporta el paradigma funcional y lo utilizaremos para nuestros ejemplos.

Funciones puras e inmutabilidad

Bueno, realmente ya explicamos de manera indirecta que es una función pura en los párrafos anteriores, pero veamos una definición formal. Una función pura es la que cumple con estas dos características:

  1. Siempre obtendremos el mismo resultado dado los mismos parámetros de entrada.
  2. No tiene ningún efecto colateral observable, no modifica el estado de los datos externos, por lo que todos los datos deben ser inmutables.

Un ejemplo de como cambiar el nombre de una objeto persona usando primero una función con efector colaterales:

function cambiarNombre(nombre) {
  persona.nombre = nombre;
}
const jaime = { nombre: 'Jaime', edad: 30 };
cambiarNombre('Juan')
console.log(jaime); // { nombre: 'Juan', edad: 30 }

En la anterior función notamos que se cambia objeto jaime, el cual supongamos que es parte del estado de nuestra aplicación, pero puede haber otras funciones que utilicen este objeto, por lo que se puede generar problemas si alguien más espera que la propiedad nombre del objeto siga siendo 'jaime'.

Ahora veamos la versión funcional de la función:

function cambiarNombre(nombre, persona) {
  return {
    nombre: nombre,
    edad: persona.edad
  }
}
const jaime = { nombre: 'Jaime', edad: 30 };
const juan = cambiarNombre('Juan', jaime);
console.log(jaime); // { nombre: 'Jaime', edad: 30 }
console.log(juan); // { nombre: 'Juan', edad: 30 }

En la versión funcional, cambiarNombre no modifica el objeto jaime, más bien crea un nuevo objeto con la misma edad que jaime y con la propiedad nombre igual a 'Juan', con esto evitamos efectos colaterales por si el objeto jaime es utilizado por otra función u otro programador.

Con esta función sin efecto colateral, nos damos cuenta de que los datos se manejan sin ser modificados, es decir, inmutables, los parámetros persona y nombre nunca fueron cambiados.

Funciones de alto nivel y currificadas

Una función de alto nivel es una función que implementa al menos una de las opciones siguientes:

  • Recibir como parámetro una o más funciones
  • Regresar como resultado una función

Un ejemplo muy común usado en nuestro navegador web es agregar escuchadores de eventos:

<button id="boton">Soy un botón</button>
const boton = document.querySelector('#boton');
boton.addEventListener('click', function () {
  alert('Click sobre el boton');
});

En el código pasamos como segundo parámetro del método addEventListener una función anónima (sin nombre) que mostrará un alerta al dar click sobre un botón con id igual a ‘botón’. Dado que pasamos por parámetro una función, entonces se dice que es una función de alto nivel.

Otro ejemplo de función de alto nivel lo podemos observar en los métodos de arreglos en Javascript, el código de abajo toma un arreglo de números y crea otro arreglo con los valores aumentados al doble.

See the Pen Funciones de alto nivel by Jaime Cervantes Velasco (@jaime_cervantes_ve) on CodePen.

La función map retorna un nuevo arreglo, no cambia el arreglo original, por lo que decimos que no existe un efecto colateral.

Las funciones currificadas son funciones de alto nivel que como resultado regresan otra función, de tal manera que el acto de currificar es convertir una función de más de un parámetro en dos o más funciones que reciben parcialmente esos parámetros en dos o más invocaciones currificadas.

See the Pen Funciones de alto nivel y funciones currificadas by Jaime Cervantes Velasco (@jaime_cervantes_ve) on CodePen.

Las funciones flecha o arrow functions nos permiten acceder al contexto de los parámetros, es por eso que seguimos teniendo acceso al parámetro a de la primera invocación de summaryCurry. De esta manera cuando se les define un valor, una arrow function puede ver ese valor. Para lograr lo mismo sin funciones flecha se debe utilizar la variable arguments que existe como variable local dentro de todas las funciones en JavaScript. Para mantener las cosas simples, de momento no veremos como hacerlo con arguments.

Función recursiva

Para crear una función recursiva, primero se define un caso base, luego a través de la división del problema en pedazos más pequeños se encuentra un patrón, este patrón llamado caso recursivo se repite muchas veces, es aquí donde la función se llama así misma y acumula los resultados, la ejecución se detiene hasta llegar a su caso base.

  1. El caso base, el cual permite detener la ejecución de subsecuentes invocaciones de la función recursiva.
  2. El caso recursivo, el cual permite que una función se llame a sí misma hasta llegar al caso base.

El factorial de un número positivo es la multiplicación de ese número por el número inmediato menor y así sucesivamente hasta llegar al número 1, su notación es n!, donde n es un número positivo. Por ejemplo el factorial de 5 es 120, 5! = 5 x 4 x 3 x 2 x 1 = 120.

// caso base:
1! = 1 = 1
// caso recursivo, ejemplos:
2! = 2 x 1 = 2 x 1!
3! = 3 x 2 x 1 = 3 x 2!
4! = 4 x 3 x 2 x 1 = 4 x 3!
5! = 5 x 4 x 3 x 2 x 1 = 5 x 4!

Con estos datos, podemos crear nuestra formula factorial(n) = n * factorial(n-1), lo cual seria nuestro caso recursivo, pero debemos de añadir nuestro caso base para que se detenga, cuando n=1 debemos obtener como resultado 1.

Veamos como quedaría nuestra función recursiva en javascript:

See the Pen Funciones recursivas by Jaime Cervantes Velasco (@jaime_cervantes_ve) on CodePen.

Con esto cubrimos las cualidades principales de la programación funcional, pero recuerda, lo más importante es que NO existen efectos colaterales.

Compartir en redes sociales desde tu página web en Android

Compartir en redes sociales desde tu página web en Android

En la versión de Google Chrome 61 para Android se agregó esta interesante funcionalidad que te permite compartir información en redes sociales utilizando las aplicaciones nativas de tu smartphone.

¿Cómo se usa?

Para poder utilzar esta Web share API, necesitas:

  • Chrome 61 o una versión mayor en Android
  • Que la aplicación o sitio web funcione sobre el protocolo seguro HTTPS

Aqui esta un ejemplo, pruebalo en tu android con Chrome 61 o una versión mayor, de lo contrario no funcionara. Esta funcionalidad no la tiene tu navegador de escritorio.

Al presionar el boton grande “Compartir” sale este cuadro de dialogo nativo de android:

¿Qué debes tomar en cuenta?

Esta funcionalidad solo se puede ejecutar con la accion del usuario, es decir, solo se puede invocar en controladores de eventos como click.

Solo se puede ejectar en Android y en el navegador web Chrome >= 61

En el ejemplo anterior, primero nos aseguramos que el navegador soporta la funcionalidad con navigator.share.

Patrones de diseño en Javascript, Singleton y Factory

Patrones de diseño en Javascript, Singleton y Factory

¿Qué es un patrón de diseño?

Cada patrón describe un problema que ocurre una y otra vez en nuestro entorno, y luego describe el núcleo de la solución a ese problema, de tal manera que puedes utilizar esta solución millones de veces, sin nunca hacerlo de la misma forma dos veces.

  • Arquitecto Christopher Alexander

La definición del patrón de diseño no viene del desarrollo de software, sino de la arquitectura del habitat humano.

Tanto la arquitectura del hábitat humano como el desarrollo de software tienen muchas similitudes, esto es porque como seres humanos somos parte del mundo y de la naturaleza. Por lo tanto el desarrollo de software busca siempre representar el mundo real,  de hecho la programación de cualquier aplicación siempre se usa para solucionar problemas reales de nuestro entorno.

Entonces podemos comprender que un patrón de diseño permite ofrecer una solución a problemas comunes en el diseño de software, describe la solución a problemas que se repiten muchas veces y que son muy similares entre ellos, en concreto, esta similitud permite diseñar una solución para un conjunto de problemas parecidos.

Los patrones de diseño actuales fueron popularizados por el libro Design patterns: elements of reusable object-oriented softwarede los autores conocidos como GoF(Gang of Four):

  • Erich Gamma
  • Richard Helm
  • Ralph Johnson
  • John Vlissides

En este libro se describen 23 patrones de diseño que desde 1995 hasta nuestros días siguen en uso con un gran impacto en el desarrollo de software. Esto no quiere decir que estos patrones no fueron utilizados mucho antes de la publicación del libro.

Este artículo será el primero de una serie, que nos permitirá entender como se pueden implementar muchos de estos patrones de diseño en el lenguaje de programación Javascript y no solo los descritos por GoF, también se explicara otros patrones de diseño útiles en Javascript.

El primer patrón de diseño es el Patron Singleton.

Patrón Singleton

Este patrón nos permite tener una solo instancia de un tipo de objeto, porque no es necesario crear varias instancias nuevas cuando una solo instancia puede encargarse del mismo trabajo en toda la aplicación. Al solo tener una instancia, centralizamos la información, funcionalidad y mejoramos el rendimiento disminuyendo el uso de memoria.

En Javascript es muy fácil utilizar este patrón, tan fácil como crear un objeto literal, por ejemplo supongamos que tenemos una configuración para el número de caracteres y palabras que se muestran en un sitio web optimizado para buscadores:

let configSEO = {
    nombre: 'Pensemosweb',
    seo: {
      descripcion: {
        limiteCaracteres: 155,
        limitePalabras: 23
      },
      titulo: {
        limiteCaracteres: 70,
        limitePalabras: 9
      }
    }
};

Un simple objeto de configuración es un singleton, pues en toda la app se va a hacer referencia al objeto configSEO y nunca se va a crear más nuevos objetos porque se puede extender esa configuración añadiendo más propiedades.

Ahora supongamos que necesitamos utilizar objeto donde existan funciones de configuración y métodos, además de una interfaz para obtener la instancia, tomando el mismo ejemplo de configSEO ahora vamos a utilizar funciones anidadas y closure (o cierres), esto ultimo permite a una función tener acceso a las funciones y variables definidas en el ámbito en que esta función también es definida.

La función anónima principal se invoca inmediatamente con la notacion (function() {}()) y recibe un parámetro el, el cual guarda la referencia al elemento del DOM con id resultado. Este parámetro se lo pasamos a la función inmediata a través de la variable global elem.

Debido a que definimos instancia dentro de la función principal, las funciones anidadas definidas más adelante tienen acceso a esa variable instancia que guardara nuestro singleton cuando invoquemos la función configSEO().

Además metodoPublico()y privada() tienen acceso a las variables instancia y el.

Si nos fijamos en la línea 48, elem.append(conf1 === conf2), comparamos igualdad de referencia, conf1y conf2son el mismo objeto, como singleton, solo trabajamos con una instancia.

También podemos hacer uso de otro patrón de diseño llamado factory, el cual veremos más a detalle en otro post, por el momento solo ten en cuenta que tendremos una función que fabricara singletons.

Podemos notar que con una sola función, podemos acceder a los singletons creados anteriormente y podemos agregar más si queremos. Este tipo de patrón factory de singletons es muy utilizado en frameworks como AngularJS. Aquí abajo un ejemplo del singleton configSEO y el factor y usando AngularJS.

es_MXES_MX