programming functional example course books programming-languages functional-programming

programming languages - functional - Buscando un lenguaje funcional



functional programming vs oop (15)

Soy un científico que trabaja principalmente con C ++, pero me gustaría encontrar un lenguaje mejor. Estoy buscando sugerencias, ni siquiera estoy seguro de que mi "lenguaje soñado" exista (todavía), pero aquí está mi lista de deseos;

CARACTERÍSTICAS IMPORTANTES (por orden de importancia)

1.1: Rendimiento: Para la ciencia, el rendimiento es muy importante. Entiendo perfectamente la importancia de la productividad, no solo la velocidad de ejecución, sino que cuando el programa tiene que ejecutarse durante horas, no puede permitirse escribirlo en Python o Ruby. No necesita ser tan rápido como C ++, pero tiene que estar razonablemente cerca (por ejemplo: Fortran, Java, C #, OCaml ...).

1.2: de alto nivel y elegante: me gustaría poder concentrarme lo más posible en la ciencia y obtener un código claro. También me gustan los lenguajes verbosos como Java.

1.3: Principalmente funcional: me gusta la programación funcional, y creo que se adapta muy bien a mi estilo ya la programación científica. No me importa si el lenguaje es compatible con la programación imperativa, podría ser una ventaja, pero tiene que enfocarse y alentar la programación funcional.

1.4: Portabilidad: debería funcionar bien en Linux (¡especialmente en Linux!), Mac y Windows. Y no, no creo que F # funcione bien en Linux con mono, y no estoy seguro de que OCaml funcione bien en Windows;)

1.5: Orientado a objetos, preferiblemente bajo la filosofía de "todo es un objeto": me di cuenta de lo mucho que me gustaba la programación orientada a objetos cuando tuve que lidiar con C pura no hace mucho tiempo. Me gustan los idiomas con un fuerte compromiso con la programación orientada a objetos, no solo con un soporte tímido.

NO REALMENTE IMPORTANTE, PERO COSAS QUE SERAN AGRADABLES

2.1: "No muy fuerte" al escribir: encuentro que el sistema de escritura fuerte de Haskell es molesto, me gusta poder hacer un casting implícito.

2.2: Herramientas: Las buenas herramientas siempre son una ventaja, pero creo que realmente depende de los idiomas. Jugué con Haskell usando Geany, un editor de peso ligero, y nunca me sentí discapacitado. Por otro lado, no hubiera hecho lo mismo con Java o incluso con Scala (a Scala, en particular, parece que le faltan buenas herramientas, lo que es realmente una pena). Java es realmente el lenguaje # 1 aquí, con NetBeans y Javadoc, la programación con Java es fácil y divertida.

2.3: Recolección de basura, pero traducida o compilada sin una máquina virtual. No tengo nada en contra de las máquinas virtuales, pero los dos gigantes en el dominio tienen sus problemas. En papel, el marco .net parece mucho mejor, y es especialmente adecuado para la programación funcional, pero en la práctica sigue siendo muy centrado en Windows y el soporte para Linux / MacOS es terrible, no tan bueno como debería ser, por lo que no vale la pena considerarlo. Java ahora es una máquina virtual madura, pero me molesta en algunos niveles: no me gustan las formas en que trata con los ejecutables, los genéricos y escribe GUIs terribles (aunque estas cosas no son tan malas).


¿Estás seguro de que realmente necesitas un lenguaje funcional? Hice la mayor parte de mi programación en lisp, que obviamente es un lenguaje funcional, pero he descubierto que la programación funcional es más una mentalidad que una característica de lenguaje. Estoy usando VB en este momento, que creo que es un excelente lenguaje (velocidad, soporte, IDE) y básicamente uso el mismo estilo de programación que hice en lisp: las funciones llaman a otras funciones que llaman a otras funciones, y las funciones generalmente son 1 -5 líneas de largo.

Sé que Lisp tiene un buen rendimiento, se ejecuta en todas las plataformas, pero está un poco anticuado en términos de cómo el soporte actualizado para características como gráficos, multihilo, etc.

He echado un vistazo a clojure, pero si no te gusta Java, probablemente no te gustará clojure. Es un lenguaje funcional estilo lisp implementado en la parte superior de java, pero probablemente te encuentres usando las bibliotecas java todo el tiempo, lo que agrega la verbosidad de java. A mí me gusta el tartamudeo, pero no me gustaba el clojure a pesar de las exageraciones.

¿También está seguro de sus requisitos de rendimiento? Matlab es un lenguaje excelente para muchos cálculos científicos, pero es un poco lento y odio leerlo. Puede que le resulte útil, aunque especialmente en conjunción con otros lenguajes, para prototipos / escenarios / subunidades.


Acabas de describir Common Lisp ...


Asumiré que está lo suficientemente familiarizado con los idiomas que mencionó como para haberlos descartado como posibilidades. Por eso, no creo que exista un lenguaje que cumpla con todas sus expectativas. Sin embargo, todavía hay algunos idiomas que puede echar un vistazo a:

  1. Clojure Esto realmente es un lenguaje muy bonito. Su sintaxis se basa en LISP y se ejecuta en la JVM.

  2. D Esto es como C ++ hecho bien. Tiene todas las características que desea, excepto que es un poco débil en la programación funcional.

  3. Limpiar Esto se basa en gran medida en Haskell, pero elimina algunos de los problemas de Haskell. Las desventajas son que no es muy madura y no tiene muchas bibliotecas.

  4. Factor Syntactically está basado en Forth, pero tiene soporte para programación funcional similar a LISP, así como mejor soporte para clases.


Clojure y / o Scala son buenos candidatos para JVM


Creo que Common Lisp se ajusta bastante bien a tu descripción.

1.1: Rendimiento: las implementaciones modernas de CL están casi a la par con C. También hay interfaces de funciones extranjeras para interactuar con las bibliotecas de C, y ya se han realizado muchos enlaces (por ejemplo, la Biblioteca Científica de GNU).

1.2: de alto nivel y elegante: sí.

1.3: Principalmente funcional: Sí, pero también puede "imperativo" donde surja la necesidad; CL es "multi-paradigma".

1.4: Portabilidad: hay varias implementaciones con soporte diferente para cada plataforma. Algunos enlaces están en CLiki y ALU Wiki .

1.5: Orientado a objetos, preferiblemente bajo la filosofía de "todo es un objeto": CLOS, el sistema de objetos Common Lisp, está mucho más cerca de estar orientado a objetos que cualquiera de los lenguajes "rizados", y también tiene características que le encantarán. Miss en otro lado, como multimethods.

2.1: Escritura "no muy fuerte": CL tiene una tipografía dinámica y fuerte, que parece ser lo que usted quiere.

2.2: Herramientas: Emacs + SLIME (el modo de interacción Lisp superior para Emacs) es un IDE gratuito muy bueno. También hay un complemento para Eclipse (Cusp), y las implementaciones comerciales de CL también ofrecen un IDE propio.

2.3: Recolección de basura, pero traducida o compilada sin una máquina virtual. La imagen Lisp en la que estarás trabajando es un tipo de máquina virtual, pero creo que eso no es lo que quieres decir.

Otra ventaja es el desarrollo incremental: tiene un REPL (read-eval-print-print-loop) en ejecución que proporciona una interfaz en vivo en la imagen en ejecución. Puede compilar y recompilar funciones individuales sobre la marcha e inspeccionar el estado actual del programa en el sistema en vivo. No tienes interrupciones forzadas debido a la compilación.


Echa un vistazo a Erlang . Originalmente, Erlang estaba destinado a construir sistemas altamente paralelos y tolerantes a fallos. Es un lenguaje funcional, que abarca inmutabilidad y funciones de primera clase. Tiene un lanzamiento binario oficial de Windows y la fuente se puede compilar para muchas plataformas * NIX (hay una compilación de MacPorts, por ejemplo).

En términos de características de alto nivel, Erlang admite listas de comprensión, coincidencia de patrones, cláusulas de protección, datos estructurados y otras cosas que usted esperaría. Es relativamente lento en el cálculo secuencial, pero es bastante sorprendente si está haciendo un cálculo paralelo. Erlang se ejecuta en una máquina virtual, pero se ejecuta en su propia máquina virtual, que forma parte de la distribución.

Erlang, aunque no está estrictamente orientado a objetos, se beneficia de una mentalidad OO. Erlang usa una cosa llamada proceso como su unidad de concurrencia. Un proceso de Erlang es en realidad muy parecido a un subproceso nativo, excepto con mucho menos sobrecarga. Cada proceso tiene un buzón, se enviarán mensajes y se procesarán esos mensajes. Es bastante fácil tratar los procesos como si fueran objetos.

No sé si tiene mucho de bibliotecas científicas. Puede que no sea una buena opción para sus necesidades, pero es un lenguaje genial que pocas personas parecen conocer.


En mi opinión, hay tres candidatos viables: Haskell, Standard ML, OCaml. (Scala dice que se compila con los códigos JVM y, por lo tanto, es poco probable que sea lo suficientemente rápido cuando los programas deben ejecutarse durante días). Todos son principalmente funcionales. Voy a comentar donde tengo conocimiento.

Performante

  • OCaml ofrece el rendimiento más estable para todas las situaciones, pero el rendimiento es difícil de mejorar. Lo que obtienes es lo que obtienes :-)

  • Haskell tiene el mejor rendimiento paralelo y puede obtener un excelente uso de una máquina de 8 o 16 núcleos. Si su futuro es paralelo, le insto a que domine su disgusto por el sistema de tipos y aprenda a usar Haskell de manera efectiva, incluidas las extensiones de Data Parallel Haskell.

    La desventaja del rendimiento de Haskell es que puede ser bastante difícil predecir el espacio y el tiempo necesarios para evaluar un programa funcional perezoso. Existen excelentes herramientas de creación de perfiles, pero aún así se puede requerir un esfuerzo significativo.

  • El estándar ML con el compilador MLton ofrece un rendimiento excelente. MLton es un compilador de programa completo y hace un muy buen trabajo.

