Saltar al contenido

La Programación Funcional De Los Principios De Cada Imperativo Programador Debe Utilizar

A veces parece funcional a los programadores son totalmente diferentes de la raza. Incluso por el programador de normas, que parecen más friki que el resto. Ellos usan extraño términos, tales como “mónada”, “para la comprensión”, y “lambda.” Que el uso de los idiomas que no terminan de cada línea con un punto y coma. Y, no importa lo incómodo que los programadores de Java están en torno a los programadores de C++, ambos grupos pueden, al menos de acuerdo que Haskell es un poco raro.

XKCD 1270: Recursión de la Cola

Pero, ¿y si no eran los principios de la programación favorecido por su funcional-paradigma de idiomas que podría ser útil para el resto de nosotros? La verdad es que la programación funcional tiene mucho que ofrecer incluso a los desarrolladores acostumbrados a trabajar en lenguajes imperativos. De hecho, muchos de los principios de la programación funcional se están volviendo más y más frecuente en los lenguajes imperativos hoy (te estoy mirando a ti, Java 8).

¿Cómo puede funcionales de los principios de la programación me beneficia a mí?

Cada desarrollador quiere escribir bien, limpio, fácil de mantener, fácil de entender el código. La popularidad de la programación orientada a objetos, por ejemplo, surgió en parte de la escritura de código y el mantenimiento de los beneficios que siguió a partir de la forma en que el paradigma anima a los desarrolladores a organizar su código. Programación funcional ofrece herramientas y prácticas de su propio que puede hacer el código más modular en formas que la programación imperativa no puede. Código Modular conduce a un código que es más fácil de comprender, fácil de reutilizar, y más fácil de probar.

Usted puede pensar que estas herramientas como una especie de pegamento que está disponible cuando necesitamos conectar partes de nuestros programas juntos. La programación imperativa ofrece algunos tipos de pegamento; programación funcional ofrece a los demás. Tener más tipos de pegamento a nuestra disposición puede mejorar la estructura general del código que escribimos. En particular, las prácticas de la prefiriendo la inmutabilidad de más de mutabilidad, la escritura pura funciones, y la superación de los problemas de uso de recursividad cada uno puede servir como un nuevo tipo de pegamento con sus propios beneficios. La mejor parte? Estas son prácticas, no características del lenguaje, y están disponibles sin importar qué idioma código.

La inmutabilidad de

Muchos lenguajes de programación funcional fomentar la inmutabilidad, a menudo haciendo que los valores inmutables de forma predeterminada. La inmutabilidad se refiere a la prevención de estado de ser modificado. La mutación puede ocurrir en dos niveles: referencia de la mutación y el valor de la mutación. Referencia de la mutación ocurre cuando se asigna una nueva referencia a una variable existente:

var x = {foo: 'bar'}; var y = x; x = {foo: 'baz'}; console.log(x, y); // Imprime "{foo: 'baz'}, {foo: 'bar'}"

En este ejemplo, la referencia x fue mutado, pero el objeto se apunta a que no fue, por lo que el valor que señala y no ha cambiado.

Valor de la mutación ocurre cuando se modifica un objeto existente:

var x = {foo: 'bar'}; var y = x; x.foo = 'baz'; console.log(x, y); // Imprime "{foo: 'baz'}, {foo: 'baz'}"

Aquí, y aunque no fue directamente modificado, se está haciendo referencia al mismo objeto como x, y el valor de su foo propiedad ha cambiado.

La distinción entre referencia de la mutación y el valor de la mutación es una sutil, pero es importante entender. En muchos idiomas con tiempo de compilación de la inmutabilidad, la referencia de la inmutabilidad es fácil de añadir a su código, pero el valor de la inmutabilidad es más difícil. En Java, por ejemplo, usted puede declarar una referencia a ser la final, pero esto no impide que pueda cambiar el valor de la no-valores finales sobre el objeto al que se hace referencia, a menos que esos valores se denota también el final.

