Article de reference

Haskell

Haskell ( / ˈhæskəl / ) est un langage de programmation généraliste , typé statiquement , purement fonctionnel , avec inférence de type et évaluation paresseuse . l' enseignemen...

Haskell ( / ˈhæskəl / ) est un langage de programmation généraliste , typé statiquement , purement fonctionnel , avec inférence de type et évaluation paresseuse . l' enseignement , la recherche et les applications industrielles , Haskell a été le pionnier de plusieurs fonctionnalités de langage de programmation telles que les classes de types , qui permettent la surcharge d'opérateurs de type sûr , et les entrées/sorties monadiques (IO). Il doit son nom au logicien Haskell Curry . La principale implémentation de Haskell est le Glasgow Haskell Compiler (GHC).

La sémantique de Haskell est historiquement basée sur celle du langage de programmation Miranda , qui a servi à concentrer les efforts du groupe de travail initial de Haskell. La dernière spécification formelle du langage a été réalisée en juillet 2010, tandis que le développement de GHC continue d'étendre Haskell via des extensions de langage.

Haskell est utilisé dans le monde universitaire et dans l'industrie. En mai 2021 , Haskell était le 28e langage de programmation le plus populaire selon les recherches Google pour les tutoriels, et représentait moins de 1 % des utilisateurs actifs sur le référentiel de code source GitHub .

Histoire

Après la sortie de Miranda par Research Software Ltd. en 1985, l'intérêt pour les langages fonctionnels paresseux a augmenté. En 1987, il existait plus d'une douzaine de langages de programmation purement fonctionnels, non stricts . Miranda était le plus utilisé, mais il s'agissait d' un logiciel propriétaire . Lors de la conférence sur les langages de programmation fonctionnels et l'architecture informatique (FPCA '87) à Portland, dans l'Oregon , il y a eu un fort consensus sur la création d'un comité pour définir une norme ouverte pour ces langages. L'objectif du comité était de consolider les langages fonctionnels existants en un langage commun pour servir de base aux futures recherches sur la conception de langages fonctionnels.

Haskell 1.0 à 1.4

Haskell a été développé par un comité, essayant de rassembler des solutions prêtes à l'emploi lorsque cela était possible.

Les classes de types , qui permettent la surcharge d'opérateurs de type sûr , ont été proposées pour la première fois par Philip Wadler et Stephen Blott pour répondre à la gestion ad hoc des types d'égalité et de la surcharge arithmétique dans les langages de l'époque.

Dans les premières versions de Haskell jusqu'à la version 1.2, l'interaction utilisateur et les entrées/sorties (IO) étaient gérées à la fois par des mécanismes basés sur les flux et sur la continuation, qui étaient largement considérés comme insatisfaisants. Dans la version 1.3, les E/S monadiques ont été introduites, ainsi que la généralisation des classes de types à des types supérieurs (constructeurs de types). Avec la notation « do », qui fournit du sucre syntaxique pour la classe de type Monad, cela a donné à Haskell un système d'effets qui maintenait la transparence référentielle et était pratique.

D'autres changements notables dans les premières versions ont été l'approche de la fonction « seq », qui crée une dépendance de données entre les valeurs et est utilisée dans les langages paresseux pour éviter une consommation excessive de mémoire ; avec son passage d'une classe de type à une fonction standard pour rendre le refactoring plus pratique.

La première version de Haskell (« Haskell 1.0 ») a été définie en 1990. Les efforts du comité ont abouti à une série de définitions de langage (1.0, 1.1, 1.2, 1.3, 1.4).

Hiérarchie des classes de types dans le prélude Haskell à partir de GHC 7.10. L'inclusion de Folding et Traversable (avec les modifications correspondantes des signatures de type de certaines fonctions), et d'Applicative comme intermédiaire entre Functor et Monad, sont des écarts par rapport à la norme Haskell 2010.

Haskell 98

Fin 1997, la série a abouti à Haskell 98 , qui avait pour but de spécifier une version stable, minimale et portable du langage ainsi qu'une bibliothèque standard d'accompagnement pour l'enseignement et comme base pour les extensions futures. Le comité a expressément accueilli favorablement la création d'extensions et de variantes de Haskell 98 via l'ajout et l'incorporation de fonctionnalités expérimentales.