De alto nivel y elegante.

  • Sintácticamente Haskell es el claro ganador. El sistema de tipos, sin embargo, está lleno de restos de experimentos recientes. El núcleo del sistema de tipo es, sin embargo, de alto nivel y elegante. El mecanismo de "clase de tipo" es particularmente poderoso.

  • El estándar ML tiene una sintaxis fea pero un sistema de tipo muy limpio y semántico.

  • OCaml es el menos elegante, tanto desde el punto de vista de la sintaxis como desde el sistema de tipos. Los restos de experimentos pasados ​​son más molestos que en Haskell. Además, las bibliotecas estándar no admiten la programación funcional tan bien como cabría esperar.

Principalmente funcional

Haskell es puramente funcional; Estándar ML es muy funcional; OCaml es principalmente funcional (pero tenga cuidado con las cadenas mutables y con algunas omisiones sorprendentes en las bibliotecas; por ejemplo, las funciones de lista no son seguras para las listas largas).

Portabilidad

Los tres funcionan muy bien en Linux. Los desarrolladores de Haskell usan Windows y está bien soportado (aunque les causa agonía). Sé que OCaml funciona bien con OSX porque uso una aplicación escrita en OCaml que se ha portado a OSX. Pero estoy mal informado aquí.

Orientado a objetos

