Upload
msdevmtl
View
390
Download
2
Embed Size (px)
Citation preview
Une introduction à la pensée fonctionnelle avec F#Kevin Avignon
AVANT DE COMMENCER LA PRÉSENTATION
Qui suis-je ?◦ Étudiant en génie des technologies de l’information (ÉTS)
◦ Stagiaire C# & F# en systèmes distribués chez Genetec
Contenu de la présentation1. Qu’est-ce que le paradigme fonctionnel ?2. Pourquoi s’intéresser à F# ?3. Les rudiments de F#4. Éléments clés de la pensée fonctionnelle5. Domaines d’application pour F#
1.Qu’est-ce que le paradigme fonctionnel?
Qu’est-ce qu’un paradigme de programmation ?
Style de programmation permettant de solutionner un problème informatique à
l'aide d'un langage (ex: C#, F#, VB.NET)
Exemples de paradigmes connus:
Procédurale (routine): Une série d’étapes à réaliser
Orienté-objet : Une collection d’objets en perpetuelle intéraction
Paradigme fonctionnelUne suite de fonctions mathématiques sans états
Une fonction mathématique est
Une expression (un algorithme avec ses entrées/sorties)
Générale
Sujet à réduction jusqu’à être irréductible
Les fonctions mathématiques n’admettent pas
Un changement d’état
La mutation des données
Pourquoi s’y intéresser?Le code est plus simple à gérer (aucun état)
Une gestion de la concurrence sans soucis
Les programmes sont généralement plus courts
2. Pourquoi s’intéresser à F#
General Purpose Language
F# est un langage de .NET, tout comme C# et VB.NET
Il est en mesure de répondre à une variété de problèmes en tout genre
S’intégre dans une solution .NET existante
Peut être exploité pour écrire de l’orienté-objet, impératif, fonctionnel ou autre
Des solutions simples pour des problèmes complexes
F# est concis et très expressif.
Moins de code nécessaire à lire et maintenir
Les fonctions de haut niveau encourage la réutilisabilité
FSIOutil permettant d’exécuter le code F# sans passer par debug
C’est un interpreteur à l’intérieur d’un command prompt
Permet également d’écrire du code pendant l’exécution
Pour être utiliser avec Visual Studio
Ctrl+Alt+F
Clique droit + Option Execute in Interactive
Chaque instruction doit être compléter avec “;;” au lieu d’un dans FSI
Justesse du code
Les valeurs(pas de variables) sont immuables par défaut
Immuabilité : L’état de la valeur ne peut être modifié après son attribution
Un système de type de données stricte
Autant votre pire ennemi que votre meilleur ami
Du pattern matching très flexible et exhaustif
Pattern matchingDéfinition : Une solution flexible pour modifier les données selon des règles spécifiques (patterns)
Permet de naviguer et décomposer simplement dans une structure de données
Chaque pattern est examiné pour valider si c’est compatible avec la structure de donnéestype LeavesColor= | Red = 0 | Green = 1
let printColorName (color:LeavesColor) = match color with | Color.Red -> printfn "Red" | Color.Green -> printfn "Green" | _ -> ()printColorName LeavesColor.RedprintColorName LeavesColor.Green
Aucun NullReferenceExceptionOption type
Type polymorphique encapsulant une valeur optionnelle
S’il y a une valeur à retourner -> Some<T>
Sinon -> None
N’est jamais à l’état null
Semblable aux nullableslet compute = function | None -> "No value" | Some x -> sprintf "The value is: %d" x
printfn "%s" ( Some 42 |> compute)(* The value is: 42 *)printfn "%s" (compute None) (* No value *)
Type inference par défautAvec C#, c’est fait en ayant recours au keyword var afin d’augmenter la lisibilité
Dictionary<List<SomeObject>,string[]> maVariable = new
Dictionary<List<SomeObject>,string[]>();
var maSecondeVariable = new Dictionary<List<SomeObject>,string[]>();
Le compilateur est intelligent et déduit rapidement le type exact d’une valeurL’information est déduite selon le contexteS’il manque d’information, il faut lui en donner davantage sinon la solution ne
“build” pas
let f a b = a + b + 100 //Retourne une valeur de type uint32 (int)
Moins de bugsSystème de type strict
Utiliser des Option types
Type inference
Immuabilité
Unit of Measures (custom unit)
[<Measure>] type foot
let distance = 3.0<foot>
// type inference for result
let distance2 = distance * 2.0
// type inference for input and output
let addThreeFeet ft = ft + 3.0<foot>
3. Les rudiments en F#
let bindingsKeyword très puissant permet de :
Faire du value binding ou attribuer une valeur à un symbol (nom de variable)
Déclarer une fonction
Déclarer une valeur locale/globale
Déclarer une valeur mutable
Control flow - les ifC’est une structure if-then-elseCe sont des expressions avec des branches de types équivalentesMieux vaut utiliser le pattern matching que if dans certains cas
// bad
let badF x =
if x = 1
then "a" else "b"
// best
let bestF x =
match x with
| 1 -> "a"
| _ -> "b"
Control flow - Les boucles
Comme la structure conditionnelle if, les boucles conservent une structure familière
Il s’agit malgré tout d’expressions
Les boucles retournent le type unit
S’apparent à void
C’est une absence de valeur représenté par ()
Les do binding demeurent locaux
Retournent également unit
Aucun équivalent de break ou continue
Control flow - for loopLa boucle for a la structure suivante :
for start - to | downto - do body-expression
Exemple: let f = for i in [1..10] do i + i |> ignore let newF = for i=10 downto 1 do i + i |> ignore
Control flow - foreachLa boucle foreach a la structure suivante :
for pattern in enumerable-expression dobody-expression
// Looping over a list.let list1 = [ 1; 5; 100; 450; 788 ]for i in list1 do printfn "%d" i
Control flow - while loopLa boucle while a la structure suivante :
while test expression dobody-expression
let lookForValue value maxValue = let mutable continueLooping = true let randomNumberGenerator = new Random() while continueLooping do // Generate a random number between 1 and maxValue. let rand = randomNumberGenerator.Next(maxValue) printf "%d " rand if rand = value then printfn "\nFound a %d!" value continueLooping <- false
Pipeline OperatorsPipe-forward operator ( |> )
Permet de passer une valeur intermédiaire à une fonction
Définit comme let (|>) f x = f x
[1..2..40] List.filter (fun value -> value %2 =0) |> printfn
Foward composition operator ( >> )Permet de composer la fonction f dans la fonction g
Se définit comme let ( >> ) f g x = g (f x )
Pipe-backward operator ( <| ) L’inverse du |>
Backward composition operator ( << )L’inverse du >>
Array, List & SeqIl s’agit des Collection types les plus importants et utilisés en F#
Array est une mutable collection ayant une taille fixe avec un 0 based index
let array1 = [| 1; 2; 3 |]
List est une collection immuable d’éléments ordonnés du même type
let list123 = [ 1; 2; 3 ]
Seq ou Sequence, est un équivalent à IEnumerable<T>
Tous les structures .NET dérivant de IEnumerable peuvent être des Seq
Il est possible de passer de l’un à l’autre en faisantCollectionType.toArray|toList|ToSeq
Tuples
Un regroupement de données pouvant être de type différent
(1,2) // Tuple de int, int
(1, “one”) Tuple de int, string
(1, 2.0, “three”, 3+1) //Tuple de int, float, string, expression
Donne une solution pour retourner plusieurs valeurs dans une fonction
Discriminated UnionsPermettent de rapidement prototyper un domaine d’affaires
Un ensemble de types hétérogènes
Les bons types de données
Les types non valides
Exemple :
type FormeGeometrique =
| Rectangle of longeur : int * largeur:int
|Cercle of int
RecordsSont immuables par défaut
Le record peut être mise à jour en faisant une copie et modifiant un champ spécifique
Se différencient des classe en orienté-objetSont seulement des propriété exposées
N’ont aucun constructeur
type Point3D = { x: float; y: float; z: float }let evaluatePoint (point: Point3D) = match point with | { x = 0.0; y = 0.0; z = 0.0 } -> printfn "Point is at the origin." | { x = xVal; y = 0.0; z = 0.0 } -> printfn "Point is on the x-axis. Value is %f." xVal | { x = 0.0; y = yVal; z = 0.0 } -> printfn "Point is on the y-axis. Value is %f." yVal | { x = 0.0; y = 0.0; z = zVal } -> printfn "Point is on the z-axis. Value is %f." zVal | { x = xVal; y = yVal; z = zVal } -> printfn "Point is at (%f, %f, %f)." xVal yVal zVal
Modules
Un regroupement logique du code tout comme un namespace
Un fichier est mis par défaut dans un module si rien n’est spécifié
S’apparente à une classe statique
4. Éléments clés de la pensée fonctionnelle
Les fonction sont les first citizens
C’est le paradigme fonctionnel, il est normal de prioriser les fonctions
Il faut voir une fonction comme étant un objet mathématique
Système dynamique et souple
Il est possible de passer une fonction comme un input
Il est possible de retourner une fonction comme output
Préserver les états orignauxEn manipulant un Collection type (list)
Penser à conserver son état original
C’est une entité à manipuler avec soin
Copier l’entité au besoin
Renforcer l’immuabilité dans vos programmes
Moins de bugs
Parallélisation et concurrence plus simple
Éviter la mutabilitéPermet d’éviter les side-effects
Les valeurs ne sont pas modifier après leur évaluaion
Rend le code thread-safe
S’assure qu’un thread ne peut modifier la valeur pendant son cycle
Pour mettre à jour une donnée
Il suffit simplement d’en faire la copie et utiliser cette copie
Retourner des fonctions non encapsulées
S’agit d’un calcul simple parfois
Exploiter la récursionLa fonction s’appelle elle-même jusqu’à temps de compléter son
itération
Augmente la lisibilité pour le programmeur
Réduit le code
Engendre théoriquement moins de bugs
Partial function applicationTechnique puissante
Ne pas avoir à complètement appliquer une fonction
Permet de définir une fonction à N paramètre
Obtenir le résultat final au moment voululet add42 = (+) 42 // partial application
add42 1
add42 3
S’éloigner de la mentalité OOCesser de penser en classe et exploiter
Records
Discriminated Unions
Cesser de penser aux méthodes à encapsuler
Créer des high order functions
L’héritage n’a plus sa place ici
Penser plutôt au partial function application
Pouvoir passer des fonctions en tant que paramètres
Pattern matching > if structurePermet de valider tous les cas possibles
Le compilateur mentionne si une situation a été oublié
Rend les cas à traiter plus simples à comprendre
Structure avec moins de “bruit”
5. Domaines d’application pour F#
Domaines d’applications 1.L’apprentissage machine
2.L’analyse de données
3.L’actuariat
4.Le développement web (WebSharper)
5.Le développement mobile (Xamarin)
6.Le traitement vidéo avec le GPU
7.Cloud computing
Période de questions
Réference intéressantes1.LIU,Tao. F# for C# Developers.2013 (Livre)
2.PETRICEK,Tomas,TRELFORD,Phillip. F# Deep dives.2015 (Livre)
3.http://fsharpforfunandprofit.com/learning-fsharp/
4.https://msdn.microsoft.com/en-us/library/hh967652.aspx
5.http://www.codeproject.com/Articles/462767/How-to-Think-Like-a-Functional-Programmer
6.http://fsharpconf.com/ (Conference F# en ligne le 4 mars 2016)
7.https://github.com/Kavignon/MSDEVMTL_SampleCode
8.https://github.com/ChrisMarinos/FSharpKoans