Haskell, Lisp, et le niveau de verbosité
Pour ceux d'entre vous l'expérience dans les deux Haskell et certains saveur de Lisp, je suis curieux de savoir comment "agréable" (pour utiliser un horrible terme), c'est d'écrire du code en Haskell vs Lisp.
Un peu de contexte: je suis en train d'apprendre Haskell maintenant, après avoir travaillé avec le Schéma et CL (et une petite incursion dans Clojure). Traditionnellement, vous pouvez me considérer comme un fan de la dynamique des langues pour la concision et la rapidité qu'ils fournissent. Je me suis rapidement tombé en amour avec Lisp macros, comme il m'a donné encore une autre façon d'éviter de verbosité et passe-partout.
Je suis la recherche Haskell incroyablement intéressant, c'est de me présenter à des moyens de codage, je ne savais pas existé. Il a certainement quelques aspects qui semblent comme ils le feraient de l'aide dans la réalisation de l'agilité, comme la simplicité de l'écriture partielle des fonctions. Cependant, je suis un peu inquiet au sujet de perdre du Lisp macros (je suppose que je les perdre; pour dire la vérité j'ai peut-être tout simplement pas appris à leur sujet encore?) et le typage statique du système.
Aurait-il quelqu'un qui a fait une quantité décente de codage dans les deux mondes de l'esprit commenter sur la façon dont les expériences diffèrent, que vous préférez, et si cette préférence est la situation?
Vous devez vous connecter pour publier un commentaire.
Réponse courte:
[Note: Il y a un "Modèle Haskell" qui vous permet d'écrire des macros comme en Lisp, mais strictement parlant, on ne devrait jamais besoin il.]
Tout d'abord, ne vous inquiétez pas à propos de la perte des caractéristiques particulières comme le typage dynamique. Comme vous êtes familier avec la Common Lisp, remarquablement bien conçu langue, je suppose que vous êtes au courant qu'une langue ne peut pas être réduit à ses fonctions. Il est tout au sujet d'un ensemble cohérent, n'est-ce pas?
À cet égard, Haskell brille avec autant d'éclat que Common Lisp n'. Ses caractéristiques se combinent pour vous offrir un mode de programmation qui rend le code extrêmement courte et élégante. Le manque de macros est quelque peu atténué par la plus élaborée (mais, de même, plus difficile à comprendre et utiliser les concepts comme des monades et des flèches. Le système de type statique ajoute à votre alimentation plutôt que d'obtenir dans votre chemin comme il le fait dans la plupart des langages orientés objet.
D'autre part, la programmation Haskell est beaucoup moins interactif que Lisp, et l'énorme quantité de réflexion présente dans des langages comme Lisp n'est tout simplement pas s'adapter à la vision statique du monde que Haskell suppose. L'outil met à votre disposition, sont donc très différents entre les deux langues, mais difficile de les comparer l'un à l'autre.
Personnellement, je préfère le Lisp chemin de la programmation en général, car j'ai l'impression qu'il correspond à la façon dont je travaille mieux. Toutefois, cela ne signifie pas que vous êtes tenu de le faire ainsi.
Il y a moins de besoin pour la métaprogrammation en Haskell qu'en Common Lisp, car beaucoup de choses peuvent être structurés autour de monades et à la syntaxe intégré DSLs l'air moins en forme d'arbre, mais il y a toujours de Modèle Haskell, comme mentionné par ShreevatsaR, et même Liskell (Haskell sémantique + syntaxe Lisp) si vous aimez les parenthèses.
Concernant les macros, voici une page qui en parle : Bonjour Haskell, au Revoir Lisp. Il explique d'un point de vue où les macros sont tout simplement pas nécessaires en Haskell. Il est livré avec un court exemple pour la comparaison.
Exemple de cas où une macro LISP est nécessaire pour éviter d'évaluation de deux arguments :
Exemple de cas où Haskell n'est pas systématiquement évalue à la fois l'argument, sans avoir besoin de quelque chose comme une définition de macro :
Et voilà
delay
ne peut pas être une fonction.accept
est (E)DSL. Leaccept
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 le Schéma sur la diapositive 40. Le Haskell et d'un Système de fonctions de calcul est la même chose avec la même stratégie d'évaluation. Au mieux, la macro vous permet d'exposer plus de la structure de votre programme à l'optimiseur. Vous ne pouvez pas demander ce que un exemple où les macros augmenter la puissance expressive de la langue qui n'est pas reproduit par les paresseux de l'évaluation.accept
est la fonction qui fait le travail, mais ce n'est pas un DSL, c'est une fonction comme toutes les autres fonctions, et les choses comme de l'utiliser dans toutes les sous-listes, ou l'utilisation nécessaire dewhere
avec son propre champ est exactement ce que les macro-fait inutile. Comme pour les paresseux de l'évaluation -- vous ne l'utilisez pas, de manière significative, alors je ne vois pas comment est-ce que toute l'argumentation pertinente.accept
) -- c'est une des raisons pourquoi il est pas DSL;automaton
devenirletrec
,:
deveniraccept
,->
devenir rien dans cette version). Quoi que ce soit.Je suis un Common Lisp programmeur.
Avoir essayé Haskell il y a quelques temps mon bas de ligne, c'est de coller avec CL.
Raisons:
Pascal Costanza)
Haskell a ses propres mérites bien sûr, et un peu les choses d'une façon fondamentalement différente, mais il n'a tout simplement pas le couper dans le long terme pour moi.
dilbert = dogbert.hire(dilbert);
"?? Je doute que beaucoup Haskell les programmeurs peuvent même lire ce sans secousses un peu.En Haskell, vous pouvez définir une fonction si, ce qui est impossible en LISP. Ceci est possible à cause de la paresse, ce qui permet pour plus de modularité dans les programmes. Ce classique de papier: Pourquoi FP questions par John Hughes, explique comment la paresse améliore la composabilité.
fold
, par exemple, tandis que les non-stricte des fonctions de ne.Il y a des choses vraiment cool que vous pouvez obtenir en Lisp avec des macros qui sont lourd (si possible) en Haskell. Prenez par exemple le "memoize' macro (voir le Chapitre 9 de Peter Norvig du PAIP). Avec elle, vous pouvez définir une fonction, disons foo, puis il suffit de les évaluer (memoize 'foo), qui remplace foo définition globale avec un memoized version. Pouvez-vous obtenir le même effet en Haskell avec des fonctions d'ordre supérieur?
Que je continue mon Haskell voyage d'apprentissage, il semble que la seule chose qui l'aide à "remplacer" macros est la possibilité de définir vos propres opérateurs infixes et de personnaliser leur priorité et associativité des opérateurs. Un peu compliqué, mais un système intéressant!