No se encuentra en Haskell o SML. OCaml tiene un sistema de OO estándar saturado en el lenguaje central, que no está bien integrado con otros idiomas.

No dices por qué estás interesado en la orientación a objetos. Los funtores ML y las clases de tipos Haskell proporcionan parte de la encapsulación y el polimorfismo (también conocido como "programación genérica") que se encuentran en C ++.

Tipo de sistema que puede ser subvertido.

Los tres idiomas proporcionan conversiones inseguras. En los tres casos, son una buena manera de obtener volcados de datos.

Me gusta poder hacer algún casting implícito.

Creo que encontrará el sistema de clase de tipo de Haskell a su gusto: puede obtener algunos efectos que son similares a los lanzamientos implícitos, pero seguros. En particular, los literales numéricos y de cadena se pueden convertir implícitamente a cualquier tipo que desee.

Herramientas

Hay herramientas de perfilado bastante buenas con Haskell. Estándar ML tiene herramientas de mierda. OCaml tiene básicamente un perfil estándar de Unix más un depurador inutilizable. (El depurador se niega a cruzar las barreras de abstracción y no funciona en el código nativo).

Mi información puede estar desactualizada; La imagen de las herramientas está cambiando todo el tiempo.

Basura recolectada y compilada a código nativo

Comprobar. Nada para elegir desde allí.

