¿Es Javascript un lenguaje de programación funcional?

34
  • ¿Es Javascript un lenguaje funcional? Sé que tiene objetos y también puedes hacer POO con él, pero ¿es también un lenguaje funcional? ¿Se puede usar de esa manera?
  • Usted sabe cómo OOP se convirtió / parece la próxima evolución en la programación, ¿eso significa que 'Programación funcional' es la próxima evolución? más para los moderadores que los contribuyentes;)).
  • Aprendo mejor a través de ejemplos, tal vez alguien podría mostrar que realizo la misma tarea de una manera OOP y luego de una manera de Programación Funcional para que yo entienda y compare lo que hace / es la programación funcional.

Realmente no entiendo completamente 'Programación funcional' para ser honesto: P Así que comparar Javascript con la programación funcional puede ser totalmente incorrecto.

Para poner la programación funcional en términos simples: ¿es simplemente el beneficio de la abstracción mediante funciones anónimas?

¿O es así de simple? De una manera simple, OOP es el beneficio de la abstracción a través de objetos, pero creo que eso es un poco demasiado simplista para describir OOP.

¿Es este un buen ejemplo de programación funcional? ...

Javascript OOP Ejemplo:

// sum some numbers
function Number( v )
{ 
  this.val = v;
}

Number.prototype.add( /*Number*/ n2 )
{
    this.val += n2.val;
}

Ejemplo de programación funcional:

function forEach(array, action) 
{
   for (var i = 0; i < array.length; i++)
       action(array[i]);
}  

function add(array)
{
    var i=0;
    forEach(array, function(n)
    {
        i += n;
    });
    return i;
}

var res = add([1,9]);
Marek
fuente
Depende de la definición de "lenguaje de programación funcional". En un sentido amplio, puede entenderse como la capacidad de construir valores funcionales con valores cerrados, es decir, tener una construcción "lambda" (en el sentido del cálculo lambda), y luego Javascript cumple con los requisitos.
Basile Starynkevitch
2
Or is that way too simple?Yeap, lo es. Las funciones anónimas a veces se asocian con lenguajes funcionales y lenguajes de paradigmas múltiples que favorecen la programación funcional, pero no son una característica única de los lenguajes funcionales. Pero si usted los ve como una implementación de λ-cálculo, así que son una parte fundamental de la programación funcional, el ser principal punto de que no es tan simple :)
Yannis
El diseño de Javascript impide que las implementaciones puedan hacer una optimización de cola. En mis libros eso solo evita que se etiquete como funcional.
dan_waterworth
I know it has objects & you can do OOP with it alsoNo puedes. Es una programación basada en prototipos que elimina la distinción entre clase y objeto. Personalmente, considero que la programación basada en prototipos tiene fallas en este nivel básico.
RokL
Javascript no es un lenguaje funcional, seguro que tiene características funcionales, pero también el viejo imperativo C, de hecho, cada lenguaje tiene las características funcionales básicas. Un lenguaje funcional puro, como Haskell, ML, etc., es un lenguaje declarativo, no imperativo.
ALXGTV

Respuestas:

72

¿Es Javascript un lenguaje funcional? Sé que tiene objetos y también puedes hacer POO con él, pero ¿es también un lenguaje funcional? ¿Se puede usar de esa manera?

A veces, la gente dirá programación funcional, cuando lo que quieren decir es programación imperativa o programación procesal . Estrictamente hablando, la programación funcional es:

En informática, la programación funcional es un paradigma de programación que trata la computación como la evaluación de funciones matemáticas y evita el estado y los datos mutables . Enfatiza la aplicación de funciones, en contraste con el estilo de programación imperativo, que enfatiza los cambios de estado. La programación funcional tiene sus raíces en el cálculo lambda, un sistema formal desarrollado en la década de 1930 para investigar la definición de funciones, la aplicación de funciones y la recursividad. Muchos lenguajes de programación funcionales pueden verse como elaboraciones sobre el cálculo lambda.

Aunque Javascript no es ampliamente conocido o utilizado como lenguaje funcional, tiene algunos elementos funcionales :

JavaScript tiene mucho en común con Scheme. Es un lenguaje dinámico. Tiene un tipo de datos flexible (matrices) que puede simular fácilmente expresiones s. Y lo más importante, las funciones son lambdas.

