Pour ceux d'entre vous expérimentés à la fois dans Haskell et dans une certaine saveur de Lisp, je suis curieux de savoir à quel point il est «agréable» (pour utiliser un terme horrible) d'écrire du code en Haskell contre Lisp.
Un peu de contexte: j'apprends Haskell maintenant, après avoir travaillé avec Scheme et CL (et une petite incursion dans Clojure). Traditionnellement, vous pourriez me considérer comme un fan des langages dynamiques pour la brièveté et la rapidité qu'ils offrent. Je suis rapidement tombé amoureux des macros Lisp, car cela me donnait un autre moyen d'éviter la verbosité et le passe-partout.
Je trouve Haskell incroyablement intéressant, car il me présente des méthodes de codage dont je ne savais pas qu'elles existaient. Il a certainement certains aspects qui semblent aider à atteindre l'agilité, comme la facilité d'écriture de fonctions partielles. Cependant, je suis un peu préoccupé par la perte des macros Lisp (je suppose que je les perds; à vrai dire, je n'ai peut-être tout simplement pas encore appris à leur sujet?) Et le système de typage statique.
Est-ce que quelqu'un qui a fait une quantité décente de codage dans les deux mondes voudrait dire comment les expériences diffèrent, ce que vous préférez et si cette préférence est situationnelle?
la source
Tout d'abord, ne vous inquiétez pas de perdre des fonctionnalités particulières comme la saisie dynamique. Comme vous connaissez Common Lisp, un langage remarquablement bien conçu, je suppose que vous êtes conscient qu'un langage ne peut pas être réduit à son ensemble de fonctionnalités. Il s'agit d'un tout cohérent, n'est-ce pas?
À cet égard, Haskell brille tout aussi brillamment que Common Lisp. Ses fonctionnalités se combinent pour vous offrir un moyen de programmation qui rend le code extrêmement court et élégant. Le manque de macros est quelque peu atténué par des concepts plus élaborés (mais également plus difficiles à comprendre et à utiliser) comme les monades et les flèches. Le système de type statique ajoute à votre puissance plutôt que de vous gêner comme il le fait dans la plupart des langages orientés objet.
D'un autre côté, la programmation en Haskell est beaucoup moins interactive que Lisp, et l'énorme quantité de réflexion présente dans des langages comme Lisp ne correspond tout simplement pas à la vision statique du monde que Haskell présuppose. Les jeux d'outils mis à votre disposition sont donc assez différents entre les deux langues, mais difficiles à comparer.
Personnellement, je préfère la manière de programmer Lisp en général, car je pense que cela correspond mieux à ma façon de travailler. Cependant, cela ne signifie pas que vous êtes obligé de le faire également.
la source
Il y a moins besoin de métaprogrammation dans Haskell que dans Common Lisp car beaucoup peuvent être structurés autour de monades et la syntaxe ajoutée fait que les DSL embarqués ressemblent moins à un arbre, mais il y a toujours Template Haskell, comme mentionné par ShreevatsaR , et même Liskell (sémantique Haskell + Lisp syntaxe) si vous aimez les parenthèses.
la source
Concernant les macros, voici une page qui en parle: Hello Haskell, Goodbye Lisp . Il explique un point de vue où les macros ne sont tout simplement pas nécessaires dans Haskell. Il est livré avec un court exemple de comparaison.
Exemple de cas où une macro LISP est requise pour éviter l'évaluation des deux arguments:
Exemple de cas où Haskell n'évalue pas systématiquement les deux arguments, sans avoir besoin de quoi que ce soit comme une définition de macro:
Et voilà
la source
delay
ne peut pas être une fonction.accept
est le (E) DSL. Laaccept
fonction est l'analogue de la macro décrite dans les pages précédentes, et la définition dev
est exactement parallèle à la définition dev
dans Scheme sur la diapositive 40. Les fonctions Haskell et Scheme calculent la même chose avec la même stratégie d'évaluation. Au mieux, la macro vous permet d'exposer davantage la structure de votre programme à l'optimiseur. Vous pouvez difficilement prétendre cela comme un exemple où les macros augmentent la puissance expressive du langage d'une manière non reproduite par une évaluation paresseuse.automaton
devenirletrec
,:
deveniraccept
,->
devenir rien dans cette version). Peu importe.Je suis un programmeur Common Lisp.
Ayant essayé Haskell il y a quelque temps, mon résultat personnel était de m'en tenir à CL.
Les raisons:
Haskell a bien sûr ses propres mérites et fait certaines choses d'une manière fondamentalement différente, mais cela ne résout pas le problème à long terme pour moi.
la source
dilbert = dogbert.hire(dilbert);
" ?? Je doute que de nombreux programmeurs Haskell puissent même lire ceci sans trembler un peu.Dans Haskell, vous pouvez définir une fonction if, ce qui est impossible dans LISP. Cela est possible en raison de la paresse, qui permet une plus grande modularité dans les programmes. Cet article classique: Pourquoi la PF compte par John Hughes, explique comment la paresse améliore la composabilité.
la source
fold
, par exemple, alors que les fonctions non strictes le font .Il y a des choses vraiment cool que vous pouvez réaliser en Lisp avec des macros qui sont encombrantes (si possible) dans Haskell. Prenons par exemple la macro `mémoize '(voir le chapitre 9 du PAIP de Peter Norvig). Avec lui, vous pouvez définir une fonction, disons foo, puis simplement évaluer (mémoriser 'foo), qui remplace la définition globale de foo par une version mémorisée. Pouvez-vous obtenir le même effet dans Haskell avec des fonctions d'ordre supérieur?
la source
Alors que je continue mon parcours d'apprentissage Haskell, il semble qu'une chose qui aide à "remplacer" les macros est la possibilité de définir vos propres opérateurs d'infixe et de personnaliser leur priorité et leur associativité. Un peu compliqué, mais un système intéressant!
la source