Una perspectiva histórica sobre paradigmas y lenguajes de programación
1943
- Colossus es el primer computador
digital programable
1948
- Se construyó el primer computador
usando la arquitectura Von Neumann - Los computadores se programan escribiendo programas en binario y luego en hexadecimal
~1950
- Los computadores se
programan usando Assembler - Copia Isomórfica de la
arquitectura Von Neuman
1957
- FORTRAN (imperativo)
- Diseñado por John Backus para IBM
- Una delgada abstracción sobre Assembler
1958
- LISP (funcional)
- Diseñado por John McCarthy
mientras enseñaba para MIT - Se apoya fuertemente en
el concepto matemático de función
1965
- Simula (OOP)
- Diseñado en el
Norwegian Computing Center
1970
- Scheme (dialecto de Lisp)
- Diseñado en MIT AI Lab
- Luego fue usado para enseñar programación
- Precursor de muchas de las características
que hoy asociamos con Programación Funcional
1972
- C (imperativo)
- Diseñado por Dennis Ritchie
mientras trabajaba en Bell Labs - Creado para hacer UNIX
- "Close to the hardware"
1973
- Actor Model
- Diseñado por Carl Hewitt
- Influenciado por Smalltalk
1977
- John Backus publica
"Can Programming be Liberated
from the von Neumann Style?"
1983
- C++ (OOP)
- Creado por Bjarne Stroustrup
- Inspirado en Simula
- "C + Objects"
1986
- Erlang (funcional)
- Creado en Ericsson
- Influenciado por el
modelo de actores
1990
- Haskell (funcional)
- Creado por miembros del
International Conference
on Functional Programming
1995
- JS (funcional)
- Influenciado por Scheme, Self y Java
- Primera versión fue hecha en 10 días
2004
- Scala (Haskell + Java)
- Creado por Martin Odersky para ser usado en su compañía Lightbend (antes llamada Typesafe)
2007
- El juego Call of Duty cambia C++ por Erlang para la programación de sus servicios de multiplayer online
- 30 millones de usuarios concurrentes
2014
- Java 8 sale, acercándo aún más
el lenguaje a la Programación Funcional
Programación Imperativa
Programa
- Serie de pasos
- Para cada paso no trivial se crea una función
- El valor de retorno de una función,
se convierte en el parámetro de otra - No hay restricciones: variables globales,
asignación de variables (mutación), etc.
Programación Funcional
Programa
- Serie de pasos
- Para cada paso no trivial se crea una función
- El valor de retorno de una función,
se convierte en el parámetro de otra - Existen restricciones: las funciones deben
ser puras; la información se concibe como
valores y no como variables
Programación Orientada a Objetos
Programa
- Modelamos Tipos de Datos
- Cada Tipo de Dato tiene
información y comportamiento - Cuando creamos una instancia
está se puede comunicar
con otros, a través de mensajes
La OOP es "Syntactic Sugar" para cualquier paradigma
// Nosotros vemos:
myFoo.something(myBar);
// myFoo es de tipo Foo
// myBar es de tipo Bar
// El compilador ve:
something(myFoo, myBar);
* * *
// Nosotros:
class Foo {
public T something(Bar myBar) {
// accedemos a los atributos: this.x
// this es el objeto sobre el que llamados el método
return ...
}
}
// El compilador
public T something(Foo this, Bar myBar) {
return ...
}
OOP
- No es inherentemente Imperativa o Funcional
- Es perfectamente combinable con ambas
Principios Funcionales
Funciones Puras
- Data In - Data Out
- Sin Side Effects
- No exceptions
Referential Transparency
- Si invocar una función foo con argumento a, retorna b entonces podemos cambiar todas las instancias de foo(a) por b, sin cambiar el significado del programa
- Sustitution Model: si hacemos estos cambios
en todo el programa, podemos garantizar lógicamente la correctitud de un programa
Ventajas
- Funciones son pequeñas
- Funciones son más fáciles de razonar
- Funciones son más fáciles de reutilizar
- Funciones son más fáciles de probar
En OOP los principios SOLID propenden por esas mismas ventajas
Usar funciones puras nos conduce a usar:
- First-Class Functions
- Anonymous Functions
- Closures
- Currying
- Recursion
- Lazy Evaluation
First Class Functions
- Puede usar funciones en los
mismos lugares que un valor - Puedo: pasar una función como parámetro,
retornar una función en una función, asignar
una función a una variable, definir una
función dentro de otra y ser invocada
Anonymous Functions
- Es engorroso tener que darle un nombre a funciones que van a ser usadas como parámetro, valores de retorno, declaración de una variable, etc.
Clousures
- Al definir una función anónima,
todas las variables que hayan sido
definidas dentro del mismo alcance,
son visibles dentro de la función
var foo = (function() {
var digits = ["cero", "uno", "dos",
"tres", "cuatro", "cinco", "seis",
"siete", "ocho", "nueve"];
return function(n) {
return digits[n];
}
}());
document.writeln(foo(3));
La función definida dentro de la función foo, "closes over" la variable digits
Currying
- Es una técnica que permite a partir
una función de n parámetros, crear
una nueva función de n-1 parámetros - Permite "quemar" el valor de un
parámetro de una función existente - Matemáticamente es muy útil porque
permite tratar todas las funciones
como funciones de un solo parámetro
Recursion
- Bullet One
- Bullet Two
- Bullet Three
Lazy Evaluation
- Si vamos a pasar una función como parámetro
no queremos que se evalúe inmediatamente, queremos poder llamarla controladamente - Se extiende a otros casos
¿Si los programas no tienen side-effects cómo interactúan con el mundo?
Mónadas
- Las Mónadas permiten encapsular
una unidad computacional y hacer uso
de Side Effects sin perder composicionabilidad
Los lenguajes funcionales que usan Tipos de Datos añaden otras características
Programación Funcional
no es un lenguaje, es un estilo de programación
Simplemente hay lenguajes que permiten ser funcional más o menos fácil
Java es un lenguaje que permite usar un estilo en su mayoría funcional
Una perspectiva histórica sobre paradigmas y lenguajes de programación
By Carlos Obregón
Una perspectiva histórica sobre paradigmas y lenguajes de programación
- 1,610