Pour ceux d'entre vous expérimentés à la fois dans Haskell et dans une certaine saveur de LISP, je suis curieux de voir à quel point il est "agréable" (pour utiliser un terme horrible) d'écrire du code dans Haskell vs LISP.
Un peu d'histoire: 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 procurent. Je suis rapidement tombé amoureux des macros LISP, car cela m'a donné une autre façon d'éviter la verbosité et le passe-partout.
Je trouve Haskell incroyablement intéressant, car il me présente des méthodes de codage que je ne connaissais pas. 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 ne les ai peut-être pas encore connues?) Et le système de saisie statique.
Est-ce que quelqu'un qui a fait une bonne quantité de codage dans les deux mondes voudrait commenter la façon dont les expériences diffèrent, ce que vous préférez et si cette préférence est situationnelle?
Réponse courte:
[Remarque: Il existe un " Template Haskell " qui vous permet d'écrire des macros comme dans LISP, mais à strictement parler, vous ne devriez jamais avoir besoin il.]
Tout d'abord, ne vous inquiétez pas de perdre des fonctionnalités particulières comme la frappe dynamique. Comme vous êtes familier avec Common LISP, un langage remarquablement bien conçu, je suppose que vous savez qu'une langue ne peut pas être réduite à son ensemble de fonctionnalités. Il s'agit d'un ensemble cohérent, non?
À cet égard, Haskell brille tout aussi brillamment que Common LISP. Ses fonctionnalités se combinent pour vous fournir 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 augmente 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 dans Haskell est beaucoup moins interactive que LISP, et la quantité énorme 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 ensembles d'outils à votre disposition sont donc assez différents entre les deux langues, mais difficiles à comparer entre eux.
Personnellement, je préfère la méthode de programmation LISP en général, car je pense qu'elle correspond mieux à ma façon de travailler. Cependant, cela ne signifie pas que vous êtes obligé de le faire également.
Il y a moins besoin de métaprogrammation dans Haskell que dans LISP commun car beaucoup peut être structuré autour de monades et la syntaxe ajoutée fait que les DSL intégrés ressemblent moins à des arbres, mais il y a toujours un modèle Haskell, comme mentionné par ShreevatsaR , et even Liskell (sémantique Haskell + syntaxe LISP) si vous aimez les parenthèses.
Concernant les macros, voici une page qui en parle: Bonjour Haskell, au revoir LISP . Il explique un point de vue où les macros ne sont tout simplement pas nécessaires dans Haskell. Il est accompagné d'un court exemple de comparaison.
Exemple de cas où une macro LISP est requise pour éviter l'évaluation des deux arguments:
(defmacro doif (x y) `(if ,x ,y))
Exemple de cas où Haskell n'évalue pas systématiquement les deux arguments, sans avoir besoin de quelque chose comme une définition de macro:
doif x y = if x then (Just y) else Nothing
Et voilà
Je suis un programmeur LISP commun.
Après avoir essayé Haskell il y a quelque temps, mon objectif personnel était de rester avec 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 suffit pas à long terme pour moi.
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 plus de modularité dans les programmes. Cet article classique: Pourquoi FP importe par John Hughes, explique comment la paresse améliore la composabilité.
Il y a des choses vraiment cool que vous pouvez réaliser dans LISP avec des macros qui sont lourdes (si possible) dans Haskell. Prenons par exemple la macro `memoize '(voir le chapitre 9 du PAIP de Peter Norvig). Avec lui, vous pouvez définir une fonction, par exemple 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?
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!