Le but de ma question n'est pas de déclencher une guerre des flammes, mais plutôt de déterminer dans quelles circonstances chaque langue est «le meilleur outil pour le travail».
J'ai lu plusieurs livres sur Clojure ( Programming Clojure , Practical Clojure , The Joy of Clojure et l'édition Manning Early Access de Clojure in Action ), et je pense que c'est un langage fantastique. Je lis actuellement Let Over Lambda qui traite principalement des macros Common Lisp, et c'est aussi un langage très intéressant.
Je ne suis pas un expert Lisp (plutôt un débutant), mais cette famille de langages me fascine, tout comme la programmation fonctionnelle, en général.
Avantages de Clojure (et inconvénients des «autres»):
Fonctionne sur la JVM.
La JVM est un environnement de langage très stable et très performant qui répond assez bien au rêve de Sun: «Écrire une fois, exécuter [presque] n'importe où». Je peux écrire du code sur mon Macbook Pro, le compiler dans un fichier JAR exécutable, puis l'exécuter sous Linux et Microsoft Windows avec peu de tests supplémentaires.
La JVM (Hotspot et autres) prend en charge le garbage collection de haute qualité et la compilation et l'optimisation juste-à-temps très performantes. Là où il y a quelques années à peine, j'écrivais tout ce qui devait tourner vite en C, maintenant je n'hésite plus à le faire en Java.
Modèle standard, simple et multithreading. Common Lisp a-t-il un package multithreading standard?
Brise la monotonie de toutes ces parenthèses avec
[]
,{}
et#{}
, bien que les experts en Common Lisp me diront probablement qu'avec les macros de lecteur, vous pouvez les ajouter à CL.
Inconvénients de Clojure :
- Fonctionne sur la JVM.
- Pas de récursion de queue ni de continuations. Common Lisp prend-il en charge les continuations? Le régime nécessite un soutien pour les deux, je crois.
Avantages des autres (Common Lisp, en particulier) (et inconvénients de Clojure):
Macros de lecteur définissables par l'utilisateur.
D'autres avantages?
Pensées? D'autres différences?
Réponses:
Ma liste personnelle de raisons de préférer Clojure à d'autres Lisps (ps, je pense toujours que tous les Lisps sont excellents!):
Fonctionne sur la JVM - obtient ainsi un accès automatique à l'ingénierie fantastique de la JVM elle-même (algorithmes de récupération de place avancés, optimisation HotSpot JIT, etc.)
Très bonne interopérabilité Java - assure la compatibilité avec la vaste gamme de bibliothèques de l'écosystème du langage Java / JVM. J'ai utilisé Clojure comme langage «glue» pour connecter différentes bibliothèques Java avec un bon effet. Comme je développe également beaucoup de code Java, il est utile pour moi que Clojure s'intègre bien avec les outils Java (par exemple, j'utilise Maven, Eclipse avec le plugin Counterclockwise pour mon développement Clojure)
Belle syntaxe pour les vecteurs
[1 2 3]
, les cartes{:bob 10, :jane 15}
et les ensembles#{"a" "b" "c"}
- je considère ces outils assez essentiels pour la programmation moderne (en plus des listes bien sûr!)Personnellement, j'aime l'utilisation de crochets pour les formulaires de liaison: par exemple
(defn foo [a b] (+ a b))
, je pense que cela rend le code un peu plus clair à lire.Accent sur la programmation fonctionnelle paresseuse avec des structures de données persistantes et immuables - en particulier, toute la bibliothèque principale de Clojure est conçue pour prendre en charge cela par défaut
Excellente implémentation de STM pour la concurrence multicœur. Je crois que Clojure a la meilleure histoire de concurrence de toutes les langues pour le moment (voir cette vidéo pour plus d'élaboration par Rich Hickey lui-même )
C'est un Lisp-1 (comme Scheme), que je préfère personnellement (je pense que dans un langage fonctionnel, il est logique de conserver les fonctions et les données dans le même espace de noms)
la source
Gardez à l'esprit que Clojure est un langage et une implémentation (généralement sur la JVM). Common Lisp est un langage avec plus de dix implémentations différentes. Nous avons donc une inadéquation de catégorie ici. Vous pouvez par exemple comparer Clojure avec SBCL.
Généralement:
une version de Common Lisp s'exécute sur la JVM: ABCL
la plupart des autres implémentations Common Lisp ne le font pas
la plupart des implémentations CL ont des capacités multitâches, une bibliothèque fournit une interface commune
Common Lisp a une syntaxe pour les tableaux. La syntaxe des autres types de données peut être écrite par l'utilisateur et est fournie par diverses bibliothèques.
Common Lisp ne prend en charge ni l'optimisation des appels de queue ni les continuations. Les implémentations fournissent le TCO et les bibliothèques fournissent une forme de continuation.
la source
Une différence importante entre Clojure et Common Lisp est que Clojure est plus prescriptif en matière de programmation fonctionnelle. La philosophie, les expressions idiomatiques de Clojure et, dans une certaine mesure, le langage / les bibliothèques encouragent fortement et insistent parfois pour que vous programmiez de manière fonctionnelle (pas d'effets secondaires, pas d'état mutable).
Common Lisp prend définitivement en charge la programmation fonctionnelle, mais il permet également la programmation à états mutables et impérative.
Bien entendu, la programmation fonctionnelle présente un certain nombre d'avantages, dans le domaine de la concurrence et autres. Mais toutes choses étant égales par ailleurs, il est également bon d'avoir le choix de l'approche que vous souhaitez utiliser pour chaque situation. Clojure n'interdit pas complètement la programmation impérative, mais il est moins accommodant de ce style que Common Lisp.
la source
Voici une bonne vidéo avec une comparaison de Scheme (Racket principalement) et Clojure .
Pour être juste, Racket a également du sucre de syntaxe (trucs de lecteur supplémentaires) pour les types de données (#hash, #, crochets, etc.)
De plus, le seul moyen de Clojure de faire un appel de queue correct est de l'utiliser
recur
, c'est l'inconvénient de la compilation vers JVM.la source
trampoline
pour les appels de queue.