Syntaxe
Les fondamentaux
Syntaxe - Clé
1er point fort de F♯ : langage succinct
Pour s'en rendre compte :
Passons rapidement en revue sa syntaxe
Ensuite vous pourrez commencer à jouer avec
☝ C'est à l'usage que l'on mesure le côté succinct de F♯
💡 F♯ est généralement plus succinct que C♯ sauf ce qui concerne le fait d'être explicite.
Commentaires
Variables → Valeurs
Mot clé
let
pour déclarer/nommer une valeurPas besoin de
;
en fin de déclarationLiaison/Binding est immutable par défaut
≃
const
en JS,readonly
pour un membre en C♯
Mutable avec
let mutable
et opérateur d'assignation<-
≃
let
en JS,var
en C♯Avec parcimonie, sur scope limité
Pièges ⚠️
Ne pas confondre la mutabilité d'une variable (la partie à gauche dans le binding) et la mutabilité d'un objet (la partie à droite du binding).
let
empêche le binding d'être modifié c'est-à-dire affecter une nouvelle valeur à une variable.let
n'empêche pas un objet de muter...
Noms
Mêmes contraintes qu'en C♯
Sauf apostrophe
'
(tick)permise dans nom au milieu ou à la fin (mais pas au début)
en fin de nom → indique une variante (convention)
Entre doubles backticks
permettent n'importe quel caractère, en particulier les espaces, à l'exception des sauts de ligne)
Shadowing
Consiste à redéfinir une valeur avec un nom existant → La valeur précédente n'est plus accessible dans le scope courant
Interdit au niveau d'un module mais autorisé dans un sous-scope
Pratique mais peut être trompeur → Peu recommandé, sauf cas particulier
Annotation de type
Optionnelle grâce à l'inférence
Type déclaré après nom
name: type
(comme en TypeScript)Valeur obligatoire, même si
mutable
👍
Constante
What: Variable effacée à la compilation, remplacée par sa valeur
≃
const
C♯ - même idée en TS queconst enum
How: Valeur décorée avec attribut
Literal
⚠️ Attributs entre[< >]
→ Erreur fréquente au début : utiliser[ ]
(comme en C♯)Convention de nommage recommandée : PascalCase
Nombre
⚠️ Pas de conversion implicite entre nombre
→ 💡 Utiliser fonctions int
, float
, decimal
String
Syntaxes complémentaires :
Chaîne avec interpolation en F# 8
Une chaîne interpolée ne peut pas contenir d'accolades ($"{xxx}"
) sauf à les doubler ($"{{xxx}}"
) . Depuis F# 8, c'est le caractère $ que l'on double ($$
) pour indiquer le nombre d'accolades à partir duquel il y a interpolation.
Encodage
Les littéraux de chaînes (EN: string literals) sont encodés en Unicode.
On peut travailler en ASCII grâce au suffixe B
mais on manipule alors un tableau de bytes :
Listes
Liste immuable → type spécial F♯ ≠ System.Collection.Generic.List<T>
Création avec
[]
, éléments séparés par;
ou saut de ligne + indentationNotation ML du type
int list
=List<int>
☝ Idiomatique que pour
array
,list
etoption
📍Type Option
Opérateurs sur les listes
::
Cons (pour "construction") → Ajoute un element en tête de liste@
Append → Concatène 2 listes..
Range →min..max
: plage de nombres ou de caractères entre le min et le max spécifiés (inclus) →min..step..max
:step
définit l'écart entre 2 nombres successifs dans la plage
⚠️ Il faut mettre un espace avant []
pour créer une liste, pour différencier de l'accès par index.
Module List
List
Ce module contient les fonctions pour manipuler une ou plusieurs listes.
map
, collect
Select()
, SelectMany()
map()
, flatMap()
exists
, forall
Any(predicate)
, All()
some()
, every()
filter
Where()
filter()
find
, tryFind
×
find()
fold
, reduce
Aggregate([seed]])
reduce()
average
, sum
Average()
, Sum()
×
Fonctions
Fonction nommée : déclarée avec
let
Convention de nommage : camelCase
Pas de
return
: la fonction renvoie toujours la dernière expression dans son corpsPas de
()
autour de tous les paramètres()
autour d'un paramètre avec annotation de type (1) ou déconstruit tel qu'un tuple (2)
Fonctions de 0-n paramètres
Paramètres et arguments séparés par espace
()
: fonction sans paramètre, sans argumentSans
()
, on déclare une valeur "vide", pas une fonction :
Fonction multi-ligne
Indentation nécessaire, mais pas de {}
Fonction anonyme
A.k.a. Lambda, arrow function
Déclarée avec
fun
et->
En général entre
()
pour question de précédence
☝ Note : taille de la flèche
Fine
->
en F♯, JavaLarge / fat
=>
en C♯, JS
Convention de noms courts
x
,y
,z
: paramètres de type valeurs simplesf
,g
,h
: paramètres de type fonctionxs
: liste dex
→x::xs
(ouh::t
) = head et tail d'une liste non vide_
: discard / élément ignoré car non utilisé (comme en C♯ 7.0)
Bien adapté quand fonction courte ou très générique :
Piping
Opérateur pipe |>
: même idée que |
UNIX
→ Envoyer la valeur à gauche dans une fonction à droite
→ Ordre naturel "sujet verbe" - idem appel méthode d'un objet
Chainage de pipes - Pipeline
Comme fluent API en C♯ mais natif : pas besoin de méthode d'extension 👍
Façon naturelle de représenter le flux de données entre différentes opérations → Sans variable intermédiaire 👍
Écriture :
Expression if/then/else
if/then/else
💡 if b then x else y
≃ Opérateur ternaire C♯ b ? x : y
☝ Si then
ne renvoie pas de valeur, else
facultatif
Expression match
match
Équivalent en C♯ 8 :
Exception
Handling Exception
💡 Il n'y a pas de try/with/finally
mais on peut faire imbriquer un try/finally
dans un try/with
.
Throwing Exception
→ Helpers failwith
, invalidArg
et nullArg
☝ Pour erreurs métier i.e. cas prévus, non exceptionnels :
→ Préférer le type Result
a.k.a Railway-oriented programming 📍 Types monadiques
Attributs
Les attributs fonctionnent comme en C# pour décorer une classe, une méthode, etc.
La subtilité vient de la syntaxe :
C#
[AttributUn][DeuxiemeAttribut]
ou[AttributUn, DeuxiemeAttribut]
→ Attributs entre[...]
et séparés par des,
F#
[<AttributUn>][<DeuxiemeAttribut>]
ou[<AttributUn>; <DeuxiemeAttribut>]
→ Attributs entre[<...>]
et séparés par des;
Ordre des déclarations
Déclaration précède usage
Au sein d'un fichier
Entre fichiers dépendants
☝ Importance de l'ordre des fichiers dans un
.fsproj
Bénéfice : pas de dépendances cycliques 👍
Indentation
Très importante pour lisibilité du code
Crée struct. visuelle qui reflète struct. logique / hiérarchie
{}
alignées verticalement (C♯) = aide visuelle mais < indentation
Essentielle en F♯ :
Façon de définir des blocs de code
Compilateur assure que indentation est correcte
👉 Conclusion :
F♯ force à bien indenter
Mais c'est pour notre bien
Car c'est bénéfique pour lisibilité du code 👍
Ligne verticale d'indentation
→ Démarre après let ... =
, (
, then
/else
, try
/finally
, do
, ->
(dans clause match
) mais pas fun
! → Commence au 1er caractère non whitespace qui suit → Tout le reste du bloc doit s'aligner verticalement → L'indentation peut varier d'un bloc à l'autre
Recommendations / Indentation
Utiliser des espaces, pas des
tabulationsUtiliser 4 espaces par indentation
Facilite la détection visuelle des blocs
... qui ne peut se baser sur les
{ }
comme en C♯
Éviter un alignement sensible au nom, a.k.a vanity alignment
Risque de rupture de l'alignement après renommage → 💥 Compilation
Bloc trop décalé à droite → nuit à la lisibilité
Complément
Dernière mise à jour
Cet article vous a-t-il été utile ?