En février 1999, la norme de langage Haskell 98 a été initialement publiée sous le titre The Haskell 98 Report . En janvier 2003, une version révisée a été publiée sous le titre Haskell 98 Language and Libraries: The Revised Report . Le langage continue d'évoluer rapidement, l' implémentation du Glasgow Haskell Compiler (GHC) représentant la norme de facto actuelle .

Haskell 2010

Début 2006, le processus de définition d'un successeur à la norme Haskell 98, appelé de manière informelle Haskell Prime , a commencé. Il s'agissait d'un processus incrémental continu visant à réviser la définition du langage, produisant une nouvelle révision jusqu'à une fois par an. La première révision, appelée Haskell 2010 , a été annoncée en novembre 2009 et publiée en juillet 2010.

Haskell 2010 est une mise à jour incrémentielle du langage, intégrant principalement plusieurs fonctionnalités bien utilisées et non controversées, précédemment activées via des indicateurs spécifiques au compilateur.

  • Noms de modules hiérarchiques. Les noms de modules peuvent être constitués de séquences séparées par des points d'identifiants en majuscules, plutôt que d'un seul identifiant. Cela permet aux modules d'être nommés de manière hiérarchique (par exemple, Data.Listau lieu de List), bien que techniquement les modules soient toujours dans un seul espace de noms monolithique. Cette extension a été spécifiée dans un addendum à Haskell 98 et a été en pratique universellement utilisée.
  • L' interface de fonction étrangère (FFI) permet des liaisons avec d'autres langages de programmation. Seules les liaisons avec C sont spécifiées dans le rapport, mais la conception autorise les liaisons avec d'autres langages. Pour prendre en charge cela, les déclarations de types de données ont été autorisées à ne contenir aucun constructeur, ce qui permet d'obtenir des types nonce robustes pour les données étrangères qui ne pouvaient pas être construites en Haskell. Cette extension a également été précédemment spécifiée dans un addendum au rapport Haskell 98 et largement utilisée.
  • Les motifs dits n + k (définitions de la forme fact (n+1) = (n+1) * fact n) n'étaient plus autorisés. Ce sucre syntaxique avait une sémantique trompeuse, dans laquelle le code semblait utiliser l' (+)opérateur, mais en fait il était désucré pour coder en utilisant (-)and (>=).
  • Les règles d' inférence de type ont été assouplies pour permettre à davantage de programmes de vérifier le type.
  • Certains problèmes de syntaxe (changements dans la grammaire formelle) ont été corrigés : des protections de modèle ont été ajoutées, permettant la correspondance de modèle au sein des protections ; la résolution de la fixité de l'opérateur a été spécifiée d'une manière plus simple qui reflète la pratique réelle ; un cas limite dans l'interaction de la syntaxe lexicale des opérateurs et des commentaires du langage a été traité, et l'interaction de la notation do et if-then-else a été modifiée pour éliminer les erreurs de syntaxe inattendues.
  • Le LANGUAGE pragma a été spécifié. En 2010, des dizaines d'extensions du langage étaient largement utilisées et GHC (parmi d'autres compilateurs) a fourni le LANGUAGEpragma pour spécifier des extensions individuelles avec une liste d'identifiants. Les compilateurs Haskell 2010 sont tenus de prendre en charge l' Haskell2010extension et sont encouragés à en prendre en charge plusieurs autres, qui correspondent aux extensions ajoutées dans Haskell 2010.

Les normes futures

La prochaine spécification formelle était prévue pour 2020. Le 29 octobre 2021, avec la version 9.2.1 de GHC, l'extension GHC2021 a été publiée. Bien qu'il ne s'agisse pas d'une spécification de langage formelle, elle combine plusieurs extensions GHC stables et largement utilisées pour Haskell 2010.

Caractéristiques

Haskell propose des fonctions d'évaluation paresseuse , d'expressions lambda , de filtrage par motifs , de compréhension de liste , de classes de types et de polymorphisme de types . C'est un langage de programmation purement fonctionnel , ce qui signifie que les fonctions n'ont généralement pas d'effets secondaires . Une construction distincte existe pour représenter les effets secondaires, orthogonale au type des fonctions. Une fonction pure peut renvoyer un effet secondaire qui est ensuite exécuté, modélisant ainsi les fonctions impures d'autres langages.

