¿Hay inconvenientes o problemas con Haskell?

47

Estoy buscando sumergirme en Haskell para mi próximo (relativamente trivial) proyecto personal. Las razones por las que estoy abordando a Haskell son:

  1. Poner mi cabeza en un lenguaje puramente funcional
  2. Velocidad. Si bien estoy seguro de que esto se puede argumentar, perfilando que he visto uñas Haskell cercanas a C ++ (y parece ser un poco más rápido que Erlang).
  3. Velocidad. El servidor web Warp parece estar loco rápido en comparación con prácticamente todo lo demás .

Entonces, dado esto, lo que estoy buscando son las desventajas o los problemas que vienen con Haskell. La web tiene una gran cantidad de información sobre por qué Haskell es una buena cosa, pero no he encontrado muchos temas sobre su lado feo (aparte de quejas sobre su sintaxis que no me importa en absoluto).

Un ejemplo de lo que estoy buscando podría ser como el GIL de Python. Algo que no creció hasta que realmente comencé a considerar el uso de la concurrencia en un entorno CPython.

Demian Brecht
fuente
44
Encontré esto en stackoverflow: stackoverflow.com/questions/1695076/pros-and-cons-of-haskell
FrustratedWithFormsDesigner
26
He escuchado que programadores menores se han ocupado de problemas de fusión cerebral. Es una condición muy costosa de tratar.
ChaosPandion
1
@FrustratedWithFormsDesigner: Gracias por el enlace. Sin embargo, todavía no hay ninguna referencia a las desventajas técnicas de Haskell. ¿Podría ser que no hay ninguna? ;)
Demian Brecht el
66
@ChaosPandion: He oído lo mismo .. Pero si no fundir el cerebro, están en realidad se tratan ? ;) Además, realmente no me consideraría un programador menor, así que no estoy demasiado preocupado por eso;)
Demian Brecht
3
@ChaosPandion: Y la mayoría de los planes de salud no lo cubren. :(
FrustratedWithFormsDesigner

Respuestas:

48

Algunas desventajas que se me ocurren:

  • Debido a la naturaleza del lenguaje y sus raíces firmes en el mundo académico, la comunidad tiene una mente muy matemática; si eres una persona pragmática, esto puede ser abrumador a veces, y si no hablas la jerga, te será más difícil que con muchos otros idiomas.
  • Si bien existe una increíble riqueza de bibliotecas, la documentación a menudo es breve.
  • Los tutoriales suaves de nivel de entrada son pocos y difíciles de encontrar, por lo que la curva de aprendizaje inicial es bastante empinada.
  • Algunas características del lenguaje son innecesariamente torpes; Un ejemplo destacado es cómo la sintaxis de registro no introduce un ámbito de denominación, por lo que no hay forma de tener el mismo nombre de campo de registro en dos tipos diferentes dentro del mismo espacio de nombres del módulo.
  • Haskell adopta por defecto la evaluación perezosa, y aunque a menudo esto es una gran cosa, a veces puede morderlo de maneras desagradables. El uso ingenuo de la evaluación perezosa en situaciones no triviales puede generar cuellos de botella innecesarios en el desempeño, y comprender lo que sucede debajo del capó no es exactamente sencillo.
  • La evaluación diferida (especialmente combinada con la pureza y un compilador agresivamente optimizado) también significa que no puede razonar fácilmente sobre el orden de ejecución; de hecho, ni siquiera sabe si un determinado fragmento de código realmente se evalúa en una situación dada. En consecuencia, la depuración del código de Haskell requiere una mentalidad diferente, aunque solo sea porque recorrer el código es menos útil y menos significativo.
  • Debido a la pureza de Haskell, no puede usar efectos secundarios para hacer cosas como E / S; tienes que usar una evaluación perezosa de mónada y 'abuso' para lograr interactividad, y debes arrastrar el contexto monádico a cualquier lugar donde quieras hacer E / S. (En realidad, esta es una buena característica en muchos sentidos, pero a veces hace imposible la codificación pragmática).
tdammers
fuente
16
En realidad, hay algunos libros introductorios realmente buenos disponibles de forma gratuita en línea ahora. Learn You a Haskell for Great Good es uno de los mejores libros de programación para principiantes que he leído y Real World Haskell es un gran recurso intermedio.
Tikhon Jelvis
1
@TikhonJelvis: Esos son de hecho los únicos dos candidatos que encontré que vale la pena usar; "Learn You A Haskell" me confundió más que nada, "Real World Haskell" trabajó para mí pero asume un poco de experiencia en programación. También hay una "Introducción suave a Haskell", pero es muy amable, especialmente si no tienes experiencia en matemáticas.
tdammers
Utilizo "Gentle Introduction to Haskell" y "Real World Haskell". La combinación de los dos me dio mucha información útil. Estoy en un nivel en el que estoy listo para un proyecto no trivial, pero desafortunadamente no tengo mucho tiempo para ello.
Giorgio
99
"si eres una persona pragmática ...": a veces, usar un lenguaje orientado a las matemáticas puede ser una decisión muy pragmática si te evita una gran cantidad de corrección de errores más adelante. Por supuesto, siempre debe encontrar un equilibrio entre la cantidad de tiempo que ahorra al usar una herramienta y la cantidad de tiempo adicional que necesita para aprender a usarla.
Giorgio
Las mónadas (y lo hacen en otros idiomas) funcionan exactamente igual en un lenguaje estricto. Absolutamente no "abusa" de la evaluación perezosa para lograr interactividad, es trivial escribir un programa interactivo estricto en Haskell.
punto
19

La mayoría de las desventajas de Haskell (así como la mayoría de las ventajas de Haskell) provienen de sus dos características definitorias: es vago y puramente funcional.

Ser perezoso hace que sea más difícil razonar sobre el rendimiento. Especialmente para las personas que no están acostumbradas a la pereza, pero incluso para los experimentados Haskellers puede ser difícil ver cómo la pereza afectará el rendimiento en ciertos casos.

La pereza también significa que es más difícil crear puntos de referencia precisos sin usar bibliotecas como Criterion.

Ser puramente funcional significa que siempre que necesite utilizar estructuras de datos mutables (en los casos en que no sea posible lograr el rendimiento deseado sin ellas, aunque gracias al optimizador de GHC que no sucede tan a menudo como podría pensar), estará atascado en la mónada IO (o ST), lo que hace que el código sea más engorroso.

Dado que mencionó la velocidad como uno de sus objetivos, debo señalar que a menudo hay grandes diferencias en el rendimiento entre el código Haskell optimizado a mano y el código Haskell que se escribió sin pensar demasiado en el rendimiento (más que en otros idiomas). Y el código de Haskell optimizado a mano suele ser bastante feo (aunque supongo que eso también es cierto en la mayoría de los otros idiomas).

sepp2k
fuente
1
Puramente funcional es en realidad una característica de venta, no un inconveniente. Un lenguaje que sea "perezoso" no tiene sentido, perezoso versus estricto es una cuestión de tipos, y tanto los tipos perezosos como los estrictos tienen sus usos. (Por lo tanto, Haskell está tan paralizado por no tener tipos estrictos como la mayoría de los idiomas están paralizados por no tener tipos perezosos). Las principales desventajas de Haskell son su sistema de módulos deficiente (los módulos no son de primera clase) y las clases de tipo de hecho realmente rompen la modularidad (el la regla "una instancia por tipo" obliga al compilador a mantener una lista global de instancias de clase de tipo).
pyon
21
"Y el código de Haskell optimizado a mano suele ser bastante feo (aunque supongo que eso también es cierto en la mayoría de los otros idiomas)". Esta. Cuando las personas quieren mostrar la elegancia de Haskell, publican un código breve y dulce, que desafortunadamente le daría un rendimiento bastante malo si se ejecuta en una cantidad de datos similar a la producción. Cuando la gente quiere demostrar que "Haskell es tan rápido como C ++", que publican enrevesado y difícil de leer el código, que sigue siendo más lento es que una versión mucho más legible en C.
quant_dev
12

No soy un experto en Haskell: aprendí los conceptos básicos, pero desafortunadamente no tuve la oportunidad de hacer un proyecto serio en Haskell (aunque me gustaría, porque me gusta mucho este idioma).

Sin embargo, por lo que sé y por una discusión con alguien que ha estado trabajando en un campo bastante cercano a la programación funcional, Haskell podría no ser la mejor solución cuando desea implementar algoritmos de gráficos, donde necesita, por ejemplo, recorrer el gráfico y realizar muchos cambios locales en la estructura del gráfico.

Como un gráfico no tiene una estructura recursiva en general, creo que el mejor enfoque es construir una copia del gráfico utilizando estructuras y punteros entre ellos (como puede hacer, por ejemplo, en C ++) y manipular esa copia cambiando los punteros, creando o destruyendo nodos, y así sucesivamente.

Me pregunto cómo se pueden manejar adecuadamente estas estructuras de datos y operaciones en Haskell, ya que hasta donde yo sé en Haskell no es posible utilizar la representación / enfoque anterior. Algunos problemas con algoritmos gráficos en Haskell se discuten brevemente en este artículo

EDITAR

Recientemente hablé con un experto en programación funcional y él confirmó que implementar ciertos algoritmos gráficos de manera eficiente puede ser bastante complicado en Haskell: moverse por los punteros como lo hace en C o C ++ puede ser mucho más rápido.

Giorgio
fuente
Notas interesantes (y enlace) sobre manipulación / recorrido de gráficos en un mundo funcional puro. No lo había considerado.
Demian Brecht
77
Los algoritmos de gráficos puramente funcionales son un tema interesante. La solución idiomática es emular la representación imperativa mediante la sustitución de punteros con diccionarios puramente funcionales, por ejemplo, mapear un vértice dado al conjunto de vértices con los que tiene bordes. Sin embargo, a menos que se use un diccionario débil, esto perderá memoria porque no se pueden recopilar subgrafías inalcanzables y no se conoce un diccionario débil puramente funcional. Al final del día, una solución de última generación puramente funcional es mucho más complicada y mucho menos eficiente.
Jon Harrop
1
Por otro lado, los algoritmos gráficos pueden ser notablemente difíciles de depurar y la estructura de datos persistente puede aliviar este problema ...
Jon Harrop
Me preguntaba si sería posible desarrollar un tipo de datos de gráfico (siguiendo la idea de ByteString: representación interna eficiente más funciones de conversión / acceso). Usando mónadas, debería ser posible hacer que estos gráficos sean mutables. Por supuesto, esto abordaría el problema de representar gráficos, pero no el de implementar algoritmos de gráficos.
Giorgio
Los DAG son una cosa. Para todo lo demás, puede explotar la pereza y "casarse".
danielm
4

La desventaja de Haskell es que es diferente. Es un paso más alejado de los idiomas que se enseñan o hablan más comúnmente, por lo que habrá una curva de aprendizaje más grande. También es menos popular de un lenguaje que puede limitar la disponibilidad de ayuda si te quedas atascado. Sin embargo, estos realmente no son inconvenientes importantes.

La única desventaja potencial es que es un lenguaje funcional, por lo que es menos útil para ciertos dominios problemáticos, pero esto también es cierto para los lenguajes orientados a objetos. En general, los idiomas no tienen verdaderos negativos más allá de las curvas de aprendizaje, al menos para los idiomas relativamente populares. Mientras un lenguaje esté completo, es teóricamente capaz de cualquier cosa.

Ryathal
fuente
3
La integridad de Turing es un arenque rojo. Teoría de la computación! = Programación práctica.
1
@delnan por eso dije teóricamente
Ryathal el
2
¿Cuáles son esos "dominios problemáticos" para los cuales Haskell supuestamente es menos útil?
Andres F.
3
Si bien es cierto que la comunidad es más pequeña , en realidad es desproporcionadamente activa. Creo que el canal #haskell en freenode solo está detrás de #python en popularidad dentro de los canales de idiomas, y responder preguntas sobre Haskell en SO es sorprendentemente competitivo :)
Tikhon Jelvis
@AndresF. - No iría tan lejos como para decir "menos útil", pero aquí hay algunas áreas donde Haskell definitivamente todavía está mostrando su infancia: 1) DP pesado - Codifiqué un algoritmo de mochila simple, y literalmente me sorprendió cómo lento fue. Estaba usando matrices en caja, así que esperaba algo de sobrecarga, pero fue mucho peor de lo que esperaba. 2) grandes juegos no triviales: AFRP está en pañales, por lo que no hay marcos particularmente buenos y el rendimiento sigue siendo demasiado difícil de predecir. Pasará mucho tiempo antes de que veamos la versión de Hasomell de Doom. (frag no cuenta, no tiene IA)
rtperson
0

Entonces, dado esto, lo que estoy buscando son las desventajas o los problemas que vienen con Haskell

Los "problemas con Haskell" tienden a aparecer en ciertos dominios. Haskell es un lenguaje maravilloso para la programación de aplicaciones, mucho más agradable de escribir que casi cualquier otra cosa. Los problemas tienden a surgir cuando intentas hacer algo para lo que no hay un buen soporte, como:

  • Compilación cruzada. GHC se puede construir como un compilador cruzado, pero el proceso es bastante complicado.
  • Aplicaciones integradas Haskell tiene administración de memoria a través de un recolector de basura, por lo que este no es demasiado sorprendente.
  • Velocidad. Haskell no es tan rápido como Rust, aunque en la mayoría de los casos competirá bastante bien. Depende en gran medida del dominio de la aplicación: los cálculos puros se optimizan bien, pero algo como "leer un archivo en un búfer y contar el número de líneas" es más difícil de expresar en Haskell.

fuente