web-dev-qa-db-fra.com

Dans quels domaines l'utilisation de F # pourrait-elle être plus appropriée que C #?

Au cours des dernières années, F # est devenu l'un des langages entièrement pris en charge par Microsoft, utilisant de nombreuses idées incubées dans OCaml, ML et Haskell.

Au cours des dernières années, C # a étendu ses fonctionnalités générales en introduisant de plus en plus de fonctionnalités de langage fonctionnel: LINQ (compréhension de liste), Lambdas, fermetures, délégués anonymes et plus ...

Compte tenu de l'adoption par C # de ces fonctionnalités et de la taxonomie de F # en tant que langage fonctionnel impur (il vous permet d'accéder aux bibliothèques du framework ou de changer l'état partagé lorsqu'une fonction est appelée si vous le souhaitez), il existe une forte similitude entre les deux langages bien que chacun ait ses propre accent primaire opposé polaire.

Je m'intéresse à tous les modèles réussis utilisant ces deux langues dans vos programmes de production polyglottes et également aux domaines des logiciels de production (applications Web, applications clientes, applications serveur) que vous avez écrits en F # au cours de la dernière année ou que vous auriez auparavant écrit en C #.

208
Peter McG

J'ai écrit une demande pour équilibrer le calendrier national de production d'électricité d'un portefeuille de centrales électriques et une position commerciale pour une société d'énergie. Les composants client et serveur étaient en C # mais le moteur de calcul a été écrit en F #.

L'utilisation de F # pour répondre à la complexité au cœur de cette application démontre clairement un sweet spot pour le langage dans les logiciels d'entreprise, à savoir l'analyse algorithmiquement complexe de grands ensembles de données. Mon expérience a été très positive. En particulier:

nités de mesure L'industrie dans laquelle je travaille est jonchée d'unités. Les équations que j'ai mises en œuvre (souvent de nature géométrique) traitaient des unités de temps, de puissance et d'énergie. Faire vérifier par le système de typage l'exactitude des unités des entrées et sorties des fonctions est un gain de temps énorme, tant en termes de test que de lecture/compréhension du code. Il supprime toute une classe d'erreurs auxquelles les systèmes précédents étaient sujets.