Scheme es un dialecto de Lisp , y probablemente sea uno de los lenguajes en los que la mayoría de los programadores piensan cuando hablan sobre programación funcional. Cuando se trata de la orientación a objetos , Javascript es un lenguaje orientado a objetos. Pero su orientación a objetos está basada en prototipos :

La programación basada en prototipos es un estilo de programación orientada a objetos en el que las clases no están presentes y la reutilización del comportamiento (conocida como herencia en lenguajes basados ​​en clases) se realiza a través de un proceso de clonación de objetos existentes que sirven como prototipos. Este modelo también se puede conocer como programación sin clases, orientada a prototipos o basada en instancias. La delegación es la característica del lenguaje que admite la programación basada en prototipos.

Entonces, aunque Javascript está orientado a objetos, no sigue el modelo basado en clases más común , al igual que los lenguajes como C ++, C #, Java y PHP (y muchos otros). Y, por supuesto, también es un lenguaje imperativo, lo que lleva a la confusión con la programación funcional que describí anteriormente.

Sabes cómo OOP se convirtió / parece la próxima evolución en la programación, ¿eso significa que la 'programación funcional' es la próxima evolución?

La orientación a objetos y la programación funcional son solo dos de los muchos paradigmas de programación diferentes , son diferentes estilos de programación con diferentes conceptos y abstracciones. La palabra clave es "diferente". No hay un solo paradigma que sea mejor que otros o más evolucionado que otros, todos y cada uno se ajusta mejor a algunos escenarios que los demás. Algunos pueden ser bastante más antiguos en origen que otros, pero en términos evolutivos eso los hace mejores, ya que han sobrevivido por más tiempo. Pero esa no es una forma muy inteligente de verlo.

Javascript, como he descrito anteriormente y como un buen número de otros idiomas, es multi-paradigma. Que le permite escribir código en imperativo objeto, basado prototipo orientado y estilo funcional. Le toca a usted para elegir la que mejor se ajusta lo que estamos construyendo. También hay varios idiomas paradigma individuales, el ejemplo canónico de ser Java, que sólo permite objeto basado clase orientada a la programación 1 .

Usted realmente debe resistir cualquier tentación de lenguajes y paradigmas como declaraciones de la manera de tratar. Hay una gran cantidad de basura, escrita principalmente por fanboys / fangirls o gente de marketing, con poco (si es que hay) conocimiento y comprensión de la programación. Términos como "mejor", "más evolucionado", etc, simplemente no se aplican.

Aprendo mejor a través de ejemplos, tal vez alguien podría mostrar que realizo la misma tarea de una manera OOP y luego de una manera de Programación Funcional para que yo entienda y compare lo que hace / es la programación funcional.

Esa sería una forma terrible de aprender. La orientación funcional y de objetos son estilos bastante diferentes, y cualquier ejemplo que no sean terriblemente simples no encajaría en uno u otro estilo.

1 Pero últimamente intenta expandir su alcance a la programación genérica, veamos cómo funciona.


En conclusión:

  • Concéntrese en aprender Javascript, es un lenguaje hermoso y extremadamente útil. Aprende el idioma, no el bombo.
  • Unos cuantos paradigmas diferentes, todos igualmente útiles. Depende de usted elegir cuál prefiere y cuál se adapta mejor a lo que esté construyendo.
  • Si desea aprender programación funcional, elija un lenguaje más adecuado, como Scheme o Clojure . Pero primero deberá comprender los conceptos matemáticos involucrados.
  • Investigue un poco antes de preguntar. La mayoría de sus preguntas son respondidas por los artículos relevantes de Wikipedia. Saber cómo investigar y cómo preguntar es una habilidad extremadamente importante para cualquier programador.
