Pregunta

En mi segundo año de Universidad nos "enseñaron" Haskell, no sé casi nada sobre él y menos sobre programación funcional.

¿Qué es la programación funcional, por qué y/o dónde querría usarla en lugar de la programación no funcional? ¿Estoy en lo cierto al pensar que C es un lenguaje de programación no funcional?

¿Fue útil?

Solución

Una característica clave de un lenguaje funcional es el concepto de funciones de primera clase.La idea es que puedas pasar funciones como parámetros a otras funciones y devolverlas como valores.

La programación funcional implica escribir código que no cambia de estado.La razón principal para hacerlo es que las llamadas sucesivas a una función produzcan el mismo resultado.Puedes escribir código funcional en cualquier lenguaje que admita funciones de primera clase, pero hay algunos lenguajes, como Haskell, que no te permiten cambiar de estado.De hecho, se supone que no debes producir ningún efecto secundario (como imprimir texto), lo que parece que podría ser completamente inútil.

En cambio, Haskell emplea un enfoque diferente para IO:mónadas.Estos son objetos que contienen la operación IO deseada que debe ejecutar el nivel superior de su intérprete.En cualquier otro nivel son simplemente objetos del sistema.

¿Qué ventajas aporta la programación funcional?La programación funcional permite codificar con menos posibilidades de errores porque cada componente está completamente aislado.Además, el uso de recursividad y funciones de primera clase permite pruebas simples de corrección que normalmente reflejan la estructura del código.

Otros consejos

¿Qué es la programación funcional?

Hay dos definiciones diferentes de "programación funcional" de uso común en la actualidad:

La definición anterior (que se origina en Lisp) es que la programación funcional se trata de programar utilizando funciones de primera clase, es decir.donde las funciones se tratan como cualquier otro valor, por lo que puede pasar funciones como argumentos a otras funciones y la función puede devolver funciones entre sus valores de retorno.Esto culmina en el uso de funciones de orden superior como map y reduce (es posible que hayas oído hablar de mapReduce como una operación única muy utilizada por Google y, como era de esperar, ¡es un pariente cercano!).Los tipos .NET System.Func y System.Action hacer que las funciones de orden superior estén disponibles en C#.Aunque el curry no es práctico en C#, las funciones que aceptan otras funciones como argumentos son comunes, p.el Parallel.For función.

La definición más joven (popularizada por Haskell) es que la programación funcional también consiste en minimizar y controlar los efectos secundarios, incluida la mutación, es decir.escribir programas que resuelvan problemas componiendo expresiones.Esto se denomina más comúnmente "programación puramente funcional".Esto es posible gracias a enfoques muy diferentes de las estructuras de datos denominadas "estructuras de datos puramente funcionales".Un problema es que traducir algoritmos imperativos tradicionales para utilizar estructuras de datos puramente funcionales normalmente empeora el rendimiento 10 veces.Haskell es el único lenguaje de programación puramente funcional que sobrevive, pero los conceptos se han introducido en la programación convencional con bibliotecas como Linq en red.

¿Dónde querría usarlo en lugar de programación no funcional?

En todos lados.Lambdas en C# ahora han demostrado importantes beneficios.C++ 11 tiene lambdas.No hay excusa para no utilizar funciones de orden superior ahora.Si puede utilizar un lenguaje como F#, también se beneficiará de la inferencia de tipos, la generalización automática, el curry y la aplicación parcial (¡además de muchas otras características del lenguaje!).

¿Estoy en lo cierto al pensar que C es un lenguaje de programación no funcional?

Sí.C es un lenguaje procesal.Sin embargo, puede obtener algunos de los beneficios de la programación funcional utilizando punteros de función y void * Cª.

Puede que valga la pena consultar este artículo sobre F# "101" en CoDe Mag publicado recientemente.

También, Dustin Campbell tiene un gran blog. donde ha publicado muchos artículos sobre sus aventuras para ponerse al día con F#.

Espero que encuentres esto útil :)

EDITAR:

Además, solo para agregar, mi comprensión de la programación funcional es que todo es una función, o parámetros de una función, en lugar de instancias/objetos con estado.Pero podría estar equivocado. F# es algo en lo que me muero por entrar, ¡pero simplemente no tengo tiempo!:)

El código de ejemplo de John el Estadístico no muestra programación funcional, porque cuando estás haciendo programación funcional, la clave es que el código NO HAGA ASIGNACIONES ( record = thingConstructor(t) es una tarea), y NO TIENE EFECTOS SECUNDARIOS (localMap.put(record) es una declaración con un efecto secundario).Como resultado de estas dos limitaciones, todo lo que un función lo que hace se captura completamente por sus argumentos y su valor de retorno.Reescribiendo el código del Estadístico de la manera que debería verse, si quisieras emular un lenguaje funcional usando C++:

RT getOrCreate(const T thing, 
                  const Function<RT<T>> thingConstructor, 
                  const Map<T,RT<T>> localMap) {
    return localMap.contains(t) ?
        localMap.get(t) :
        localMap.put(t,thingConstructor(t));
}

