Clojure vs otros Lisps
comparison scheme (4)
El objetivo de mi pregunta no es comenzar una guerra de llama, sino determinar en qué circunstancias cada idioma es "la mejor herramienta para el trabajo".
He leído varios libros sobre Clojure ( Programación Clojure , Practical Clojure , The Joy of Clojure y la edición Manning Early Access de Clojure en acción ), y creo que es un lenguaje fantástico. Actualmente estoy leyendo Let Over Lambda, que trata principalmente con macros de Common Lisp, y, también, es un lenguaje muy interesante.
No soy un experto en Lisp (más novato), pero esta familia de idiomas me fascina, al igual que la programación funcional, en general.
Ventajas de Clojure (y desventajas de "otros"):
Se ejecuta en la JVM.
La JVM es un entorno de lenguaje muy estable y de alto rendimiento que cumple con el sueño de Sun de "Escribir una vez, ejecutar [casi] en cualquier lugar". Puedo escribir código en mi Macbook Pro, compilarlo en un archivo JAR ejecutable y luego ejecutarlo en Linux y Microsoft Windows con pocas pruebas adicionales.
La (Hotspot, y otra) JVM admite recolección de basura de alta calidad y una compilación y optimización just-in-time muy eficaz. Donde hace unos años, escribí todo lo que tenía que correr rápido en C, ahora no dudo en hacerlo en Java.
Modelo estándar, simple y multihilo. ¿Common Lisp tiene un paquete estándar multihilo?
Rompe la monotonía de todos esos paréntesis con
[]
,{}
y#{}
, aunque los expertos en Common Lisp probablemente me digan que con las macros del lector, puede agregarlas a CL.
Desventajas de Clojure :
- Se ejecuta en la JVM.
- Sin repetición de cola o continuaciones. ¿Common Lisp admite continuaciones? El esquema requiere apoyo para ambos, creo.
Ventajas de los demás (Common Lisp, en particular) (y desventajas de Clojure):
Macros de lectores definibles por el usuario.
Otras ventajas?
¿Pensamientos? Otras diferencias?
Aquí hay un buen video con una comparación de Scheme (Racket principalmente) y Clojure .
Para ser justos, Racket tiene sintaxis de azúcar (material de lectura adicional) para los tipos de datos también (#hash, #, corchetes, etc.)
Además, la única forma de Clojure de hacer una llamada correcta es recur
, esa es la desventaja de compilar en JVM.
Tenga en cuenta que
recur
es la única construcción de bucle que no consume pila en Clojure. No se optimiza la llamada de cola y se desaconseja el uso de llamadas propias para el bucle de límites desconocidos.recur
es funcional y su uso en posición de cola es verificado por el compilador. ( Formularios especiales ).
Mi lista personal de razones para preferir Clojure a otros Lisps (ps ¡Todavía creo que todos los Lisps son geniales!):
Se ejecuta en la JVM; por lo tanto, obtiene acceso automático a la fantástica ingeniería en la propia JVM (algoritmos avanzados de recolección de basura, optimización HotSpot JIT, etc.)
Muy buena interoperabilidad con Java: proporciona compatibilidad con la gran variedad de bibliotecas en el ecosistema de lenguaje Java / JVM. He utilizado Clojure como un lenguaje "pegamento" para conectar diferentes bibliotecas Java con buen efecto. Como también desarrollo mucho código Java, es útil para mí que Clojure se integre bien con las herramientas Java (por ejemplo, uso Maven, Eclipse con el complemento Counterclockwise para mi desarrollo en Clojure).
Buena sintaxis para vectores
[1 2 3]
, maps{:bob 10, :jane 15}
y sets#{"a" "b" "c"}
- Considero estas herramientas bastante esenciales para la programación moderna (además de las listas de ¡curso!)Personalmente me gusta el uso de corchetes para formas de enlace: por ejemplo,
(defn foo [ab] (+ ab))
- Creo que hace que el código sea un poco más claro de leer.Énfasis en la programación floja y funcional con estructuras de datos permanentes e inmutables; en particular, toda la biblioteca central de Clojure está diseñada para admitir esto por defecto
Excelente implementación de STM para la concurrencia multi-core. Creo que Clojure tiene la mejor historia de concurrencia de cualquier idioma en este momento (mira este video para mayor elaboración por el propio Rich Hickey )
Es un Lisp-1 (como Scheme), que personalmente prefiero (creo que en un lenguaje funcional tiene sentido mantener las funciones y los datos en el mismo espacio de nombres)
Tenga en cuenta que Clojure es un lenguaje y una implementación (generalmente en JVM). Common Lisp es un lenguaje con más de diez implementaciones diferentes. Entonces tenemos un desajuste de categoría aquí mismo. Por ejemplo, puede comparar Clojure con SBCL.
En general:
una versión de Common Lisp se ejecuta en la JVM: ABCL
la mayoría de las otras implementaciones de Common Lisp no
la mayoría de las implementaciones de CL tienen capacidades multitarea, una biblioteca proporciona una interfaz común
Common Lisp tiene sintaxis para arreglos. La sintaxis para otros tipos de datos puede ser escrita por el usuario y proporcionada por varias bibliotecas.
Common Lisp no admite la optimización de llamadas de cola ni las continuaciones. Las implementaciones proporcionan TCO y las bibliotecas proporcionan alguna forma de continuación.
Una diferencia importante entre Clojure y Common Lisp es que Clojure es más prescriptivo sobre la programación funcional. La filosofía, las expresiones idiomáticas y, hasta cierto punto, el lenguaje / las bibliotecas de Clojure fomentan y en ocasiones insisten en que programes de forma funcional (sin efectos secundarios, sin estado mutable).
Common Lisp definitivamente admite la programación funcional, pero también permite el estado mutable y la programación imperativa.
Por supuesto, hay una serie de beneficios para la programación funcional, en el área de la concurrencia y de lo contrario. Pero si todo lo demás sigue igual, también es bueno tener la opción de qué enfoque desea usar para cada situación. Clojure no prohíbe completamente la programación imperativa, pero es menos complaciente de ese estilo que Common Lisp.