Recomendación

Supere su aversión a los sistemas de tipo seguro. Estudie las clases de tipos de Haskell (el artículo original de Wadler y Blott y un tutorial de Mark Jones puede ser esclarecedor). Profundice en Haskell y asegúrese de aprender acerca de la enorme colección de software relacionado en Hackage .


Muchos de sus requisitos se basan en rumores. Un ejemplo: la idea de que Mono es "terrible".

http://banshee-project.org/

Ese es el reproductor multimedia oficial de muchas distribuciones de Linux. Está escrito en C #. (¡Ni siquiera tienen una versión pública de Windows!)

Sus afirmaciones sobre el rendimiento relativo de varios idiomas son igualmente dudosas. Y requerir un lenguaje para no usar una máquina virtual es bastante irreal y totalmente indeseable. Incluso un sistema operativo es una forma de máquina virtual en la que se ejecutan las aplicaciones, que virtualiza los dispositivos de hardware de la máquina.

Aunque ganas puntos por mencionar herramientas (aunque no con suficiente prioridad). Como observó Knuth, la primera pregunta sobre un lenguaje es "¿Cómo es el depurador?"


Prueba Scala. Es un lenguaje funcional orientado a objetos que se ejecuta en la JVM, por lo que puede acceder a todo lo que se haya escrito en Java. Tiene todas sus características importantes y una de las características agradables de tener. (Obviamente no es el # 2.2 :) pero probablemente mejorará rápidamente.) Tiene una tipificación muy fuerte, pero con la inferencia de tipos no se interpone en su camino.


Puedes usar F # en mono; tal vez vale la pena echar un vistazo? Sé que el mono no es 100% perfecto (nada lo es), pero está muy lejos de ser "terrible"; la mayoría de las brechas están en cosas como WCF / WPF, que dudo que quieras utilizar desde FP. Esto parece ofrecer mucho de lo que desea (excepto que, obviamente, se ejecuta en una máquina virtual, pero obtiene un gran conjunto de bibliotecas disponibles en la negociación (es decir, la mayoría de .NET) - mucho más fácilmente que OCaml en el que se basa) .


Seguiría apostando por Python pero usando NumPy o algún otro módulo externo para el procesamiento de números o, alternativamente, haría la lógica en Python y los puntos de acceso en C / assembler.

Siempre estás renunciando a los ciclos por comodidad, mientras más confort hay, más ciclos. Por lo tanto sus requisitos son mutuamente exclusivos


Si le gusta usar listas para la mayoría de las cosas y le importa el rendimiento, use Haskell o Ocaml. A pesar de que Ocaml sufre de manera significativa, los flotadores en el montón deben estar empaquetados debido al diseño de la máquina virtual (pero los arreglos de los flotadores y los registros puramente flotantes no están empaquetados individualmente, lo que es bueno).

Si está dispuesto a usar matrices más que listas, o planea programar usando un estado mutable, use Scala en lugar de Haskell. Si desea escribir código multi-core con hilos, use Scala o Haskell (Ocaml requiere que usted lo bifurque).

La lista de Scala es polimórfica, por lo que una lista de ints es realmente una lista de objetos Int en caja. Por supuesto, puedes escribir tu propia lista de entradas en Scala que sería tan rápida, pero supongo que prefieres usar las bibliotecas estándar. Scala tiene tanta recursión de cola como es posible en JVM.

Ocaml falla en Vista 64 para mí, creo que porque solo cambiaron el enlazador en la última versión (3.11.1?), Pero las versiones anteriores funcionaron bien.

El soporte de la herramienta Scala está defectuoso en este momento si está utilizando versiones nocturnas, pero pronto será bueno. Hay plugins de eclipse y netbeans. Estoy usando emacs en su lugar. He utilizado con éxito la interfaz gráfica de usuario de eclipse y netbeans debugger en el pasado.

Ninguno de Scala, Ocaml o Haskell tiene bibliotecas estándar realmente excelentes, pero al menos puedes usar fácilmente las librerías de Java en Scala. Si usas mapreduce, Scala gana en la integración. Haskell y Ocaml tienen una cantidad razonable de librerías de terceros. Me molesta que haya combinadores con nombres diferentes para 2-3 tipos de mónadas en Haskell.

http://metamatix.org/~ocaml/price-of-abstraction.html puede convencerlo de quedarse con C ++. Es posible escribir Scala que sea casi idéntico en rendimiento a Java / C ++, pero no necesariamente en un alto nivel funcional o estilo OO.

http://gcc.gnu.org/projects/cxx0x.html parece sugerir que auto x = ... (inferencia de tipo para expresiones) y lambdas son utilizables. C ++ 0x con impulso, si puedes soportarlo, parece bastante funcional. La desventaja de que las bibliotecas que abusan de la plantilla de alto rendimiento de C ++ es, por supuesto, el tiempo de compilación.


Sus requisitos me parecen describir bastante bien a ocaml, a excepción de la escritura "no demasiado fuerte". En cuanto a las herramientas, uso y me gusta el modo tuareg para emacs. Ocaml debería ejecutarse en Windows (aunque no lo he usado yo) y es bastante similar a F #, FWIW.

También consideraría el ecosistema alrededor del lenguaje. En mi opinión, el principal inconveniente de Ocaml es que no tiene una gran comunidad y, por lo tanto, carece de la gran biblioteca de módulos de terceros que son parte de lo que hace que Python sea tan conveniente. Tener que escribir su propio código o modificar el módulo de prototipo de una sola persona que encontró en Internet puede consumir parte del tiempo que ahorra al escribir en un lenguaje funcional agradable.


Teniendo en cuenta sus necesidades, recomendaría VB en Mono o en una máquina virtual con Windows. Como dijo un póster anterior, lo primero que debe preguntarse acerca de un idioma es "¿Cómo es el depurador?" Y VB / C # tiene el mejor depurador. Solo es el resultado de todos los empleados de Microsoft que han golpeado al depurador y que los equipos están cerca para hacer un error (no se pretende hacer un juego de palabras) para solucionarlo.

Lo mejor de VB y C # es el gran conjunto de herramientas de desarrollo, comunidad, ayuda de Google, ejemplos de código, bibliotecas, software que interactúa con él, etc. He utilizado una amplia variedad de entornos de desarrollo de software en los últimos 27 años. y lo único que se acerca es el entorno de la máquina Xerox Lisp (mejor) y la máquina Symbolics Lisp (peor).


Versión corta : El lenguaje de programación D

Yum Yum Yum, eso es un gran conjunto de requisitos.

Como probablemente sepa, la orientación a objetos, la semántica de alto nivel, el rendimiento, la portabilidad y el resto de sus requisitos no suelen coincidir desde un punto de vista técnico. Vamos a dividir esto en una vista diferente:

Requisitos de sintaxis

  1. Presentación orientada a objetos
  2. Baja complejidad de gestión de memoria.
  3. Permite estilo de función.
  4. No es Haskell (maldita)

Requisitos de Backend

  1. Ayuno para la ciencia
  2. Basura recolectada

Sobre esta base, recomendaría el lenguaje de programación The D, que es un sucesor de C, que trata de ser todo para todas las personas.

Este artículo sobre D trata sobre sus aspectos de programación funcional. Está orientado a objetos, se recolecta basura y se compila en un código de máquina, por lo que es rápido.

Buena suerte