Como resultado de la regla de no efectos secundarios, cada declaración es parte del valor de retorno (por lo tanto return llega primero), y cada declaración es una expresión.En lenguajes que imponen programación funcional, el return La palabra clave está implícita y la si La declaración se comporta como la de C++. ?: operador.

Además, todo es inmutable, por lo que localMap.put tiene que crear una nueva copia de localMapa y devolverlo, en lugar de modificar el original localMapa, como lo haría un programa normal de C++ o Java.Dependiendo de la estructura de localMap, la copia podría reutilizar punteros en el original, reduciendo la cantidad de datos que se deben copiar.

Algunas de las ventajas de la programación funcional incluyen el hecho de que los programas funcionales son más cortos y es más fácil modificar un programa funcional (porque no hay efectos globales ocultos que deban tenerse en cuenta) y es más fácil obtener el programa correctamente en el primer lugar.

Sin embargo, los programas funcionales tienden a ejecutarse lentamente (debido a todas las copias que tienen que hacer) y no tienden a interactuar bien con otros programas, procesos del sistema operativo o sistemas operativos, que trabajan con direcciones de memoria, little-endian. bloques de bytes y otros bits no funcionales específicos de la máquina.El grado de no interoperabilidad tiende a estar inversamente correlacionado con el grado de pureza funcional y el rigor del sistema de tipos.

Los lenguajes funcionales más populares tienen sistemas de tipos realmente estrictos.En OCAML, ni siquiera se pueden mezclar matemáticas de números enteros y de punto flotante, ni usar los mismos operadores (+ es para sumar números enteros, +.es para agregar flotadores).Esto puede ser una ventaja o una desventaja, dependiendo de cuánto valore la capacidad de un verificador de tipos para detectar ciertos tipos de errores.

Los lenguajes funcionales también tienden a tener entornos de ejecución realmente grandes.Haskell es una excepción (los ejecutables de GHC son casi tan pequeños como los programas C, tanto en tiempo de compilación como de ejecución), pero los programas SML, Common Lisp y Scheme siempre requieren toneladas de memoria.

Sí, tienes razón al pensar que C es un lenguaje no funcional.C es un lenguaje procesal.

Prefiero usar programación funcional para ahorrarme trabajo repetido, haciendo una versión más abstracta y luego usándola en su lugar.Déjame dar un ejemplo.En Java, a menudo me encuentro creando mapas para registrar estructuras y, por lo tanto, escribiendo estructuras getOrCreate.

SomeKindOfRecord<T> getOrCreate(T thing) { 
    if(localMap.contains(t)) { return localMap.get(t); }
    SomeKindOfRecord<T> record = new SomeKindOfRecord<T>(t);
    localMap = localMap.put(t,record);
    return record; 
}

Esto sucede muy a menudo.Ahora, en un lenguaje funcional podría escribir

RT<T> getOrCreate(T thing, 
                  Function<RT<T>> thingConstructor, 
                  Map<T,RT<T>> localMap) {
    if(localMap.contains(t)) { return localMap.get(t); }
    RT<T> record = thingConstructor(t);
    localMap = localMap.put(t,record);
    return record; 
}

y nunca más tendría que escribir uno nuevo de estos, podría heredarlo.Pero podría hacer algo mejor que heredar, podría decir en el constructor de esta cosa.

getOrCreate = myLib.getOrCreate(*,
                                SomeKindOfRecord<T>.constructor(<T>), 
                                localMap);

(donde * es una especie de notación de "dejar este parámetro abierto", que es una especie de curry)

y luego el getOrCreate local es exactamente el mismo que habría sido si escribiera todo, en una línea, sin dependencias de herencia.

Si buscas un buen texto en F#

Experto F# está coescrito por Don Syme.Creador de F#.Trabajó en genéricos en .NET específicamente para poder crear F#.

F# está modelado a partir de OCaml, por lo que cualquier texto OCaml también le ayudará a aprender F#.

Encuentro ¿Qué es la programación funcional? ser útil

La programación funcional se trata de escribir funciones puras, sobre la eliminación de entradas y salidas ocultas lo más lejos que podamos, de modo que la mayor parte de nuestro código sea posible solo describir una relación entre entradas y salidas.

Prefiero explícito when parámetro

public Program getProgramAt(TVGuide guide, int channel, Date when) {
  Schedule schedule = guide.getSchedule(channel);

  Program program = schedule.programAt(when);

  return program;
}

encima

public Program getCurrentProgram(TVGuide guide, int channel) {
  Schedule schedule = guide.getSchedule(channel);

  Program current = schedule.programAt(new Date());

  return current;
}

Un lenguaje funcional es activamente hostil a los efectos secundarios.Los efectos secundarios son la complejidad y la complejidad son los errores y los errores son el diablo.Un lenguaje funcional también le ayudará a ser hostil a los efectos secundarios.

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