216 votes

Dans quels domaines l'utilisation du fa# serait-elle plus appropriée que celle du do# ?

Au cours des dernières années, F# a évolué pour devenir l'un des langages entièrement pris en charge par Microsoft, utilisant de nombreuses idées issues d'OCaml, ML et Haskell.

Au cours des dernières années, le langage C# a étendu ses fonctionnalités générales en introduisant de plus en plus de fonctionnalités fonctionnelles : LINQ (compréhension des listes), Lambdas, Closures, Délégués anonymes et plus encore...

Compte tenu de l'adoption par C# de ces caractéristiques fonctionnelles et de la taxonomie de F# en tant que langage fonctionnel impur (il vous permet d'accéder aux bibliothèques du cadre ou de modifier 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 d'entre eux ait ses propres priorités opposées.

Je suis intéressé par tout modèle réussi employant ces deux langages dans vos programmes polyglottes de production, ainsi que par les domaines des logiciels de production (applications web, applications client, applications serveur) que vous avez écrits en F# au cours de l'année écoulée et que vous auriez écrits auparavant en C#.

267voto

simon cousins Points 101

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

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

Unités de mesure Le secteur dans lequel je travaille est truffé d'unités. Les équations que j'ai mises en œuvre (souvent de nature géométrique) portaient sur des unités de temps, de puissance et d'énergie. Le fait que le système de type vérifie l'exactitude des unités des entrées et des sorties des fonctions représente un gain de temps considérable, tant en termes de tests que de lecture/compréhension du code. Il permet d'éradiquer toute une série d'erreurs que les systèmes précédents étaient susceptibles de commettre.

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

Tests unitaires Le code écrit à l'aide de fonctions sans effet de bord et de structures de données immuables est un plaisir à tester. Il n'y a pas d'interactions complexes dépendant du temps pour faire foirer les choses ou de grands ensembles de dépendances à simuler.

L'interopérabilité J'ai défini l'interface avec le moteur de calcul en C# et j'ai implémenté le calcul en F#. Le moteur de calcul pouvait alors être injecté dans n'importe quel module C# qui avait besoin de l'utiliser sans se soucier le moins du monde de l'interopérabilité. Sans faille. Le programmeur C# n'a jamais besoin de savoir.

Réduction du code La plupart des données introduites dans le moteur de calcul se présentaient sous la forme de vecteurs et de matrices. Les fonctions d'ordre supérieur les mangent pour le petit déjeuner avec un minimum d'agitation et de code. C'est beau.

Absence de bogues La programmation fonctionnelle peut sembler étrange. Je peux être en train de 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. C'est presque binaire, soit ça ne compile pas, soit c'est correct. Les erreurs bizarres sont minimisées, la récursion et les fonctions d'ordre supérieur éliminent une grande partie du code de comptabilité qui introduit des erreurs bizarres.

Parallélisme La pureté fonctionnelle de l'implémentation qui en résulte permet d'exploiter le parallélisme inhérent au traitement des vecteurs de données. C'est peut-être ce que je vais faire maintenant que .NET 4 est sorti.

79voto

Tomas Petricek Points 118959

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 d'IntelliSense dans le cadre de projets antérieurs en C#, et je pense donc pouvoir 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 n'ai pas l'impression qu'il y ait une différence majeure entre C# et F# (cela fonctionne sans problème à partir de F#).

  • Les structures de données utilisées pour représenter le code du programme en F# sont principalement syndicats discriminés (qui ne sont pas pris en charge en C# de manière raisonnable) et cela rend un énorme pour ce type d'application (où vous devez traiter des structures arborescentes, comme le code d'un programme). Les unions discriminées et la recherche de motifs vous permettent de mieux structurer le code (conserver les fonctionnalités connexes en un seul endroit plutôt que de les disperser dans des méthodes virtuelles).

Auparavant, j'ai également travaillé sur le fournisseur CodeDOM pour F# (également écrit en F#). J'ai fait les 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, de sorte qu'il n'y a pas beaucoup d'espace pour inventer vos propres représentations de données (ce qui est le domaine dans lequel F# peut offrir des avantages intéressants).

  • Cependant, de nombreuses petites fonctionnalités de F# ont facilité la tâche. Puisque vous devez produire une chaîne de caractères, j'ai défini des opérateurs personnalisés pour construire des chaînes de caractères (à l'aide de StringBuilder ) et j'ai implémenté le code en les utilisant ainsi que des fonctions d'ordre supérieur (par exemple pour formater une liste d'objets séparés par la chaîne spécifiée, etc. foreach boucles).

