Clojure vs autres Lisps [fermé]

93

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?

Ralph
la source
15
personnellement j'aime un genre de parenthèses;) ressemble à du code "plus propre"
Moe
3
D'après ce que j'ai lu sur votre liste d'avantages, je pense que vous aimerez peut-être aussi Erlang www.erlang.org
Peer Stritzinger
4
Clojure prend en charge la récursivité de queue explicite via la forme spéciale "recur". Cela vous permet d'obtenir tous les avantages de la récursivité de queue à condition que vous le demandiez explicitement (la seule exception est qu'elle ne prend pas actuellement en charge les récursions de queue mutuelles entre plusieurs fonctions).
mikera
1
Clojure prend également en charge les continuations, au moins dans le sens de «style de passage de continuation». Vous avez raison de dire qu'il n'a pas de suites de première classe. voir stackoverflow.com/questions/1173133/continuations-in-clojure
mikera
@mikera: récursion de queue sur une fonction. Deux fonctions qui s'appellent doivent être faites avec "trampoline", qui est une sorte de kludgy (mais élégant à sa manière :-)).
Ralph

Réponses:

52

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)

mikera
la source
2
+1 pour la STM. Il suffit à lui seul de justifier l'utilisation de Clojure.
André Caron
2
Vous pouvez toujours obtenir STM en utilisant la bibliothèque CL-STM.
Mike Manilone
2
@ AndréCaron uniquement si vous en avez besoin.
droite le
Si vous vouliez écrire une simple application Web et l'héberger sur, par exemple, un hôte bon marché à 5 $ / mois, ce n'est évidemment pas possible avec Clojure en raison de la JVM, n'est-ce pas?
Hexatonic
@Hexatonic Je ne suis pas très expérimenté mais il est difficile de croire qu'une machine utilisée de nos jours n'aurait pas de JVM.
MasterMastic
25

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.

Rainer Joswig
la source
24

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.

Fleurs de Charlie
la source
3
@Charlie Flowers: Je crois qu'en Common Lisp il est possible de programmer dans un style "purement fonctionnel" (support de structure de données persistante, etc.), mais nécessite de la discipline. Correct?
Ralph
2
Juste une clarification sur "pas d'effets secondaires, pas d'état mutable" - Clojure a un état mutable (les références, les atomes, les agents, etc. sont tous mutables) mais nécessite que vous y accédiez de manière contrôlée (c'est-à-dire via les mécanismes STM et transactionnels associés mise à jour de la sémantique)
mikera
5
@mikera: sauf que Clojure repose sur l'utilisation de bibliothèques Java pour être utilisable, et toutes ces bibliothèques nécessitent un style impératif et sont pleines d'effets secondaires. J'ai trouvé que les liaisons avec Java étaient un cadeau empoisonné ...
André Caron
1
@Andre - bien sûr, si vous décidez d'utiliser une bibliothèque qui nécessite un état mutable et une sémantique impérative, vous devez gérer cela. Ce n'est pas différent de si vous avez accédé à une telle bibliothèque à partir d'une autre langue. Mais vous avez deux options décentes: a) N'utilisez pas de telles bibliothèques - vous pouvez écrire du code parfaitement bon en Clojure pur ou b) envelopper la complexité de l'interfaçage avec ces bibliothèques dans une belle interface fonctionnelle de style Clojure, ce qui est généralement facile avec macros ou agents, etc. Dans l'ensemble, j'ai trouvé que la capacité d'exploiter les bibliothèques Java était un avantage bien plus important que le problème.
mikera
4
@mikera: les bibliothèques ont un avantage. Je fais juste remarquer que l'utilisation des bibliothèques Java (c'est l'un des principaux objectifs de Rich Hickey pour le langage) va vraiment à l'encontre de l'aspect "plus fonctionnel que les autres lisps" de Clojure. Mon commentaire voulait dire: "à moins que vous ne réécriviez / enveloppiez ces bibliothèques, vous obtiendrez du code impératif et ne bénéficierez pas des plus belles parties de Clojure".
André Caron
10

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.

Notez que recurc'est la seule construction de boucle qui ne consomme pas de pile dans Clojure. Il n'y a pas d'optimisation des appels de fin et l'utilisation d'auto-appels pour boucler des limites inconnues est déconseillée. recurest fonctionnel et son utilisation en position de queue est vérifiée par le compilateur. ( Formulaires spéciaux ).

Daniil
la source
Link est mort je suppose.
nawfal
1
@nawfal Je pense que je l'ai réparé
Daniil
6
Le lien est mort (encore?)
Compte à jeter
1
On dirait que la vidéo sur ce lien peut être trouvée ici: vimeo.com/22675078 .
GDP2
Il y a aussi trampolinepour les appels de queue.
HappyFace