Historique d'F#

Si l'on souhaite remonter aux objectifs premiers d'F#, l'on peut revenir vers 2000. Don Syme et Andrew Kennedy travaillent sur l'ajout des generics dans .NET. Le but était de proposer un mécanisme remplaçant les templates de C++, en se basant sur quelques principes : le code est spécialisé à l'exécution, avec la compilation just-in-time ; le code est partagé autant que possible ; les informations de typage sont gardées ; les valeurs ne sont jamais encapsulées dans un objet (boxing). Le papier qu'ils ont écrit à ce sujet est toujours très intéressant.

Ils avaient une contrainte importante : le mécanisme devait être aussi indépendant du langage que possible, car .NET se veut une plateforme ouverte à tous les paradigmes. À cette époque, il n'y avait aucun langage fonctionnel utilisant .NET ; il fallait une preuve de concept. C'est en parallèle de la conception des generics que Don Syme préparait cette preuve, F#. La toute première version date de 2003.

Héritage d'OCaml

F# repose en grande partie sur les bases de Caml. Plutôt que de partir sur un nouveau langage, ex nihilo, Don a choisi de reprendre ce qui a été le sujet de nombreux travaux de recherches, Caml, issu de la famille ML. Il a réutilisé la syntaxe, le système d'inférence de types, l'approche du lambda calcul, les types somme, le filtrage par motifs, la redéfinition d'opérateurs, la bibliothèque standard, etc. Le compilateur F# a d'abord été écrit avec Caml. Puis, longtemps, le code source était à la fois du Caml et du F# valides. Bien sûr, tout cela a évolué depuis. F# n'est pas la version .NET de Caml, c'est un langage à part, ayant grandi de son côté.

Héritage de C#

Par souci de compatibilité et d'intégration dans .NET, F# a beaucoup été influencé par C#. On y retrouve un certain d'aspects importants : l'introspection, le système objet, nominal et basé sur des interfaces, les méthodes d'extension, les méthodes variadiques (à nombre d'arguments variable), la surcharge de méthodes et d'opérateurs, les accesseurs, Linq, les énumérateurs, les types anonymes, les directives de préprocesseur...

Héritage d'Haskell

À Microsoft Research Cambridge, à une dizaine de mètres du bureau de Don Syme, se trouve celui de Simon Peyton Jones, le principal concepteur de GHC, l'un des meilleurs compilateurs Haskell. Ce n'est donc pas par hasard si ce magnifique langage a influencé F#.

Le fait de prendre en compte l'indentation pour comprendre le code, de rendre facultatifs les délimiteurs de blocs, vient en partie d'Haskell, même si ce n'est pas le seul autre langage à le faire (Python le fait aussi, mais de façon beaucoup plus restreinte).

Autre fonctionnalité : les compréhensions de listes. Même si ce n'est finalement que du sucre syntaxique, cela aide beaucoup lors des manipulations des listes, mais aussi d'autres structures. La notion des flux de calculs (computation workflows) est un calque des monades, fonctionnalité phare d'Haskell. Les quelques différences sont au niveau de la syntaxe et des utilisations faites, le principe de base étant le même.

De plus, comme en Haskell, il est relativement simple de manipuler des listes infinies et d'effectuer des calculs de façon paresseuse, quand on le souhaite (l'évaluation est stricte par défaut).

Enfin, il a été envisagé à plusieurs reprises d'intégrer le mécanisme de type classes (une forme de surcharge typique d'Haskell) dans F#. J'ignore toutefois si cela sera fait plus tard.

Innovations

Pour finir, certaines fonctionnalités du langage sont assez nouvelles. C'est notamment le cas des unités : chaque nombre peut avoir une unité de grandeur (mètre, joule, mètre par seconde, etc.) et le compilateur vérifie que tous les calculs sont cohérents. Il existe quelques langages qui savent faire cela (je pense notamment à Fortress, de Sun), mais je n'en connais aucun qui le combine avec un système d'inférence de types. Cela a été implémenté dans F# par Andrew Kennedy, qui avait fait sa thèse sur ce thème.

Les active patterns, une extension au système de filtrage par motifs, a fait l'objet de plusieurs travaux de recherche. F# fait partie des premiers langages à introduire cette notion en standard (il y a eu des propositions similaires en Haskell, appelées views).

Les quotations - le fait de manipuler à l'exécution l'arbre correspondant à une expression du langage - rappellent les expression trees de C#, en plus puissant et plus flexible (c'est notamment lié à la syntaxe du langage). En essayant les quotations pour la première fois, je n'ai toutefois pas pu m'empêcher de penser à Lisp. On reste cependant dans un monde statiquement typé, ce qui fait toute la différence.

Ce billet a été l'occasion de refaire un tour des fonctionnalités d'F# et d'expliquer comment ce langage se positionne par rapport aux autres. Je sais bien que tous les lecteurs ne connaissent pas toutes les notions citées, mais je suis prêt à détailler certains éléments du langage, s'il y a de la demande.