Yannis
fuente
55
+1 Gran respuesta. Debido a la forma en que se estructura la educación en programación, los nuevos programadores parecen pensar que los paradigmas son exclusivos y discretos, pero no lo son. Intente escribir código OOP que aproveche los conceptos funcionales cuando tenga sentido hacerlo. La programación basada en eventos es un paradigma, pero los aspectos de EDP influyen ciertamente en cada interfaz gráfica de usuario y programa web. El polimorfismo , una característica central de OOP, es una programación realmente genérica. Nombrar estas ideas nos ayuda a conceptualizar una buena programación, pero no debe usar una para excluir a otras.
kojiro
Aunque la pregunta original y su respuesta están describiendo Javascript y su relación con la programación funcional, creo que su respuesta es una de las mejores comparaciones entre OO y la programación funcional que he visto. Bien hecho.
AnotherDeveloper
"Esa sería una forma terrible de aprender". Acabo de terminar de leer este libro que presenta un problema y lo resuelve con una variedad de paradigmas, incluidos los estilos OOP y FP: github.com/crista/exercises-in-programming-style . ¡Aprendí mucho de eso!
Nick
@ Nick Eso sólo puede describirte lo que las miradas como paradigma y cómo funciona, pero no le dice por qué , lo que podría decirse que es el aspecto más importante. Pero debe aprender cómo antes de saber por qué :) a veces olvidamos que estas cosas son un proceso.
Matthew Brent
8

Javascript puede usarse como lenguaje funcional, de hecho lo hace bastante bien. Es posible implementar mónadas con soporte para una construcción lambda, etc. No es exclusivamente un lenguaje funcional, ya que también tiene muchas características orientadas a objetos, pero se puede usar de esa manera. En realidad, encuentro que usar Javascript como lenguaje funcional es una excelente manera de usarlo. (Ejemplo jQuery y underscore.js)

Zachary K
fuente
bueno y conciso! Convino en que la programación funcional es a menudo la forma más fácil de hacer algo en js.
bunglestink
Aún más interesante que las mónadas, puede implementar flechas es JS ( cs.umd.edu/projects/PL/arrowlets ). Ahora, en cuanto a por qué alguien querría flechas en JavaScript, esa es una pregunta abierta. Pero puede hacerse.
rtperson
Admitiré que no entiendo lo suficiente sobre las flechas para saber si serán útiles. Pero estoy trabajando en un Libro sobre mónadas en Javascript y puedo agregar un capítulo sobre Flechas ( shop.oreilly.com/product/0636920023890.do )
Zachary K
6

La evolución normalmente significa un cambio incremental . OOP no es una adición incremental a la programación de procedimientos; de hecho, es completamente ortogonal a un modelo de programación subyacente y se puede combinar con cualquiera de ellos. La programación funcional no es una adición incremental a procedimientos, OOP o lo que sea; es una base alternativa para expresar principios informáticos fundamentales, y en realidad es la primera base de este tipo formulada, mucho antes de que aparecieran las primeras computadoras. Es importante comprender que todos estos sistemas fundamentales son equivalentes (es decir, uno se puede expresar en términos de otro).

Para comprender el enfoque funcional, primero deberá obtener las matemáticas básicas . Si desea tener una idea de lo que significa codificar en un estilo funcional en Javascript, comience a usar jQuery .

SK-logic
fuente
2

No.

JavaScript es un lenguaje orientado a objetos en primer lugar.

Eso no quiere decir que no pueda escribir programas JavaScript en un estilo funcional, ya que puede adoptar un estilo funcional en cualquier lenguaje completo de Turing si se esfuerza lo suficiente. Puede hacer programación funcional en ensamblador si lo desea. Pero esto no hace que todos los idiomas funcionen. También podría llamar a Haskell imperativo, o Java, un lenguaje de programación lógico: si adoptara este enfoque, los términos pronto no tendrían sentido.

En mi opinión, la forma de clasificar un idioma en el paradigma apropiado es considerar:

  • ¿Cuál es el estilo dominante habilitado por las construcciones del lenguaje (claramente OOP para JavaScript, los lenguajes funcionales enfatizan las funciones y los valores de datos inmutables)
  • Qué paradigma es compatible con las bibliotecas principales del lenguaje (de nuevo claramente OOP para JavaScript)
  • Qué características están deshabilitadas o desalentadas en el lenguaje (los lenguajes funcionales desalientan o prohíben las variables mutables, que no es el caso para JavaScript)
  • Qué estilo de desarrollo prevalece en la comunidad de desarrolladores que usan el lenguaje (nuevamente, OOP es claramente prevalente en el mundo de JavaScript)

Personalmente, me parece bastante divertido que a mucha gente le guste decir que un idioma es "funcional" solo porque es un término moderno en este momento :-)

Si desea una perspectiva un poco larga pero entretenida sobre los paradigmas de programación a través de los años, vale la pena ver el video del tío Bob Martin "El último lenguaje de programación" . Para mí, la gran idea de esta charla fue que los paradigmas de programación se definen por las funciones que eliminan , no por las funciones que incorporan ...

