Mezcla de Haskell y C++
ffi (4)
Si tuviera la posibilidad de tener una aplicación que usaría tanto Haskell como C ++. ¿Qué capas dejarías que administrara Haskell y qué capas dejarías que administrara C ++?
¿Alguien ha hecho alguna vez tal asociación, (seguramente)?
(el sitio de Haskell dice que es realmente fácil porque Haskell tiene un modo donde se puede compilar en C por gcc)
Al principio, creo que mantendría todas las operaciones de E / S en las capas de C ++. Además de la gestión de GUI.
Es una pregunta bastante vaga, pero como estoy planeando aprender Haskell, estaba pensando en delegar un poco de trabajo al código Haskell (aprendo en realidad la codificación), y quiero elegir alguna parte en la que vea los beneficios de Haskell.
Así es como veo las cosas:
- Los lenguajes funcionales se destacan en transformar cosas . Cada vez que escribe programas que toman una entrada y la mapean / filtran / reducen, use construcciones funcionales. Maravillosos ejemplos del mundo real donde Haskell debería sobresalir son dados por aplicaciones web (básicamente, transforma las cosas almacenadas en una base de datos en páginas web).
- Los lenguajes de procedimiento (los lenguajes de POO son de procedimiento) destacan por los efectos secundarios y la comunicación entre los objetos. Son engorrosos de usar para transformar datos, pero cada vez que desea realizar una programación del sistema o una interacción (bidireccional) con humanos (interfaces de usuario de cualquier tipo, incluida la programación web del lado del cliente), hacen el trabajo de forma limpia.
- Sin embargo, algunos pueden argumentar que las interfaces de usuario deben tener una descripción funcional, respondo que los marcos bien establecidos son lo suficientemente fáciles de usar con los lenguajes de OOP que uno debería usarlos de esta manera. Después de todo, es natural pensar en los componentes de la interfaz de usuario en términos de objetos y comunicación entre objetos.
- IO es solo una herramienta: cada vez que transforma una entrada en una salida, Haskell (o cualquier lenguaje FP) debería hacer el IO. Siempre que hable con un ser humano, C ++ (o cualquier lenguaje OOP) debería hacer el IO.
- No me importa la velocidad. Cuando usa Haskell para el trabajo correcto, es eficiente. Cuando usa C ++ o Python para el trabajo correcto, es eficiente.
Por lo tanto, digamos que domino Haskell, C, C ++ y Python, así es como escribo aplicaciones:
- Si la función principal de mi aplicación es transformar datos, los escribo en Haskell, posiblemente con algunas partes de bajo nivel escritas en C (que a su vez pueden llamar partes de bajo nivel de alta tecnología escritas en C ++, pero me quedaría con C como interfaz por razones de portabilidad).
- Si la función principal de mi aplicación es interactuar con un usuario, la escribo en Python (PyQt por ejemplo) y dejo que Python llame rutinas de rendimiento crítico escritas en C ++ (boost :: python es bastante bueno como generador de enlace). También es posible que tenga que llamar a subrutinas que transforman o captan datos, que se escribirán en Haskell.
- Si tengo que escribir una parte de una aplicación en Haskell, la segrego en una API C-invocable.
- A veces, una aplicación Haskell que lee cosas en stdin y vuelve a escribir en stdout es útil como un submódulo (al que llamas con fork / exec, o lo que sea en tu plataforma). A veces, un script de shell es el contenedor adecuado para tales aplicaciones.
El beneficio de Haskell son las poderosas abstracciones que te permite usar. No estás pensando en términos de unos y ceros, direcciones y registros, sino de cálculos y propiedades de tipo y continuaciones.
El beneficio de C ++ es qué tan ajustado puede optimizarlo cuando sea necesario. No está pensando en mónadas, flechas, aplicaciones parciales y funciones puras de alta resolución: con C ++, ¡puede llegar hasta el metal desnudo!
Hay tensión entre estas dos declaraciones. En su documento "Programación estructurada con go to
declaraciones", Donald Knuth escribió
Durante mucho tiempo he sentido que un talento para la programación consiste en gran medida en la capacidad de cambiar fácilmente de vistas microscópicas a macroscópicas de las cosas, es decir , cambiar los niveles de abstracción con fluidez.
Saber cómo usar Haskell y C ++, pero también cómo y cuándo combinarlos bien eliminará todo tipo de problemas.
El último gran proyecto que escribí que utilizaba FFI implicaba el uso de una biblioteca interna de modelado de radar escrita en C. Reimplementarlo hubiera sido una tontería, y expresar la lógica de alto nivel del resto de la aplicación habría sido un dolor. Mantuve sus "cerebros" en Haskell y llamé a la biblioteca C cuando lo necesitaba.
Deseas hacer esto como ejercicio, así que te recomendaría el mismo enfoque: escribe la inteligencia en Haskell. El encadenamiento de Haskell como esclavo de C ++ probablemente terminará frustrando o haciéndote sentir como si hubieras perdido tu tiempo. Use cada idioma donde se encuentran sus puntos fuertes.
Esta respuesta es más una historia que una respuesta integral, pero utilicé una mezcla de Haskell, Python y C ++ para mi disertación en lingüística computacional, así como varias herramientas C y Java que no escribí. Me pareció más simple ejecutar todo como un proceso separado, utilizando Python como código de pegamento para iniciar los programas Haskell, C ++ y Java.
El C ++ era un bucle bastante simple y apretado que contaba las apariciones de características. Básicamente todo lo que hizo fue matemática y E / S simple. De hecho, controlé las opciones haciendo que el código de pegamento de Python escribiera un encabezado lleno de #define
y volviendo a compilar. Tipo de hacky, pero funcionó.
El Haskell fue todo el procesamiento intermedio: tomar la salida compleja de los diversos analizadores C y Java que usé, filtrando datos extraños y transformándolo en el formato simple que el código C ++ esperaba. Luego tomé la salida C ++ y la transformé en marcado LaTeX (entre otros formatos).
Esta es un área en la que esperaría que Python fuera fuerte, pero descubrí que Haskell facilita la manipulación de estructuras complejas; Es probable que Python sea mejor para transformaciones simples de línea a línea, pero estaba cortando y cortando árboles de análisis y descubrí que olvidé los tipos de entrada y salida cuando escribí el código en Python.
Como usaba Haskell mucho más como un lenguaje de scripting más estructurado, terminé escribiendo algunas utilidades de E / S de archivos, pero más allá de eso, bastaba con las bibliotecas integradas para la manipulación de árboles y listas.
En resumen, si tiene un problema como el mío, sugeriría C ++ para la parte de velocidad crítica, restringida por la memoria, Haskell para las transformaciones de alto nivel y Python para ejecutarlo todo.
Nunca he mezclado ambos idiomas pero su enfoque se siente un poco al revés para mí. Haskell es más apto para operaciones de alto nivel, mientras que C ++ se puede optimizar y puede ser más beneficioso para bucles estrechos y otros códigos de rendimiento crítico.
Uno de los mayores beneficios de Haskell es la encapsulación de IO en mónadas. Mientras este IO no sea crítico en el tiempo, no veo ninguna razón para hacerlo en C ++.
Para la parte de la GUI, probablemente tengas razón. Hay una gran cantidad de bibliotecas de GUI Haskell, pero C ++ tiene herramientas potentes como QtCreator que simplifican mucho las tareas tediosas.