Greboca  

Suport technique et veille technologique

Aujourd’hui, les grandes entreprises et administrations publiques hésitent entre continuer à utiliser des logiciels propriétaires ou basculer vers les Logiciels Libres. Pourtant, la plupart des logiciels libres sont capables de bien traiter les données issues des logiciels propriétaire, et parfois avec une meilleur compatibilité.

C’est alors la barrière de la prise en main qui fait peur, et pourtant...

Les logiciels libres

L’aspect « Logiciel Libre » permet une évolution rapide et une plus grande participation des utilisateurs. Les aides et tutoriels foisonnent sur Internet ou sont directement inclus dans le logiciel lui-même.

Enfin, les concepteurs sont plus proches des utilisateurs, ce qui rend les logiciels libres plus agréable à utiliser et conviviaux.

Grâce à la disponibilité des logiciels libres, vous trouverez facilement des services de support techniques et la licence n’est plus un frein à l’utilisation de ces logiciels par votre personnel.

Notre support technique concerne essentiellement les logiciels libres, que ce soit sous forme de services ponctuels ou de tutoriels.

DLFP - Dépêches  -  Sortie du Glorious Haskell Compiler 7.8

 -  Avril 2014 - 

Ghc, le Glorious Haskell Compiler est sorti le 9 avril 2014 en version 7.8.1. Il s'agit du compilateur le plus populaire pour le langage Haskell. Haskell est un langage de programmation purement fonctionnel, avec un système de types sophistiqué. C'est le principal langage généraliste à utiliser une stratégie d'évaluation non-stricte par défaut : la valeur d'une expression n'est calculée que si elle est nécessaire.

Sommaire

Haskell en trois mots

Haskell est un langage de programmation purement fonctionnel, avec un typage statique fort, et une stratégie d'évaluation non stricte.

Le Glasgow Haskell Compiler est le principal compilateur Haskell, bien qu'il en existe d'autres.

Quelques exemples

L'inévitable hello world :

main = putStrLn "Saluton Ĉirkaŭaĵojn!"

Suite de Fibonnacci :

fibs :: Int -> Int
fibs 0 = 0
fibs 1 = 1
fibs n = fibs (n-1) + fibs (n-2)

