# Premiers pas en OCaml/Fonctions

Ce chapitre est le plus important de la leçon. N'hésitez pas à le relire plusieurs fois et effectuer l'exercice dédié aux fonctions.

## Convention de nommage

Vous verrez à plusieurs reprises dans les définitions les notations suivantes :
* <mot en français> : À remplacer par :
** <type> : un type d'OCaml tel qu'int, float, bool, char, string, unit, <fun>, ...
** <expression> : une expression telle que x + 1.
** <paramètre> : un nom de paramètre ou une valeur constante tel que x ou 1.

## Les fonctions
### Qu'est-ce qu'une fonction ?

Les fonctions OCaml sont très proches des fonctions mathématiques. Par exemple
$f(x)=x$
s'écrit en OCaml
Les fonctions (ou abstractions) sont définies par la syntaxe suivante :

### Exemple d'utilisation

On peut par exemple créer une fonction qui prend un entier en paramètre et renvoie son successeur.
Voyons maintenant comment l’utiliser.

## Définition
### Qu'est-ce qu'une définition ?

Redéclarer à chaque fois une fonction devient vite pénible. Pour régler le problème, on utilise une définition qui consiste à donner un nom à une valeur. Il faut utiliser le mot-clef let pour assigner un nom à une expression.
On peut aussi effectuer une définition locale avec le mot-clef in:
Les définitions locales sont utiles pour factoriser des calculs répétitifs.

### Exemple d'utilisation des définitions

Pour assigner un entier à un nom.
On peut ensuite récupérer sa valeur à tout moment.

### Exemple d'utilisation des définitions locales

Si nous voulons effectuer le calcul suivant : $2*3*4+2*3$ Ici $2*3$ est calculé 2 fois. Nous pouvons résoudre ce problème en utilisant les définitions locales.

## Définition et fonctions

Nous pouvons procéder de même pour donner un nom à nos fonctions.
Reprenons l'exemple de la fonction successeur en lui donnant un nom
* Il est important de comprendre ici le résultat de l'interpréteur :
* val successeur : int -> int = <fun>
Disséquons le élément par élément :
* val successeur : : 'Successeur' est ici le nom de la définition.
* int -> int : La fonction prend un entier en paramètre et donne un entier en résultat.
* = <fun> : La valeur de la définition est une fonction.

## Fonctions à plusieurs paramètres

Une fonction à plusieurs paramètres peut être vue comme une suite de fonctions à un paramètre.
Le mot-clef fun permet de soumettre plusieurs paramètres à une fonction contrairement au mot-clef function.
* Il est important de bien comprendre le résultat de la fonction précédente :
* [...] int -> int -> int [...]
Il faut savoir que pour le type des fonctions le parenthésage à droite est implicite. Pour plus de compréhension, mettons des parenthèses. on obtient (int -> (int -> int)). On a donc une fonction qui prend en paramètre un entier et qui rend une fonction prenant en paramètre un entier et qui rend un entier. Imaginez que l’on passe à la fonction fxy qu'un seul paramètre : (2 -> (int -> int)) on récupère alors une fonction qui prend un entier en paramètre et retourne un entier en paramètre (int -> int).
Maintenant, imaginez que l’on passe à la fonction fxy deux paramètres : (2 -> (5 -> int)) on récupère un entier.
Vous remarquez ici que pour l'appel des fonctions le parenthésage à gauche est implicite. C'est très important si vous prenez l'exemple suivant :
La fonction rend 11 et non pas 16 (2 * 8) OCaml a parenthésé comme ci-dessous.
Pire si vous mettiez
pour rechercher le produit 3*3. le parenthésage sera effectué comme ci-dessous.
C'est pour cette raison qu'on a droit a une belle erreur de compilation.
Pour corriger ce problème, il faut mettre des parenthèses sur l'opération.

## Fonction sans paramètre

Imaginons maintenant que nous souhaitons une fonction qui renvoie un résultat mais qui n'a pas besoin de paramètre en entrée. Nous pourrions essayer de ne pas spécifier de paramètre comme ci-dessous.
Mais cela ne fonctionne pas.
L'astuce est d’utiliser le type unité.
Pour appeler la fonction, il suffit de lui passer en paramètre la seule valeur du type unité :.

## Sucre syntaxique

Il y a un raccourci d'écriture pour les fonctions.
C'est plus court mais je vous déconseille de l’utiliser tant que vous ne maîtrisez pas encore les fonctions.

## Déterminer le type d'une fonction

Vous avez le nom d'une fonction ? Vous souhaitez connaître le type de ses arguments sans chercher dans la documentation ? Il suffit simplement de marquer le nom de la fonction dans l'interpréteur pour récupérer son type.
Et cela marche aussi pour les opérateurs qui peuvent s'utiliser comme des fonctions. Il faut alors utiliser des parenthèses pour qu’ils soient considérés comme des fonctions.
Grâce à ceci, on sait que la fonction (+) peut s'utiliser de façon.
* Soit avec deux paramètres et la fonction renvoie alors un entier.
* Soit avec un paramètre et la fonction renvoie alors une fonction.
Sans vous en rendre compte, vous venez de recoder la fonction successeur.