Pregunta

He estado trabajando con Node.js por un tiempo en una aplicación de chat (lo sé, muy original, pero pensé que sería un proyecto de aprendizaje bien). Underscore.js proporciona una gran cantidad de conceptos de programación funcionales que parecen interesantes, así que me gustaría entender cómo un programa funcional en JavaScript sería configuración.

Desde mi comprensión de la programación funcional (que puede estar equivocado), la idea es que los efectos secundarios EVITAR, que son, básicamente, tiene una función que actualiza otra variable fuera de la función así que algo como

var external;
function foo() {
   external = 'bar';
}
foo();

sería la creación de un efecto secundario, ¿correcto? Por lo tanto, como regla general, se quiere evitar molestar a las variables en el ámbito global.

Ok, así que ¿cómo funciona eso, cuando usted está tratando con objetos y lo que no? Por ejemplo, muchas veces, voy a tener un constructor y un método init que inicializa el objeto, así:

var Foo = function(initVars) {
   this.init(initVars);
}

Foo.prototype.init = function(initVars) {
   this.bar1 = initVars['bar1'];
   this.bar2 = initVars['bar2'];
   //....
}

var myFoo = new Foo({'bar1': '1', 'bar2': '2'});

Así que mi método init está causando intencionadamente efectos secundarios, pero lo que sería una forma funcional para manejar el mismo tipo de situación?

Además, si alguien me podría apuntar a un código fuente de Python o JavaScript de un programa que trata de ser lo más funcional posible, que sería también muy apreciada. Siento como si estuviera cerca de "hacerlo", pero no estoy muy allá. Principalmente estoy interesado en cómo funciona la programación funcional con el concepto tradicional de clases de programación orientada a objetos (o lo hace con la suya por algo diferente si ese es el caso).

¿Fue útil?

Solución

Se debe leer esta pregunta:

Javascript como lenguaje funcional

Hay un montón de enlaces útiles, incluyendo:

Ahora, para mi opinión. Mucha gente entienden mal JavaScript , posiblemente debido a su aspecto de sintaxis como la mayoría de otros lenguajes de programación (en Lisp / Haskell / OCaml aspecto totalmente diferente). JavaScript es no orientado a objetos, es en realidad un href="http://en.wikipedia.org/wiki/Prototype-based_programming" rel="nofollow noreferrer"> prototipo basado en el lenguaje . No tiene clases o la herencia clásica por lo que no debería realmente ser comparado con Java o C ++.

JavaScript puede ser mejor en comparación con un Lisp; que tiene cierres y funciones de primera clase. El uso de ellas puede crear otras técnicas de programación funcionales, tales como aplicación parcial ( currificación).

Tomemos un ejemplo (usando sys.puts de Node.js):

var external;
function foo() {
    external = Math.random() * 1000;
}
foo();

sys.puts(external);

Para deshacerse de los efectos secundarios globales, podemos envolverlo en un cierre:

(function() {
    var external;
    function foo() {
        external = Math.random() * 1000;
    }
    foo();

    sys.puts(external);
})();

Tenga en cuenta que en realidad no podemos hacer nada con external o foo fuera del alcance. Están completamente envuelto en su propio cierre, intocable.

Ahora, para deshacerse de la external efecto secundario:

(function() {
    function foo() {
        return Math.random() * 1000;
    }

    sys.puts(foo());
})();

Al final, el ejemplo no es puramente funcional porque no pueden sea. El uso de un número aleatorio lee desde el estado global (para obtener una semilla) y la impresión de que la consola es un efecto secundario.

También quiero señalar que la mezcla de la programación funcional con objetos está perfectamente bien. Tome esto, por ejemplo:

var Square = function(x, y, w, h) {
   this.x = x;
   this.y = y;
   this.w = w;
   this.h = h;
};

function getArea(square) {
    return square.w * square.h;
}

function sum(values) {
    var total = 0;

    values.forEach(function(value) {
        total += value;
    });

    return total;
}

sys.puts(sum([new Square(0, 0, 10, 10), new Square(5, 2, 30, 50), new Square(100, 40, 20, 19)].map(function(square) {
    return getArea(square);
})));