Haskell dispose d'un système de typage statique et robuste basé sur l'inférence de type Hindley-Milner . Sa principale innovation dans ce domaine est les classes de types, conçues à l'origine comme un moyen de principe pour ajouter une surcharge au langage, mais qui ont depuis trouvé de nombreuses autres utilisations.

La construction qui représente les effets secondaires est un exemple de monade : un cadre général qui peut modéliser divers calculs tels que la gestion des erreurs, le non-déterminisme , l'analyse syntaxique et la mémoire transactionnelle logicielle . Ils sont définis comme des types de données ordinaires, mais Haskell fournit un peu de sucre syntaxique pour leur utilisation.

Haskell dispose d'une spécification ouverte et publiée, et de multiples implémentations existent. Son implémentation principale, le Glasgow Haskell Compiler (GHC), est à la fois un interpréteur et un compilateur de code natif qui fonctionne sur la plupart des plateformes. GHC est connu pour son système de types riche intégrant des innovations récentes telles que les types de données algébriques généralisés et les familles de types. Le jeu Computer Language Benchmarks met également en évidence son implémentation haute performance de la concurrence et du parallélisme .

Une communauté active et croissante existe autour du langage, et plus de 5 400 bibliothèques et outils open source tiers sont disponibles dans le référentiel de packages en ligne Hackage .

Exemples de code

Un programme "Hello, World!" en Haskell (seule la dernière ligne est strictement nécessaire) :

module Main ( main ) -- pas nécessaire dans l'interpréteur, est la valeur par défaut dans un fichier de module
main :: IO () -- le compilateur peut déduire cette définition de type main = putStrLn "Bonjour le monde !"