La inmutabilidad es un método de bajo costo para asegurar que su código está desacoplado. Esto permite que el desarrollador para controlar la forma de los objetos en el sistema se les permite ser cambiado. Esto puede ser muy útil, por ejemplo, en un programa multiproceso. Muchos (aunque no todos) de los errores y oscuro borde de los casos que el código de causa a no ser seguro para subprocesos surgir a causa de la mutación. Si los objetos y las referencias están bloqueados, entonces usted no tiene que preocuparse acerca de una condición de carrera donde dos hilos intentar sobrescribir un valor al mismo tiempo, o cuando el valor cambia inesperadamente entre las lecturas. También hace que el código sea más fácil visualmente de depuración. La persona que lee el código no necesita preocuparse acerca de cómo un determinado valor puede haber cambiado por fuentes fuera de los códigos que se está leyendo, ya que el valor no puede ser cambiado en absoluto. Estas son sólo algunas de las maneras en que la inmutabilidad puede hacer el código más seguro y más fácil a la razón acerca de.

La inmutabilidad tienen un costo. Dependiendo de las implementaciones de los objetos y qué idioma que está utilizando, con el fin de modificar un objeto inmutable, puede que necesite hacer un clon de la totalidad de su objeto, con los cambios que usted desea declarado en el momento en que el objeto es instanciado. Esto podría resultar en una gran cantidad de objetos se crean y luego se descarta, que pueden desencadenar la recolección de basura con más frecuencia. Algunos casos de uso, tales como el juego o el desarrollo de GUI, son un mal ajuste de la inmutabilidad por esta razón. Sin embargo, incluso en estos ambientes especializados, la inmutabilidad puede ser utilizado cuando corresponda, con el fin de beneficiarse de las garantías de seguridad que ofrece. A pesar de esta precaución, todavía es posible utilizar la inmutabilidad sin un costo de rendimiento si la estructura de los objetos correctamente y deliberado en el que las partes de los objetos son inmutables. Por ejemplo, los árboles o las listas enlazadas son mucho más fáciles de trabajar en una inmutable de la moda que son las tablas hash o arraylists.

La inmutabilidad de cambios en la manera de abordar los problemas en nuestro código. Cambia la forma en que pensamos acerca de las partes de nuestro código y nos anima a ponerlos juntos en más limpia, más segura para subprocesos maneras. Sin embargo, la inmutabilidad solo a veces, puede parecer como más de una obstaculización que una ayuda. Por suerte, es más fácil trabajar con cuando se utiliza en conjunto con otros funcional de los principios de la programación. Muchos de estos principios, como puro funciones, están habilitados por escrito inmutable código.

Puro Funciones

Es sin duda una sorpresa saber que la programación funcional se centra en las funciones. Sin embargo, no significa que la “función” de la forma de un imperativo programador significa “método” o “procedimiento”. Más bien, la “función” en este contexto se remonta a las funciones que hemos aprendido en la clase de matemáticas. Cosas como el buen ol’ f(x) = x + 1. Estas funciones son simples. Ellos toman un valor y devolver un resultado. Son predecibles y fiables. La mayoría de todo, sólo calcular su resultado. Programación funcional anima a escribir procedimientos después de la manera de las funciones encontradas en las matemáticas. Estos son los llamados puro funciones.

La característica más significativa de puro funciones, es que ellos no modificar cualquier estado. Esto incluye el estado de los argumentos aportados a la función, el estado global, o incluso del estado externo al propio programa. Funcional a los programadores como para decir que no pura funciones que realmente puede hacer todo lo que desea, y no hay manera de saber en el sitio de llamada que no habrá efectos secundarios en el sitio de llamada. Un ejemplo divertido es que al llamar no-puro función puede lanzar un misil en algún lugar. Ciertamente no es probable, pero ¿cómo se puede garantizar que llamar a algunos arbitrario procedimiento de no hacer esto sin investigar el código de ti mismo? Si la función es puro, entonces no se puede lanzar los misiles que, por definición.

Por supuesto, la función de pureza puede ser llevado demasiado lejos. Si el estado no se modifica, entonces un programa bien podría no haber sido correr a todos. Por lo tanto, pura funciones deben ser utilizados con cuidado, al igual que con la inmutabilidad.

XKCD 1312: Puro Funciones