-- Sous forme de liste infinie
fibs':: [Int]
fibs' = 0:1:(zipWith (+) fibs' (tail fibs'))

Un langage fonctionnel pur

La spécificité la plus marquante de Haskell, c'est qu'il s'agit d'un langage fonctionnel pur : une fonction appelée avec les mêmes arguments renverra toujours le même résultat, contrairement à une fonction comme input(message) en python.

Cela rend possible la transparence référentielle : une expression peut être remplacée par son résultat sans changer le comportement de l'application. Le raisonnement sur les équations est mené par substitution sans inquiétude des effets de bord.

Les entrée-sorties et autres effets de bord sont bien sûr possibles, mais ils sont distingués dans le système de type des calculs sans effets de bord. Cela permet des optimisations assez poussées et garanties correctes sur ces derniers. Cette distinction des effets de bord dans le système de type est déroutante au début, mais avec l'expérience, elle apporte un réel confort.

Avec un typage puissant

Le typage statique permet de vérifier à la compilation la cohérence d'un programme et de détecter de nombreuses classes d'erreurs fréquentes. Un type statique est une approximation réalisée pendant la compilation des valeurs rencontrées au cours de l'exécution. Il est extrêmement difficile de concevoir un système de type à la fois flexible (faiblement verbeux, avec une inférence utile), complet (de grain fin, éliminant plus de bugs) et correct (pas de programmes justes rejetés). Haskell essaye de trouver le juste milieu pour que la programmation généraliste soit efficace.

Les aficionados du typage dynamique et du « duck typing » argumentent que, lors du développement avec les langages statiquement typés (typiquement C/C++), une grande partie des ressources sont gaspillées à combattre le système de type. Le typage statique de Haskell est rendu extrêmement flexible grâce au polymorphisme paramétrique, similaire aux templates en C++, mais avec des possibilités d'inférence bien plus développées.

Un type polymorphique peut être restreint à l'aide de contraintes, c'est-à-dire un ensemble de spécifications (ou typeclasses). Par exemple pour insérer un élément dans un Set, il est nécessaire de pouvoir le comparer aux éléments déjà présents avec la méthode compare de la typeclasse Ord, d'où la contrainte Ord a => dans le type de insert :

insert :: Ord a => a -> Set a -> Set a

En pratique, dans les cas courants, la seule différence induite par le système de types entre un code haskell et le code python correspondant est la présence (facultative mais habituelle) en haskell de la signature de chaque fonction… Signatures qui sont en cours d'adoption par la communauté python.

Les nouveautés de ghc 7.8.1

Changements du langage

Typed holes

Grâce au typage fort de haskell, on se trouve souvent à utiliser les types pour guider la conception : on écrit d'abord les types dont on va avoir besoin, puis les signatures des fonctions. Ensuite, de proche en proche, l'implémentation des fonctions est guidée par les signatures. Bien sûr, dans les cas les plus complexes, il faut d'autres ressources que cette méthode, mais on y devient rapidement accro. L'extension typed holes (littéralement « trous typés ») permet d'utiliser cette démarche dans le corps d'une fonction.

Cette extension est souvent utilisée conjointement avec le drapeau -fdefer-type-errors qui transforme les erreurs de typage en warnings. Dans ghci, cela permet de charger toutes les définitions et de les manipuler même si leurs types sont incorrects. Une expression mal typée ou contenant des typed holes est équivalant à undefined et déclenchera une erreur uniquement si elle est évaluée.

En pratique, un hole est un _ placé dans le code à la place d'une expression manquante (ici à la dernière ligne):

getSensorReading :: IO Double
getSensorReading = return 123.45
 -- TODO: utiliser vraiment la sonde thermique

main = do
    tKelvins <- getSensorReading
    putStrLn ("Aujourd'hui il fait " ++ _ ( tKelvins - 273.15) ++ " degrés")

À la compilation, ghc émet une erreur (ou un warning si -fdefer-type-errors est activé) pour chaque hole, et affiche son type:

    Found hole ‘_’ with type: Double -> [Char]
    Relevant bindings include
      tKelvins :: Double (bound at toto.hs:6:5)
      main :: IO () (bound at toto.hs:5:1)
    In the expression: _
    In the first argument of ‘(++)’, namely ‘_ (tKelvins - 273.15)’
    In the second argument of ‘(++)’, namely
      ‘_ (tKelvins - 273.15) ++ " degrés"’

Dans notre exemple, le warning à la compilation nous indique que pour afficher la température dans le putStrLn, il nous faudra une fonction de type Double -> String. Une simple recherche dans hoogle nous indique que la fonction en question n'est autre que show.

OverloadedLists

Haskell repose sur une syntaxe très concise, la majeure partie du langage (Opérateurs, type de base, etc) étant définie dans le Prelude.
En revanche, ce n'est pas le cas des expressions littérales comme les nombres, les chaines de caractères et les listes. Par exemple [1, 2, 3] est interprété par le compilateur comme 1:2:3:[], où (:) et [] sont les constructeurs du type liste défini dans le Prelude. OverloadedStrings autorisait déjà les chaînes de caractères littérales avec d'autres types que [Char], notamment le type Text pour l'encodage UTF-8.

Cette extension OverloadedLists est documentée, elle permet d'utiliser la syntaxe des littéraux listes avec d'autres types, comme par exemple les vecteurs, les chaînes du module Text ou encore les ensembles.

Pour utiliser cette extension, il faut disposer d'une instance de la classe IsList. Il faudra donc attendre que ces instances soient intégrées aux bibliothèques haskell pour vraiment en profiter.

PatternSynonyms

Une autre extension, PatternSynonyms permet de donner un nom à un motif pour le filtrage.

La puissance des types de donnée algébrique (ADT) repose sur la possibilité de filtrer les données par motif, comme en Scala :

type Errno = Int
data Error = ErrorLibC Errno
           | ErrorIO IOException

errorToStr :: Error -> String
errorToStr (ErrorIO ioe)     = "Haskell's IOException: " ++ show ioe
errorToStr (ErrorLibC errno) = "LibC's errno: " ++ show errno

Chaque constructeur du type Error défini un motif, utilisé par la fonction errorToStr pour filtrer les erreurs. En revanche il n'était pas possible de définir ses propres motifs en plus des constructeurs. PatternSynonyms permet maintenant cela, par exemple pour avoir plusieurs motifs par constructeurs :

pattern ErrorPERM  = ErrorLibC 1
pattern ErrorNOENT = ErrorLibC 2
pattern ErrorSRCH  = ErrorLibC 3

errorToStr :: Error -> String
errorToStr (ErrorIO ioe) = "Haskell's IOException: " ++ show ioe
errorToStr  ErrorPERM    = "Operation not permitted"
errorToStr  ErrorNOENT   = "No such file or directory"
errorToStr  ErrorSRCH    = "No such process"
errorToStr (ErrorLibC errno) = "LibC's unknown errno: " ++ show errno

Les motifs synonymes sont aussi utilisés pour cibler des données profondément imbriquées : pattern Greetings name = 'h':'e':'l':'l':'o':' ':name. Par défaut il sont bidirectionnels : Greetings "world" est une valeur. Il est possible de définir des synonymes unidirectionnels lorsqu'il n'existe pas de bijection.

TypeFamilies fermées

Il est possible de déclarer une famille de type et ses instances dans la même clause, par exemple:

type family TF a where
    TF ([Bool]) = Int
    TF ([Bool],[Bool]) = Double

La famille est alors fermée, c'est-à-dire qu'il n'est pas possible de déclarer de nouvelles instances de TF.

Améliorations du compilateur

De nombreuses améliorations portent sur le compilateur lui-même, sans modifier le langage. Il est toujours plus rapide et économe en mémoire, notamment pour l'inférence de types. La compilation en parallèle de modules est activable avec la nouvelle option -jN.

Sur Linux, FreeBSD et Mac OS X, GHCi utilise maintenant le chargeur de code dynamique du système. Auparavant, un chargeur maison liait dynamiquement du code statique (.a) en mémoire. Pour utiliser cette fonctionnalité, il est nécessaire de compiler avec -dynamic-too pour générer des bibliothèques dynamiques (.dyn.so).

Améliorations de la génération de code

La qualité du code que ghc produit s'améliore aussi :

  • ghc est capable d'utiliser plus de types «nus» (unboxed), avec l'activation de -funbox-small-strict-fields par défaut;
  • le gestionnaire d'entrée sortie se parallélise mieux, «de façon linéaire jusqu'à 32 cœurs»;
  • le nouveau générateur de représentation intermédiaire Cmm a été activé, après une gestation de plusieurs années;
  • de nouvelles primitives (PrimOps) pour les instructions SIMD sont disponibles, pour l'instant uniquement avec le générateur LLVM.

Amélioration du gestionnaire d'entrée-sorties

Le gestionnaire d'entrée-sorties était un des points les plus critiques de la performance du runtime haskell. Dans la version 7.8.1, il a été grandement amélioré, en particulier dans un contexte multi-processeurs. Haskell devient ainsi de plus en plus crédible comme meilleur langage impératif du monde.

Compilation vers iOS

La gestion de la compilation croisée a été améliorée, ce qui permet notamment de compiler vers les systèmes iOS.

Compilation vers javascript avec ghcjs

La sortie de la version 7.8 devrait être accompagnée de la première version publique de ghcjs, un compilateur haskell vers javascript. Ce langage devient de plus en plus l'assembleur du client web et ghc prend ainsi en charge cette plateforme. Par rapport à Fay, qui est plus ancien, ghcjs cherche à compiler tout le langage haskell et pas seulement un sous-ensemble.

L'introduction à ghcjs permet de se faire une bonne idée de la façon de l'utiliser, en particulier pour les parties spécifiques à javascript.

Vers ghc 7.10

La version 7.10.1 sera la prochaine version majeure de ghc. On trouve sur le trac de ghc une liste de choses qui devraient figurer dans cette prochaine version. Certaines nouveautés de cette version sont préparées dès la 7.8.

Monad / Applicative

Ces deux concepts permettent d'associer un effet à une valeur : IO Int peut par exemple représenter l'action de la lecture d'un entier présent dans un fichier. La notion de foncteur applicatif est plus générale : toutes les monades sont des foncteurs applicatifs, tandis que l'inverse n'est pas nécessairement vrai. L'exécution des effets d'une monade peut dépendre des valeurs obtenues des effets précédents, contrairement aux foncteurs applicatifs où les effets sont exécutés dans l'ordre des arguments.

La classe de type Monad fut introduite dans les premières versions du langage pour gérer les entrées/sorties avec la monade IO. Lorsque, plus tard, la classe de type Applicative apparût dans la bibliothèque de base, Monad n'a pas été modifiée pour avoir Applicative comme super-classe.

Le but de la proposition Functor < Applicative < Monad est de corriger ce problème pour réduire la redondance (par exemple entre return et pure, liftM et fmap).
Ce changement, susceptible de rendre du code incompatible, est déjà signalé par un warning dans GHC 7.8 et sera officialisé dans la version 7.10.

Autres actualités de haskell

Olivier Charles a publié sur son blog l'édition 2013 de sa chronique 24 Days of Hackage qui offre une série d'introductions (avec des exemples) aux paquets majeurs disponibles sur Hackage. L'édition 2012 vaut également le détour, car elle couvre des paquets encore plus incontournables (base, containers, transformers, etc.).

Hackage 2

Le site hackage qui répertorie les paquets haskell libres, exécutables et bibliothèques est passé en version 2 en septembre 2013. L'aspect visuel a été amélioré, la recherche concerne maintenant aussi la description des paquets. La plupart des informations sont plus accessibles, en consultation mais aussi à la modification : le nouveau hackage est plus permissif, et il a une API rest plus étendue.

D'autres fonctionnalités ont été développées mais pas encore déployées, comme la gestion flexible des tags et le calcul des dépendances inverses.

Haskell platform

Il n'est généralement pas recommandé d'installer ghc seul, mais plutôt de récupérer la plateforme haskell, qui contient ghc ainsi que les bibliothèques les plus essentielles du monde haskell. Comme la version 7.8 de ghc a tardé, la plateforme n'a pas été mise à jour depuis la version 2013.2 de mai 2013. Une nouvelle version, adaptée à ghc 7.8 devrait sortir prochainement.

Lire les commentaires

par galbolle, Piezo, BAud, Bruno Michel, Benoît Sibaud, Lucas, tuiu pol, ZeroHeure, Xavier Claude

DLFP - Dépêches

LinuxFr.org

L’écriture et l’image, des âges farouches au texte électronique

 -  16 mai - 

Dans cette nouvelle excursion du Transimpressux, nous voyagerons chez les Mayas de l’époque pré-colombienne ainsi que dans la Rome antique. Nous (...)


GIMP 2.10.38 est sorti

 -  14 mai - 

Note : cette dépêche est une traduction de l'annonce officielle de la sortie de GIMP 2.10.38 du 3 mai 2024 (en anglais).Cette (peut-être dernière) (...)


Visualisation d’imageries médicales avec Invesalius

 -  13 mai - 

Nous allons parler ici des examens par imageries médicales de type scanner ou IRM. Un scanner est une série d’images faites aux rayons X et pour une (...)


Lettre d'information XMPP de mars 2024

 -  11 mai - 

N. D. T. — Ceci est une traduction de la lettre d’information publiée régulièrement par l’équipe de communication de la XSF, essayant de conserver les (...)


Conférence OW2con’24 : financements et nouveaux défis réglementaires pour les logiciels libres

 -  9 mai - 

Avec quatre discours inauguraux, quatre sessions en petits groupes et 30 présentations d’experts, la conférence annuelle d’OW2 traite des aspects (...)