Como se puede ver, el uso de objetos en un lenguaje funcional puede estar muy bien. Algunos incluso tienen Lisps cosas llamadas listas de propiedades que pueden ser considerados como objetos.

El verdadero truco para el uso de objetos con un estilo funcional es para asegurarse de que no se basan en sus efectos secundarios, sino que los trata como inmutables. Una forma fácil es cada vez que desee cambiar una propiedad, basta con crear un nueva objeto con los nuevos detalles y pasar que uno a lo largo, en vez (este es el enfoque de uso frecuente en Clojure y Haskell).

Creo firmemente que los aspectos funcionales pueden ser muy útiles en JavaScript pero en última instancia, usted debe usar lo hace el código más legible y lo que funciona para usted.

Otros consejos

Hay que entender que la programación funcional y programación orientada a objetos son algo antitéticos entre sí. No es posible ser ambos puramente funcional y puramente orientado a objetos.

funcional de programación es todo acerca de los cálculos sin estado. programación orientada a objetos es todo acerca de las transiciones de estado. (Paraphasing este . Esperemos que no sea demasiado mal)

JavaScript está más orientado a objetos de lo que es funcional. Lo que significa que si usted desea programar en un estilo puramente funcional, que tiene que renunciar a gran parte de la lengua. Específicamente todas las piezas objeto de orientar.

Si usted está dispuesto a ser más pragmáticos de ello, hay algunas inspiraciones del mundo puramente funcional que se puede utilizar.

Trato de cumplir con las siguientes reglas:

funciones que realizan cálculos no debería estado alter. Y las funciones de ese estado alter no deben realizar cálculos. Además, las funciones de ese estado alter deben alterar lo menos posible el estado. El objetivo es tener un montón de pequeñas funciones que hacer solamente una cosa. Entonces, si hay que hacer algo grande, redacta un montón de pequeñas funciones para hacer lo que necesita.

Hay una serie de beneficios que pueden obtenerse de las siguientes reglas:

  1. La facilidad de reutilización. La función de un largo y más complejo, más especializada es también, y por lo tanto menos probable es que se puede reutilizar. La implicación inversa es que las funciones más cortos tienden a más genérico y por lo tanto más fácil de reutilización.

  2. La fiabilidad de código. Es más fácil razonar sobre la corrección del código si es menos compleja.

  3. Es más fácil de funciones de prueba cuando lo hacen una sola cosa. De esta manera hay menos casos especiales a prueba.

Actualización:

Incorporated sugerencia de hacer comentarios.

Actualización 2:

añadido algunos enlaces útiles.

Creo, http://documentcloud.github.com/underscore/ debe ser agradable apto para lo que necesita - proporciona la mayoría de las funciones importantes de orden superior para la programación funcional y no hace tiene funciones del lado del cliente para la manipulación DOM, que no es necesario para el lado del servidor. Aunque no tengo experiencia con ella.

Como nota al margen: En mi humilde opinión característica principal de la programación funcional es Referencial transparencia de una función - resultado de la función depende sólo de sus parámetros - la función no depende de cambios en otros objetos y no introduce ningún cambio, excepto su valor resultado. Esto hace que sea fácil de razonar sobre la corrección del programa y muy valiosa para la implementación de predecible multi-threading (si es pertinente). A pesar de JavaScript no es el idioma apuesta para FP - espero estructuras de datos inmutables a ser muy costosos en cuanto al rendimiento de uso

.

Así que 2 cosas que señalan,

  1. En el primer ejemplo la variable no sería una fuga en la zona global y es la forma en que se debe hacer, trate de no utilizar variables sin tener que hacerlos es decir, test = 'datos' podrían ocasionar que los datos se filtran a la área global.

  2. Su segundo ejemplo es correcta, así, Bar1 y bar2 sólo serían declaradas en el objeto de Foo.

Las cosas a tener en cuenta Trate de no abusar de prototipos ya que se aplica a todos los objetos que se crea, esto podría ser muy intensivo de la memoria en función de la complejidad de sus objetos son.

Si usted está buscando un marco de desarrollo de aplicaciones, echar un vistazo a ExtJs . Personalmente creo que encajaría perfectamente en el modelo que se está tratando de desarrollar en contra. Hemos de tener en cuenta cómo su modelo de licencia de obras antes de ser invertido mucho en ella.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top