La forma en que me lo propusieron, y lo que creo que es cierto después de haber trabajado en el aprendizaje de Haskell durante un mes, es el hecho de que la programación funcional tuerce tu cerebro de maneras interesantes: te obliga a pensar en problemas familiares de diferentes maneras. : en lugar de bucles, piense en mapas, pliegues y filtros, etc. En general, si tiene más de una perspectiva sobre un problema, estará mejor capacitado para razonar sobre este problema y cambiar de punto de vista según sea necesario.
La otra cosa realmente interesante de Haskell es su sistema de tipos. Está estrictamente escrito, pero el motor de inferencia de tipos lo hace sentir como un programa de Python que mágicamente le dice cuando ha cometido un error estúpido relacionado con el tipo. Los mensajes de error de Haskell en este sentido son algo deficientes, pero a medida que se familiarice más con el idioma, se dirá a sí mismo: ¡esto es lo que se supone que es escribir!
Este es el ejemplo que me convenció de aprender Haskell (y me alegro de haberlo hecho).
Bien, es un programa breve y legible. En ese sentido, es mejor que un programa C. Pero, ¿en qué se diferencia esto de (digamos) un programa de Python con una estructura muy similar?
La respuesta es evaluación perezosa. En la mayoría de los lenguajes (incluso algunos funcionales), un programa estructurado como el anterior daría como resultado que todo el archivo se cargara en la memoria y luego se escribiera nuevamente con un nuevo nombre.
Haskell es "vago". No calcula las cosas hasta que lo necesita y, por extensión , no calcula las cosas que nunca necesita. Por ejemplo, si eliminara la
writeFile
línea, Haskell no se molestaría en leer nada del archivo en primer lugar.Tal como están las cosas, Haskell se da cuenta de que
writeFile
depende dereadFile
y, por lo tanto, puede optimizar esta ruta de datos.Si bien los resultados dependen del compilador, lo que suele suceder cuando ejecuta el programa anterior es lo siguiente: el programa lee un bloque (digamos 8 KB) del primer archivo, luego lo escribe en el segundo archivo y luego lee otro bloque del primero archivo y lo escribe en el segundo archivo, y así sucesivamente. (¡Intenta ejecutarlo
strace
!)... que se parece mucho a lo que haría la implementación eficiente de C de una copia de archivo.
Por lo tanto, Haskell le permite escribir programas compactos y legibles, a menudo sin sacrificar mucho rendimiento.
Otra cosa que debo agregar es que Haskell simplemente dificulta la escritura de programas con errores. El asombroso sistema de tipos, la falta de efectos secundarios y, por supuesto, la compacidad del código Haskell reduce los errores por al menos tres razones:
Mejor diseño de programas. La complejidad reducida conduce a menos errores lógicos.
Código compacto. Menos líneas para que existan errores.
Compila errores. Muchos errores simplemente no son válidos para Haskell .
Haskell no es para todos. Pero todo el mundo debería intentarlo.
fuente
hSetBuffering handle (BlockBuffering (Just bufferSize))
.Data.Bytestring.Lazy.readFile
), que nada tienen que ver con Haskell es un lenguaje vago (no estricto). Las mónadas se están secuenciando , esto significa que aproximadamente "todos los efectos secundarios se realizan cuando se elimina el resultado". En cuanto a la magia de "lazy Bytestring": esto es peligroso, y puedes hacerlo con una sintaxis similar o más simple en la mayoría de los otros lenguajes.readFile
también hace IO perezoso de la misma manera que loData.ByteString.Lazy.readFile
hace. Entonces, la respuesta no es incorrecta y no es simplemente una optimización del compilador. De hecho, esto es parte de la especificación de Haskell : "LareadFile
función lee un archivo y devuelve el contenido del archivo como una cadena. El archivo se lee perezosamente, bajo demanda, como congetContents
".const fs = require('fs'); const [file1, file2] = process.argv.slice(2); fs.createReadStream(file1).pipe(fs.createWriteStream(file2))
. Bash también tiene algo similar:cat $1 > $2
Estás haciendo la pregunta incorrecta.
Haskell no es un lenguaje en el que ves algunos ejemplos interesantes y dices "¡Ajá, ya veo, eso es lo que lo hace bueno!"
Es más bien, tenemos todos estos otros lenguajes de programación, y todos son más o menos similares, y luego está Haskell, que es totalmente diferente y loco de una manera que es totalmente asombrosa una vez que te acostumbras a la locura. Pero el problema es que lleva bastante tiempo aclimatarse a la locura. Cosas que distinguen a Haskell de casi cualquier otro idioma incluso semi-convencional:
así como algunos otros aspectos que son diferentes de muchos lenguajes convencionales (pero compartidos por algunos):
Como han respondido algunos otros carteles, la combinación de todas estas características significa que usted piensa en la programación de una manera completamente diferente. Por eso es difícil encontrar un ejemplo (o un conjunto de ejemplos) que comunique esto adecuadamente a Joe-mainstream-programmer. Es una cosa experiencial. (Para hacer una analogía, puedo mostrarles fotos de mi viaje a China en 1970, pero después de ver las fotos, todavía no sabrán cómo fue haber vivido allí durante ese tiempo. Del mismo modo, puedo mostrarles un Haskell 'clasificación rápida', pero aún no sabrá lo que significa ser un Haskeller).
fuente
Lo que realmente distingue a Haskell es el esfuerzo que hace en su diseño para hacer cumplir la programación funcional. Puede programar con un estilo funcional en prácticamente cualquier idioma, pero es muy fácil abandonarlo a la primera comodidad. Haskell no te permite abandonar la programación funcional, por lo que debes llevarlo a su conclusión lógica, que es un programa final sobre el que es más fácil razonar y esquiva toda una clase de los tipos de errores más espinosos.
Cuando se trata de escribir un programa para uso en el mundo real, es posible que a Haskell le falte algo práctico, pero tu solución final será mejor por haber conocido a Haskell desde el principio. Definitivamente no he llegado a ese punto todavía, pero hasta ahora aprender Haskell ha sido mucho más esclarecedor que decir que Lisp estaba en la universidad.
fuente
unsafePerformIO
para las personas que solo quieren ver arder el mundo;)Parte del alboroto es que la pureza y la escritura estática permiten el paralelismo combinado con optimizaciones agresivas. Los lenguajes paralelos están de moda ahora y el multinúcleo es un poco disruptivo.
Haskell le ofrece más opciones de paralelismo que prácticamente cualquier lenguaje de propósito general, junto con un compilador de código nativo rápido. Realmente no hay competencia con este tipo de soporte para estilos paralelos:
Entonces, si le interesa hacer que su multinúcleo funcione, Haskell tiene algo que decir. Un buen lugar para comenzar es con el tutorial de Simon Peyton Jones sobre programación paralela y concurrente en Haskell .
fuente
La memoria transaccional de software es una forma genial de lidiar con la concurrencia. Es mucho más flexible que el paso de mensajes y no es propenso a bloqueos como los mutex. La implementación de STM de GHC se considera una de las mejores.
fuente
Pasé el último año aprendiendo Haskell y escribiendo un proyecto bastante grande y complejo en él. (El proyecto es un sistema de comercio de opciones automatizado, y todo, desde los algoritmos de comercio hasta el análisis y el manejo de datos de mercado de bajo nivel y alta velocidad, se realiza en Haskell). Es considerablemente más conciso y más fácil de entender (para aquellos con antecedentes apropiados) de lo que sería una versión de Java, además de extremadamente robusta.
Posiblemente, la mayor ganancia para mí ha sido la capacidad de modularizar el flujo de control a través de cosas como monoides, mónadas, etc. Un ejemplo muy simple sería el monoide Ordering; en una expresión como
donde
c1
y así sucesivamente retornoLT
,EQ
oGT
,c1
volviendoEQ
causas la expresión de continuar, la evaluaciónc2
; sic2
devuelveLT
oGT
ese es el valor del todo, yc3
no se evalúa. Este tipo de cosas se vuelve considerablemente más sofisticado y complejo en cosas como generadores de mensajes monádicos y analizadores sintácticos en los que puedo tener diferentes tipos de estado, tener diferentes condiciones de aborto o puede querer poder decidir para cualquier llamada en particular si abortar realmente significa "Sin procesamiento adicional" o significa "devolver un error al final, pero continuar con el procesamiento para recopilar más mensajes de error".Todo esto es algo que lleva algo de tiempo y probablemente bastante esfuerzo para aprender, por lo que puede ser difícil presentar un argumento convincente para aquellos que aún no conocen estas técnicas. Creo que el tutorial de All About Monads ofrece una demostración bastante impresionante de una faceta de esto, pero no esperaría que alguien que no esté familiarizado con el material ya lo "entienda" en la primera, o incluso en la tercera, lectura cuidadosa.
De todos modos, también hay muchas otras cosas buenas en Haskell, pero esta es una de las principales que no veo que se mencione tan a menudo, probablemente porque es bastante complejo.
fuente
Para ver un ejemplo interesante, puede consultar: http://en.literateprograms.org/Quicksort_(Haskell)
Lo interesante es observar la implementación en varios idiomas.
Lo que hace que Haskell sea tan interesante, junto con otros lenguajes funcionales, es el hecho de que tienes que pensar de manera diferente sobre cómo programar. Por ejemplo, generalmente no usará bucles for o while, pero usará la recursividad.
Como se mencionó anteriormente, Haskell y otros lenguajes funcionales sobresalen con aplicaciones de escritura y procesamiento en paralelo para trabajar en múltiples núcleos.
fuente
No podría darte un ejemplo, soy un chico de OCaml, pero cuando estoy en una situación como la tuya, la curiosidad simplemente se apodera de ti y tengo que descargar un compilador / intérprete y probarlo. Probablemente aprenderá mucho más de esa manera sobre las fortalezas y debilidades de un lenguaje funcional dado.
fuente
Una cosa que encuentro muy interesante cuando trato con algoritmos o problemas matemáticos es la evaluación inherente y perezosa de los cálculos de Haskell, que solo es posible debido a su estricta naturaleza funcional.
Por ejemplo, si desea calcular todos los números primos, puede usar
y el resultado es en realidad una lista infinita. Pero Haskell lo evaluará de izquierda a derecha, por lo que siempre que no intente hacer algo que requiera la lista completa, aún puede usarlo sin que el programa se atasque en el infinito, como:
que suma todos los números primos menos de 100. Esto es bueno por varias razones. En primer lugar, solo necesito escribir una función principal que genere todos los números primos y luego estoy prácticamente listo para trabajar con números primos. En un lenguaje de programación orientado a objetos, necesitaría alguna forma de decirle a la función cuántos números primos debería calcular antes de regresar, o emular el comportamiento de la lista infinita con un objeto. Otra cosa es que, en general, terminas escribiendo código que expresa lo que quieres calcular y no en qué orden evaluar las cosas; en cambio, el compilador lo hace por ti.
Esto no solo es útil para listas infinitas, de hecho se usa sin que usted lo sepa todo el tiempo cuando no hay necesidad de evaluar más de lo necesario.
fuente
Estoy de acuerdo con otros en que ver algunos pequeños ejemplos no es la mejor manera de mostrar a Haskell. Pero daré algunos de todos modos. Aquí hay una solución ultrarrápida para los problemas 18 y 67 del Proyecto Euler , que le piden que encuentre la ruta de suma máxima desde la base hasta el vértice de un triángulo:
Aquí hay una implementación completa y reutilizable del algoritmo BubbleSearch de Lesh y Mitzenmacher. Lo usé para empaquetar archivos multimedia grandes para el almacenamiento de archivos en DVD sin desperdicio:
Estoy seguro de que este código parece un galimatías aleatorio. Pero si lee la entrada del blog de Mitzenmacher y comprende el algoritmo, se sorprenderá de que sea posible empaquetar el algoritmo en código sin decir nada sobre lo que está buscando.
Habiéndole dado algunos ejemplos tal como me pidió, diré que la mejor manera de comenzar a apreciar a Haskell es leer el documento que me dio las ideas que necesitaba para escribir el paquete de DVD: Por qué la programación funcional es importante por John Hughes. El documento en realidad es anterior a Haskell, pero explica brillantemente algunas de las ideas que hacen que la gente le guste Haskell.
fuente
Para mí, el atractivo de Haskell es la promesa de una exactitud garantizada por el compilador . Incluso si es para partes puras del código.
He escrito una gran cantidad de código de simulación científica, y he preguntado por lo que muchas veces si hubo un error en mis códigos anteriores, lo que podría invalidar una gran cantidad de trabajo actual.
fuente
Encuentro que para ciertas tareas soy increíblemente productivo con Haskell.
La razón es por la sintaxis sucinta y la facilidad de prueba.
Así es la sintaxis de declaración de función:
Esa es la forma más sencilla en la que puedo pensar en definir una función.
Si escribo la inversa
Puedo verificar que sea inverso para cualquier entrada aleatoria escribiendo
Y llamando desde la línea de comando
Lo que verificará que todas las propiedades de mi archivo se mantengan, probando aleatoriamente las entradas cien veces.
No creo que Haskell sea el lenguaje perfecto para todo, pero cuando se trata de escribir pequeñas funciones y probar, no he visto nada mejor. Si su programación tiene un componente matemático, esto es muy importante.
fuente
Si puede entender el sistema de tipos en Haskell, creo que en sí mismo es un gran logro.
fuente
no tiene construcciones de bucle. no muchos idiomas tienen este rasgo.
fuente
Estoy de acuerdo con aquellos que dicen que la programación funcional tuerce su cerebro para que vea la programación desde un ángulo diferente. Solo lo he usado como aficionado, pero creo que cambió fundamentalmente la forma en que abordo un problema. No creo que hubiera sido tan efectivo con LINQ sin haber estado expuesto a Haskell (y usando generadores y listas de comprensión en Python).
fuente
Para ventilar una visión contraria: Steve Yegge escribe que los lenguajes Hindely-Milner carecen de la flexibilidad necesaria para escribir buenos sistemas :
Vale la pena aprender Haskell, pero tiene sus propias debilidades.
fuente