Il s'agit de deux exemples relativement spécifiques, mais tous deux sont liés au travail avec des représentations de programmes, 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 (indépendamment des fonctionnalités fonctionnelles de C#).

47voto

Jon Harrop Points 26951

Nous avons livré le premier produit commercial au monde écrit en F# ( F# pour la visualisation ) et la seconde ( F# pour les nombres ) ainsi que la première littérature commerciale sur le fa# ( Le journal F#.NET ) et a écrit et publié le seul livre sur la version actuelle de F# ( Visual F# 2010 pour l'informatique technique ).

Nous avions déjà livré des produits similaires écrits en C# (par ex. cette ), mais nous avions aussi une solide expérience de l'utilisation commerciale d'OCaml. Nous avons été les premiers adeptes enthousiastes de F# lorsqu'il n'était encore qu'un prototype de recherche en 2006, car nous étions conscients du potentiel d'un langage moderne et décent semblable à OCaml sur la plateforme industrielle .NET et, par conséquent, nous avons fait pression pour qu'il soit produit. Le résultat a été un succès incroyable et F# a largement dépassé nos attentes les plus élevées.

Pour nous, F# présente de nombreux avantages 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 tous de nos applications LOB : nos transactions par carte de crédit sont traitées en code F#, nos notifications de produits sont envoyées en code F#, nos abonnements sont gérés en code F#, nos comptes sont gérés en code F#, etc. La principale caractéristique du langage qui porte ses fruits ici est sans doute le filtrage. Nous avons même utilisé F# pour colorer la syntaxe de notre dernier livre...

Notre bibliothèque de visualisation est un gros vendeur et sa fonctionnalité est centrée sur F# interactif fonctionnant dans Visual Studio. Notre bibliothèque complète cette fonctionnalité avec la possibilité de créer des visualisations interactives en 2D et 3D avec un minimum d'effort (par exemple, il suffit de Plot([Function sin], (-6., 6.)) pour tracer une onde sinusoïdale). En particulier, tous les problèmes de threading sont entièrement automatisés, de sorte que les utilisateurs n'ont pas à se préoccuper des threads et de la répartition de l'interface utilisateur. Les fonctions de première classe et la paresse ont été 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. La prévisibilité des performances s'est également avérée précieuse lorsque nos clients ont rencontré des bogues de performance lors des tests de performance de WPF et ont pu facilement réimplémenter le code concerné en F# pour une amélioration des performances de l'ordre de 10 000 fois. En raison de la nature libre de l'interface graphique de ce produit, le concepteur d'interface graphique et C# n'auraient pas été utiles.

Une grande partie de notre travail porte sur les méthodes numériques, y compris nos bibliothèques commerciales et nos livres. Dans ce domaine, F# est beaucoup plus fort que C# car il offre des abstractions de haut niveau (par exemple, des fonctions d'ordre supérieur) avec des pénalités de performance 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, 20 fois plus courte que le code Fortran de l'implémentation de référence de LAPACK, jusqu'à 3 fois plus rapide que la bibliothèque Intel Math Kernel Library adaptée au fournisseur 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 entrailles) et de C# (pour le shim), nous construisons des applications WPF qui servent de manuels interactifs pour nos produits logiciels et je suis en train d'écrire un nouveau livre, Multicore F#, qui sera le guide définitif de la programmation parallèle à mémoire partagée sur .NET.

27voto

JaredPar Points 333733

Au cours des 6 derniers mois, j'ai travaillé sur une couche d'émulation de Vim pour Visual Studio 2010. Il s'agit d'un produit gratuit dont toutes les sources sont disponibles 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 Visual Studio : C#

C'est le premier grand projet que je réalise avec F# et je dois dire que j'adore ce langage. A bien des égards, j'ai utilisé ce projet comme une méthode d'apprentissage de F# (et cette courbe d'apprentissage est tout à fait évidente si vous regardez l'historique du projet).

Ce que je trouve le plus étonnant à propos de F#, c'est la concision du langage. Le moteur Vim comprend l'essentiel de la logique, mais il ne représente que 30 % de la base de code globale.

13voto

Brian Points 82719

Une grande partie des tests unitaires pour les composants F# de Visual Studio sont écrits en F#. Ils s'exécutent en dehors de VS, en simulant les différents éléments de Visual Studio. La possibilité de construire des objets anonymes qui implémentent des interfaces est utile à la place d'un cadre/outil d'imitation. Je peux simplement é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 )

lorsque j'ai besoin d'une instance, par exemple d'un IVsOutputWindowPane à transmettre à un autre composant qui finira par appeler OutputString y Clear et inspecter ensuite le string list ref à la fin du test pour voir si la sortie attendue a été écrite.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X