Puro funciones vienen con muy pocos beneficios. Uno de los principales es una propiedad denominada transparencia referencial. Referentially transparente funciones puede, en teoría, la llamada sitio reemplazado con el resultado actual de invocar la función sin cambiar el comportamiento del programa en absoluto. Dicho de otra manera, referentially transparente de las funciones de garantía de un resultado, para un conjunto dado de insumos. f(x) = x + 1 siempre devolverá 3 cuando x es 2, no importa cuántas veces se invoca. Esto significa que no sólo puede la función no mutar en cualquier estado, cuando se llama, pero también no se puede confiar en cualquier estado externo que puede ser mutado así. Las funciones que se referentially transparente, fácilmente puede tener sus resultados en caché. Por ejemplo, memoization y programación dinámica se vuelven posibles cuando se utiliza puro funciones.

Puro funciones también son naturalmente thread-safe. Porque el estado no está mutado, una pura función puede ser llamada por muchos hilos como desee en paralelo. De hecho, pura funciones realizar la paralelización y la programación concurrente de una brisa. Dadas dos puro funciones que no dependen de los resultados de la una de la otra, usted puede llamar a las funciones en cualquier orden sin causar condiciones de carrera.

La forma más fácil de convertir una función en una pura función es inyectar todo el estado, que una pura función de las necesidades como argumentos a la función. Esto puede tener algunos inconvenientes si su función es demasiado complejo, porque usted puede terminar para arriba con largas listas de parámetros. Esto también pone de relieve la importancia de la utilización de puro funciones con cuidado junto con el paradigma de la programación orientada a objetos. Los métodos en los objetos tienen un montón de estado de los que no necesita ser proporcionada como parámetro. Esta tensión puede ser resuelto si a las variables miembro de un objeto inmutable o utilizar las funciones estáticas que toma el objeto como uno de sus parámetros (creo que Python).

La recursividad

Recursividad—y su refinado subtipo, la cola de la recursión es un concepto que debe ser familiar para casi todo programador. La recursividad es nada menos que esencial en la programación funcional, donde el énfasis en la inmutabilidad y puro funciones de procesamiento convencional de bucle incómodo de usar y el mejor de los desanimen en el sentido general. La recursividad es un bucle mecanismo por el que una función se llama a sí mismo repetidamente para cada paso del bucle en lugar de depender de una variable de contador.

Uno de los conceptos fundamentales de la recursividad y la razón por la que la incluye como un consejo para ser utilizado por imperativo de los programadores—descomponer los problemas más grandes en las pequeñas, la auto-piezas similares. Problemas más pequeños son más fáciles de entender y más intuitiva para resolver. Naturalmente, esto conduce a mejorar el código de la comprensión y la facilidad de mantenimiento. Cada vez que te topas con el código que necesita bucle, pregúntate a ti mismo si la recursividad es la forma correcta de realizar el bucle. Iterar sobre una matriz para llamar a una función en cada uno de los valores que contiene es más adecuado para un cuadro normal, mientras que la ordenación de una matriz utilizando el quicksort estrategia sería un gran candidato para la recursividad.

Recuerde siempre usar recursión de la cola si el problema lo permite y su lenguaje soporta. La cola de la recursividad es cuando la llamada recursiva es la última cosa que sucede antes del final de la función, en otras palabras, es en la trasera de posición. Esta función recursiva es la cola-recursiva:

la función factorial(x, acc) { acc = acc || 1; // acc puede ser omitido cuando inicialmente invocar a factorial() si (x > 1) { return factorial(x - 1, acc * x); } else { return acc; } }

La cola de la recursividad es beneficioso porque evita uno de los mayores puntos débiles de la recursividad: desbordamientos de pila. El compilador puede optimizar la cola de llamadas recursivas de tal manera que no se produzca en función de los punteros en la pila cada vez más profundo y más profundo con cada llamada. Si su función recursiva puede ser llamado cientos de veces, considere la posibilidad de escribir la función en una cola de manera recursiva o de reescritura utilizando más convencional de bucle mecanismos.

Conclusión

La brecha entre funcionales y programadores imperativo que los programadores no es tan amplia como usted podría pensar. Al final del día, ambas partes tienen mucho que aportar al mundo de la programación. Herramientas familiares para el mundo de la programación funcional puede ser utilizado en el imperativo de los lenguajes de programación para hacer nuestro código más limpio, más modular, y más fáciles de mantener.