mikera
fuente
What is the dominant style enabled by the language constructsTe reto a que intentes aplicar eso a Perl ... O a cualquier otro de tus puntos, realmente :)
yannis
2
Perl? Buen reto! Es algo así como un lenguaje ensamblador en el sentido de que puedes hackear casi cualquier paradigma que quieras juntos, pero en el uso común que he visto (scripting) se usa principalmente como un lenguaje imperativo / de procedimiento.
mikera
Bueno, oop también es bastante común. De manera perly, por supuesto. Y, funcional también , aunque poco común. perl es simplemente perl, no tiene sentido tratar de darle sentido :)
yannis
JavaScript es un poco más funcional que Java porque al menos tiene cierres y funciones de primera clase. Pero tiene razón, JavaScript es tan funcional como lo es C #.
Raynos
2

Javascript es prototípico primero, con capacidades funcionales, otorgadas por su uso de funciones como objetos de primera clase.

Esto significa que puede usar funciones como datos, lo que tiene el curioso efecto de reducir la necesidad de variables que mantengan el estado. Si descubres que estás buscando la declaración var, o estás usando una o más declaraciones "if", entonces te estás desviando de un estilo funcional.

Otra idiosincrasia notable del estilo funcional es que las funciones SOLO deberían devolver el resultado de su evaluación y no tener efectos secundarios en el estado fuera de su alcance:

// oops, this is producing a side effect
function sideEffecter(){//theres no input...        
    window.thingy = 'foo';
    // hey, this isn't returning anything!!!
} 

Los lenguajes funcionales no son destructivos, lo que significa que no mutan la entrada, sino que devuelven datos completamente nuevos basados ​​en la entrada. Vea este hilo: https://stackoverflow.com/questions/749084/jquery-map-vs-each

Los lenguajes funcionales también presentan muchos métodos en común, con nombres como "mapa", "doblar", "reducir" que procesan listas / colecciones. En JS, a diferencia de otros lenguajes, tenemos que crearlos manualmente: vea bibliotecas como underscore.js para ver algunos ejemplos, aunque la última implementación de JS tiene algunos de estos directamente listos.

Lo importante a tener en cuenta (IMO) es que, si bien JS puede utilizar algunos patrones funcionales, no siempre está bien equipado para ejecutarse en ese momento.

Tome iterar sobre una matriz, por ejemplo. Puede hacerlo utilizando un estilo funcional o las construcciones de bucle nativo, y en general el bucle es más eficiente. Tome este ejemplo: golpee con bucles de tamaño creciente y registre los tiempos de ejecución en diferentes navegadores (ya lo he hecho, pero he perdido los puntos de referencia, ¡lo siento!)

var test = ['foo', 'bar', 'baz'], removeFunc, removeLoop;

//(semi)functional style...
// to be really functional each condition in the ternary would be another function
removeFunc = function(src, trg) {
    return src.length === 0 ? 
        src : 
            src[0] === trg ? 
                src.slice(1) : 
                    [src[0]].concat(removeFunc(src.slice(1), trg));
};

//but this is faster
removeLoop = function(src, trg){
    var len = src.length, // using variables to represent state...
        i=0, 
        result = [];        
    while(i < n){
       if(src[i] !== trg){
          result.push(src[i]);
       }
       i = i+1;
    }
}

Además, si usa una construcción funcional para golpear bucles de tamaño considerable y no utiliza alguna forma de gestión de pila ad-hoc, podría inundar la pila (aunque, para ser justos, necesita una GRAN lista para que esto ocurra. ..). También debe tener en cuenta la combinación de las optimizaciones de variantes en cada navegador, aunque si está trabajando en un entorno Node.js, esto obviamente es más un objetivo fijo.

Eso no quiere decir que no deba usar construcciones funcionales en Javascript, solo tenga en cuenta las limitaciones en su implementación en relación con su entorno.

Aquí hay algunos enlaces que pueden ser de su interés:

Un buen capítulo sobre Programación funcional en Javascript del excelente "Eloquent Javascript"

El pequeño intrigante

un amigo mío escribió una biblioteca JS basada en Little Schemer

Un buen tutorial sobre Scheme que podría ayudarlo a comprender mejor FP

sunwukung
fuente