Programmation exploratoire Travailler avec des fichiers de script et le REPL (F # Interactive) m'a permis d'explorer l'espace de la solution plus efficacement avant de s'engager dans une implémentation que l'édition/compilation plus traditionnelle/run/test loop C'est un moyen très naturel pour un programmeur de développer sa compréhension du problème et des tensions de conception en jeu.

Test unitaire Le code écrit en utilisant des fonctions sans effet secondaire et des structures de données immuables est une joie à tester. Il n'y a pas d'interactions complexes dépendant du temps pour bousiller les choses ou de grands ensembles de dépendances à se moquer.

Interoperation J'ai défini l'interface avec le moteur de calcul en C # et implémenté le calcul en F #. Le moteur de calcul pourrait alors être injecté dans n'importe quel module C # qui devait l'utiliser sans aucun souci d'interopérabilité. Sans couture. Le programmeur C # n'a jamais besoin de savoir.

Réduction de code Une grande partie des données introduites dans le moteur de calcul étaient sous forme de vecteurs et de matrices. Les fonctions d'ordre supérieur les mangent pour le petit déjeuner avec un minimum d'agitation, un code minimal. Beau.

Manque de bugs La programmation fonctionnelle peut sembler étrange. Je peux travailler sur un algorithme, en essayant de faire en sorte que le code passe le vérificateur de type, mais une fois que le vérificateur de type est satisfait, cela fonctionne. Son presque binaire, soit il ne compilera pas ou c'est correct. Les erreurs de cas Edge étranges sont minimisées, la récursivité et les fonctions d'ordre supérieur suppriment beaucoup de code de comptabilité qui introduit des erreurs de cas Edge.

Parallélisme La pureté fonctionnelle de l'implémentation résultante la rend mûre pour exploiter le parallélisme inhérent au traitement des vecteurs de données. C'est peut-être là que j'irai maintenant maintenant que .NET 4 est sorti.

257
simon cousins

Pendant mon stage chez Microsoft Research, j'ai travaillé sur certaines parties de Visual Studio IntelliSense pour F # (qui est lui-même écrit en F #). J'avais déjà une certaine expérience avec IntelliSense de projets C # antérieurs, donc je pense que je peux comparer les deux.

  • L'extensibilité de Visual Studio est toujours basée sur COM, vous devez donc traiter des objets qui ne sont pas des objets .NET très agréables (et certainement pas fonctionnels), mais je ne pense pas qu'il y ait une différence majeure entre C # et F # (cela fonctionne bien de F #)

  • Les structures de données utilisées pour représenter le code de programme en F # sont principalement les unions discriminées (qui ne sont pas prises en charge en C # de manière raisonnable) et cela fait un - énorme différence pour ce type d'application (où vous devez traiter des structures arborescentes, telles que du code de programme). Les unions discrètes et la correspondance de modèles vous permettent de mieux structurer le code (conservez les fonctionnalités associées au même endroit plutôt que de les avoir partout dans les méthodes virtuelles)

Plus tôt, j'ai également travaillé sur le fournisseur CodeDOM pour F # (également écrit en F #). En fait, j'ai fait mes premières expériences en C #, mais j'ai ensuite converti le code en F #.

  • Le fournisseur CodeDOM doit traverser une structure représentée à l'aide d'objets .NET, donc il n'y a pas beaucoup d'espace pour inventer vos propres représentations de données (qui est le domaine où F # peut offrir de beaux avantages).

  • Cependant, il existe de nombreuses petites fonctionnalités F # qui facilitent la tâche. Comme vous devez produire une chaîne, j'ai défini des opérateurs personnalisés pour la construction de chaînes (en utilisant StringBuilder) et implémenté le code en les utilisant et des fonctions d'ordre supérieur (par exemple pour formater la liste des objets séparés en utilisant la chaîne spécifiée, etc.) , ce qui a supprimé beaucoup de répétitions (et de fastidieuses boucles foreach).

Ce sont deux exemples relativement spécifiques, mais tous deux sont liés à l'utilisation de représentations de programmes ou d'expressions ou, plus généralement, de structures de données arborescentes complexes. Je pense que dans ce domaine, F # est définitivement un bon choix (quelles que soient les fonctionnalités en C #).

76
Tomas Petricek

Nous avons expédié le premier produit commercial au monde écrit en F # ( F # pour la visualisation ) et le second ( F # pour les numériques ) ainsi que la première littérature commerciale sur F # ( The F # .NET Journal ) et a écrit et publié le seul livre sur la version actuelle de F # ( Visual F # 2010 for Technical Computing ).

Nous avions expédié des produits selon des lignes similaires écrites en C # (par exemple this ), mais nous avions également une solide expérience dans l'utilisation commerciale d'OCaml. Nous avons été les premiers à adopter avec enthousiasme F # alors qu'il s'agissait encore d'un prototype de recherche en 2006 parce que nous avons reconnu le potentiel d'avoir un langage OCaml moderne décent sur la plate-forme .NET de puissance industrielle et, par conséquent, nous avons poussé à le faire produire. Le résultat a été un succès incroyable et F # a largement dépassé nos attentes élevées.

Pour nous, F # présente de nombreux avantages différents et nous l'utilisons pour une grande variété d'applications. Nous avons des centaines de milliers de lignes de code F # en production. Nous utilisons maintenant F # pour toutes toutes nos applications LOB: nos transactions par carte de crédit sont traitées en utilisant le code F #, nos notifications de produits sont envoyées en utilisant le code F #, nos abonnements sont gérés en utilisant le code F #, nos comptes se font en utilisant le code F # et ainsi de suite. Peut-être que la principale caractéristique du langage qui paie des dividendes est la correspondance de modèles. Nous avons même utilisé F # pour mettre en évidence la syntaxe des couleurs de notre dernier livre ...

Notre bibliothèque de visualisation est un gros vendeur et ses fonctionnalités se concentrent sur l'exécution interactive de F # dans Visual Studio. Notre bibliothèque augmente cela avec la possibilité de générer des visualisations interactives 2D et 3D avec un minimum d'effort (par exemple juste Plot([Function sin], (-6., 6.)) pour tracer une onde sinusoïdale). En particulier, tous les problèmes de thread sont entièrement automatisés afin que les utilisateurs n'aient pas à se soucier des threads d'interface utilisateur et de la répartition. Les fonctions de première classe et la paresse étaient extrêmement précieuses lors de l'écriture de cette partie de la bibliothèque et les types de données algébriques ont été largement utilisés ailleurs. Les performances prévisibles se sont également révélées précieuses ici lorsque nos clients ont rencontré des bogues de performances dans les tests de réussite de WPF et ont facilement pu réimplémenter le code pertinent en F # pour une amélioration de 10 000 × des performances. En raison de la nature libre de l'interface graphique de ce produit, le concepteur de l'interface graphique et C # n'auraient pas été bénéfiques.

Une grande partie de notre travail s'articule autour des méthodes numériques, y compris nos bibliothèques commerciales et nos livres. F # est beaucoup plus puissant dans ce domaine que C # car il offre des abstractions de haut niveau (par exemple des fonctions d'ordre supérieur) avec des pénalités de performances minimales. Notre résultat le plus convaincant dans ce contexte a été la création d'une implémentation simple mais généralisée de la décomposition QR à partir de l'algèbre linéaire qui était 20 × plus courte que le code Fortran à partir de l'implémentation de référence de LAPACK, jusqu'à 3 × plus rapide que le processeur Intel Math Bibliothèque du noyau et plus générique car notre code peut gérer des matrices de tout type, même des matrices symboliques!

Nous développons actuellement des composants WPF/Silverlight dans un mélange de F # (pour les tripes) et C # (pour le shim), construisant des applications WPF pour agir comme des manuels interactifs pour nos produits logiciels et j'écris un nouveau livre, Multicore F #, qui sera le guide définitif de la programmation parallèle en mémoire partagée sur .NET.

42
Jon Harrop

Au cours des 6 derniers mois, j'ai travaillé sur une couche d'émulation Vim pour Visual Studio 2010. C'est un produit gratuit avec toutes les sources, il est disponible gratuitement sur github

Le projet est divisé en 3 DLL représentant une couche distincte. Chaque couche a une DLL de test unitaire correspondante.

  1. Moteur Vim: F #
  2. Couche WPF pour les ornements et l'intégration de l'éditeur: C #
  3. Couche d'intégration de Visual Studio: C #

C'est le premier projet majeur que j'ai jamais fait avec F # et je dois dire que j'aime la langue. À bien des égards, j'ai utilisé ce projet comme méthode d'apprentissage de F # (et cette courbe d'apprentissage est très évidente si vous regardez à travers l'histoire du projet).

Ce que je trouve le plus étonnant à propos de F #, c'est à quel point il est concis d'un langage. Le moteur Vim comprend la majeure partie de la logique, mais il ne représente que 30% de la base de code globale.

25
JaredPar

De nombreux tests unitaires pour les composants F # Visual Studio sont écrits en F #. Ils s'exécutent en dehors de VS, se moquant des différents bits de Visual Studio. La possibilité de contrer des objets anonymes qui implémentent des interfaces est utile à la place d'un framework/outil moqueur. Je peux juste écrire

let owpe : string list ref = ref []
let vsOutputWindowPane = 
    { new IVsOutputWindowPane with
        member this.Activate () = err(__LINE__)
        member this.Clear () = owpe := []; 0
        member this.FlushToTaskList () = VSConstants.S_OK
        member this.GetName(pbstrPaneName) = err(__LINE__)
        member this.Hide () = err(__LINE__)
        member this.OutputString(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
        member this.OutputStringThreadSafe(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
        member this.OutputTaskItemString(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText) = err(__LINE__)
        member this.OutputTaskItemStringEx(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText, pszLookupKwd) = err(__LINE__)
        member this.SetName(pszPaneName) = err(__LINE__)
    }            
DoSomethingThatNeedsA(vsOutputWindowPane)
assert( !owpe = expectedOutputStringList )

quand j'ai besoin d'une instance de par exemple un IVsOutputWindowPane pour passer à un autre composant qui appellera éventuellement OutputString et Clear, puis inspectera le string list ref objet à la fin du test pour voir si la sortie attendue a été écrite.

13
Brian

Nous avons écrit un langage de moteur de règles personnalisé en utilisant l'implémentation Lex-Yacc en F #

EDIT pour inclure la réponse au commentaire

Il n'y avait pas d'implémentation Lex/yacc en C #. (à notre connaissance, et le F # était)

Cela aurait été possible, mais une véritable douleur de construire l'analyse nous-mêmes.

Cette rubrique montre quelques autres suggestions, telles que les bibliothèques externes, mais notre architecte principal est un vieux maître des langages fonctionnels, donc le choix d'utiliser F # était une évidence.

9
johnc

Je travaille actuellement sur une compilation pour un langage de programmation. Le compilateur est entièrement écrit en F #. Le compilateur (à part la construction de Lex et de l'analyseur avec Lex/yacc) est essentiellement construit comme beaucoup de transformation d'une structure arborescente complexe.

Comme indiqué par d'autres, les unions discriminantes et la correspondance de modèles rendent le travail avec ce type de structure de données beaucoup plus facile que de vider le code dans des méthodes virtuelles "partout".

Je n'avais pas fait de travail en F # avant de commencer à travailler sur le compilateur (j'avais cependant des compilateurs volumineux dans une autre variante OCaml appelée MoscowML) et tout comme Jared déclare qu'il est visible dans le code quelles parties j'ai fait en premier mais en général j'ai trouvé F # facile pour apprendre à entrer dans l'état d'esprit FP après avoir codé principalement OO pendant une décennie prendra un peu plus de temps cependant).

travaillant avec des arbres de côté, je trouve la possibilité d'écrire du code déclaratif le principal avantage de FP (F # inclus) avoir un code qui décrit l'algorithme Im essayant de mettre en œuvre contrairement à C # décrivant comment J'ai implémenté l'algortihm est un énorme avantage.

7
Rune FS

Pas une expérience personnelle, mais vous pouvez écouter un épisode de DNR (je pense que c'est celui-ci ) où ils parlent à F folk de Microsoft. Ils ont écrit la plupart du système de notation Xbox Live, qui était loin d'être anodin, en utilisant F #. Le système a évolué massivement sur des centaines de machines et ils en étaient très satisfaits.

6
Igor Zevaka

Les gens de WebSharper ont construit un produit entier centré sur F # pour la programmation Web. Voici un article qui en parle:

http://www.sdtimes.com/content/article.aspx?ArticleID=34075

6
Brian

Voici une étude de cas sur une banque qui utilise F # avec C++/COM pour des choses:

http://www.Microsoft.com/casestudies/Case_Study_Detail.aspx?CaseStudyID=4000006794

6
Brian

Je ne sais pas si c'est en production, mais l'IA de "The Path of Go" a été écrite en F #:

http://research.Microsoft.com/en-us/events/techvista2010/demolist.aspx#ThePathofGo

The Path of Go: un jeu de recherche Microsoft pour Xbox 360

Cette démo présente un jeu Xbox 360, basé sur le jeu de Go, produit en interne chez Microsoft Research Cambridge. Go est l'un des jeux de société les plus célèbres d'Asie de l'Est, il est né en Chine il y a 4000 ans. Derrière la simplicité trompeuse du jeu se cache une grande complexité. Cela ne prend que quelques minutes pour apprendre, mais il faut une vie pour maîtriser. Bien que les ordinateurs aient dépassé les compétences humaines aux échecs, la mise en œuvre d'une IA compétitive pour Go reste un défi de recherche. Le jeu est propulsé par trois technologies développées à Microsoft Research Cambridge: une IA capable de jouer à Go, le langage F # et TrueSkill ™ pour correspondre aux joueurs en ligne. L'IA est implémentée en F # et relève le défi de fonctionner efficacement dans le cadre compact .net sur Xbox 360. Ce jeu vous place dans un certain nombre de scènes 3D visuellement époustouflantes. Il a été entièrement développé en code managé en utilisant l'environnement XNA.

(Quelqu'un d'autre a déjà mentionné "TrueSkill".)

5
Brian