La fonction factorielle en Haskell, définie de différentes manières (la première ligne est l' annotation de type , qui est facultative et est la même pour chaque implémentation) :

factorielle :: ( intégrale a ) => a -> a
-- En utilisant la récursivité (avec l'expression "ifthenelse") 
factorielle n = si n < 2 alors 1 sinon n * factorielle ( n - 1 )
-- Utilisation de la récursivité (avec recherche de motifs) 
factorielle 0 = 1 factorielle n = n * factorielle ( n - 1 )
-- En utilisant la récursivité (avec gardes) 
factorielle n | n < 2 = 1 | sinon = n * factorielle ( n - 1 )
-- En utilisant une liste et la fonction "produit" 
factorielle n = produit [ 1 .. n ]
-- En utilisant fold (implémente "product") 
factorielle n = foldl ( * ) 1 [ 1 .. n ]
-- Factorielle de style sans point = foldr ( * ) 1 . enumFromTo 1

L'utilisation du combinateur à virgule fixe de Haskell permet d'écrire cette fonction sans aucune récursivité explicite.

importer Data.Function ( fix )
factorielle = fac fixe fac f x | x < 2 = 1 | sinon = x * f ( x - 1 )


Comme le type Integer a une précision arbitraire , ce code calculera des valeurs telles que factorial 100000(un nombre de 456 574 chiffres), sans perte de précision.

Une implémentation d'un algorithme similaire au tri rapide sur les listes, où le premier élément est pris comme pivot :

-- Annotation de type (facultative, identique pour chaque implémentation) 
quickSort :: Ord a => [ a ] ​​-> [ a ]
-- Utilisation des compréhensions de liste 
quickSort [] = [] -- La liste vide est déjà triée quickSort ( x : xs ) = quickSort [ a | a <- xs , a < x ] -- Trier la partie gauche de la liste ++ [ x ] ++ -- Insérer un pivot entre deux parties triées quickSort [ a | a <- xs , a >= x ] -- Trier la partie droite de la liste
-- Utilisation du filtre 
quickSort [] = [] quickSort ( x : xs ) = quickSort ( filtre ( < x ) xs ) ++ [ x ] ++ quickSort ( filtre ( >= x ) xs )

Implémentations

Toutes les implémentations répertoriées sont distribuées sous des licences open source .

Les implémentations entièrement ou presque conformes à la norme Haskell 98 incluent :

  • Le compilateur Glasgow Haskell (GHC) compile en code natif sur de nombreuses architectures de processeur différentes, et en ANSI C , via l'un des deux langages intermédiaires : C-- , ou dans les versions plus récentes, le bitcode LLVM (anciennement Low Level Virtual Machine). GHC est devenu le dialecte Haskell standard de facto . Il existe des bibliothèques (par exemple, des liaisons à OpenGL ) qui ne fonctionnent qu'avec GHC. GHC a également été distribué avec la plateforme Haskell .
  • Jhc, un compilateur Haskell écrit par John Meacham, met l'accent sur la rapidité et l'efficacité des programmes générés et sur l'exploration de nouvelles transformations de programmes.
    • Ajhc est un fork de Jhc.
  • Le compilateur Utrecht Haskell (UHC) est une implémentation Haskell de l'Université d'Utrecht . Il prend en charge presque toutes les fonctionnalités de Haskell 98 ainsi que de nombreuses extensions expérimentales. Il est implémenté à l'aide de grammaires d'attributs et est principalement utilisé pour la recherche sur les systèmes de types générés et les extensions de langage.

Les implémentations qui ne sont plus activement maintenues incluent :

  • Le système Gofer de l'utilisateur Haskell ( Hugs ) est un interpréteur de bytecode . Il était autrefois l'une des implémentations les plus utilisées, aux côtés du compilateur GHC, mais a maintenant été en grande partie remplacé par GHCi. Il est également livré avec une bibliothèque graphique.
  • HBC est une implémentation précoce prenant en charge Haskell 1.4. Elle a été implémentée par Lennart Augustsson dans Lazy ML et basée sur celui-ci. Elle n'a pas été activement développée depuis un certain temps.
  • nhc98 est un compilateur de bytecode axé sur la minimisation de l'utilisation de la mémoire.
    • Le compilateur York Haskell ( Yhc ) était un fork de nhc98, avec pour objectif d'être plus simple, plus portable et plus efficace, et d'intégrer le support de Hat, le traceur Haskell. Il disposait également d'un backend JavaScript , permettant aux utilisateurs d'exécuter des programmes Haskell dans des navigateurs Web .

Les implémentations qui ne sont pas entièrement conformes à Haskell 98 et qui utilisent une variante du langage Haskell incluent :

  • Eta et Frege sont des dialectes de Haskell ciblant la machine virtuelle Java .
  • Gofer est un dialecte éducatif de Haskell, avec une fonctionnalité appelée classes constructeurs , développée par Mark Jones. Il est supplanté par le système Gofer de Haskell User (Hugs).
  • Helium, un nouveau dialecte de Haskell. L'objectif est de faciliter l'apprentissage grâce à des messages d'erreur plus clairs en désactivant les classes de types par défaut.

Applications notables

  • Agda est un assistant de preuve écrit en Haskell.
  • Cabal est un outil permettant de créer et d'empaqueter des bibliothèques et des programmes Haskell.
  • Darcs est un système de contrôle de révision écrit en Haskell, avec plusieurs fonctionnalités innovantes, comme un contrôle plus précis des correctifs à appliquer.
  • Glasgow Haskell Compiler (GHC) est également souvent un banc d'essai pour les fonctionnalités de programmation fonctionnelle avancées et les optimisations dans d'autres langages de programmation.
  • Git-annex est un outil de gestion de fichiers de données (volumineux) sous contrôle de version Git . Il fournit également un système de synchronisation de fichiers distribué (assistant git-annex).
  • Linspire Linux a choisi Haskell pour le développement d'outils système.
  • Pandoc est un outil permettant de convertir un format de balisage en un autre.
  • Pugs est un compilateur et un interpréteur pour le langage de programmation alors nommé Perl 6, mais depuis renommé Raku .
  • TidalCycles est un langage spécial pour le codage en direct de motifs musicaux, intégré dans Haskell.
  • Xmonad est un gestionnaire de fenêtres pour le système X Window , entièrement écrit en Haskell.
  • GarganText est un outil collaboratif permettant de cartographier par analyse sémantique des textes sur n'importe quel navigateur Web , entièrement écrit en Haskell et PureScript , qui est utilisé par exemple dans la communauté de recherche pour établir des rapports et des feuilles de route de pointe.

Industrie

Web

Les frameworks Web notables écrits pour Haskell incluent :

Critique

Jan-Willem Maessen, en 2002, et Simon Peyton Jones , en 2003, ont discuté des problèmes associés à l'évaluation paresseuse tout en reconnaissant les motivations théoriques qui la sous-tendent. En plus des considérations purement pratiques telles que l'amélioration des performances, ils notent que l'évaluation paresseuse rend plus difficile pour les programmeurs de raisonner sur les performances de leur code (en particulier son utilisation de l'espace).

Bastiaan Heeren, Daan Leijen et Arjan van IJzendoorn ont également observé en 2003 quelques obstacles pour les apprenants de Haskell : « La syntaxe subtile et le système de types sophistiqué de Haskell sont une épée à double tranchant, très appréciée par les programmeurs expérimentés, mais aussi une source de frustration pour les débutants, car la généralité de Haskell conduit souvent à des messages d'erreur cryptiques. » Pour traiter les messages d'erreur, des chercheurs de l'Université d'Utrecht ont développé un interpréteur avancé appelé Helium, qui a amélioré la convivialité des messages d'erreur en limitant la généralité de certaines fonctionnalités de Haskell. En particulier, il désactive les classes de types par défaut.

Ben Lippmeier a conçu Disciple comme un dialecte strict par défaut (paresseux par annotation explicite) de Haskell avec un système de type et d'effet, pour répondre aux difficultés de Haskell à raisonner sur l'évaluation paresseuse et à utiliser des structures de données traditionnelles telles que les tableaux mutables. Il soutient (p. 20) que « la mise à jour destructive fournit au programmeur deux outils importants et puissants... un ensemble de structures de données efficaces de type tableau pour gérer des collections d'objets, et... la capacité de diffuser une nouvelle valeur à toutes les parties d'un programme avec une charge minimale pour le programmeur. »

Robert Harper , l'un des auteurs de Standard ML, a donné ses raisons pour ne pas utiliser Haskell pour enseigner la programmation d'introduction. Parmi celles-ci figurent la difficulté de raisonner sur l'utilisation des ressources avec une évaluation non stricte, le fait que l'évaluation paresseuse complique la définition des types de données et le raisonnement inductif, et l'« infériorité » du système de classes (ancien) de Haskell par rapport au système de modules de ML.

L'outil de construction de Haskell, Cabal , a toujours été critiqué pour sa mauvaise gestion de plusieurs versions de la même bibliothèque, un problème connu sous le nom de « l'enfer de Cabal ». Le serveur Stackage et l'outil de construction Stack ont ​​été créés en réponse à ces critiques. Cabal lui-même dispose désormais d'un système de construction beaucoup plus sophistiqué, fortement inspiré de Nix , qui est devenu la valeur par défaut avec la version 3.0.

Langues apparentées

Clean est un proche parent de Haskell, légèrement plus ancien. Sa plus grande déviation par rapport à Haskell réside dans l'utilisation de types d'unicité au lieu de monades pour les entrées/sorties (E/S) et les effets secondaires.

Une série de langages inspirés de Haskell, mais avec des systèmes de types différents, ont été développés, notamment :

D'autres langues apparentées incluent :

  • Curry , un langage de programmation fonctionnel/logique basé sur Haskell.

Les variantes notables de Haskell incluent :

  • Haskell générique , une version de Haskell avec support du système de types pour la programmation générique .
  • Hume , un langage fonctionnel strict pour les systèmes embarqués basé sur des processus en tant qu'automates sans état sur une sorte de tuples de canaux de boîtes aux lettres à un élément où l'état est conservé par rétroaction dans les boîtes aux lettres, et une description de mappage des sorties vers les canaux sous forme de câblage de boîte, avec un langage d'expression et une syntaxe de type Haskell.

Conférences et ateliers

La communauté Haskell se réunit régulièrement pour des activités de recherche et développement. Les principaux événements sont les suivants :

À partir de 2006, une série de hackathons organisés a eu lieu, la série Hac, visant à améliorer les outils et les bibliothèques de langage de programmation.

Plus d articles de Worldlex Wiki

Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.

Explorer l index