définition de fonction
Dans les exemples précédents, nous avons utilisé des fonctions
fournies par DrScheme (on dit alors qu'elles sont prédéfinies).
Notons que ces fonctions sont de deux genres:
-
des fonctions qui sont implantées dans l'interpréteur -- c'est
le cas des fonctions que nous avons utilisées jusqu'alors --, on
parle alors de fonctions de base ou de primitives;
- des fonctions qui ont été écrites en Scheme, par les écrivains
de l'interpréteur ou par d'autres personnes, qui ont été
regroupées par centre d'intérêt et qui sont mises à disposition de
l'utilisateur, à condition que celui-ci le demande. On parle alors
d'unités de bibliothèque et on dit que l'utilisateur
demande le chargement d'une unité de bibliothèque. Par exemple,
le DrScheme qui vous est fourni possède une entrée dans le menu
MIAS qui peut charger l'unité de bibliothèque mias,
écrite par nos soins et qui comporte des fonctions, non présentes
dans Scheme, utiles pour ce cours.
On peut aussi définir ses propres fonctions à l'aide de
définitions. C'est un mécanisme d'abstraction qui permet
d'associer un « programme » à un nom.
Voici un énoncé « mathématique »:
Soit f la fonction qui associe à un nombre r le nombre p r2.
Calculer f(22) et f(Ö(2)).
(
Ö(2) est la racine carrée de 2)
La première phrase est une
définition de la fonction
f,
définition que l'on peut noter plus formellement par:
f : Nombre |
--> |
Nombre |
r |
|--> |
p r2 |
La seconde phrase demande d'évaluer deux
applications de la
fonction
f: d'abord appliquer
f avec l'
argument 22,
ensuite appliquer
f avec l'argument
Ö(2) (qu'il faut d'abord
évaluer).
On peut ensuite définir une autre fonction, par exemple
g:
g : Nombre × Nombre |
--> |
Nombre |
(r, h) |
|--> |
f(r) × h |
et demander d'évaluer
g(22, 5)...
Reprenons la première ligne de la définition formelle de la fonction
g:
Cette partie de la définition est appelée la
signature de la fonction:
La signature de la fonction est composée du nom de la fonction suivi
d'un caractère deux-points et du
type de la fonction:
le type de la fonction étant constitué par les types de ses arguments
(séparés par des ×), suivi
du signe --> et du type de son résultat.
Supposons que l'on veuille
calculer le poids au mètre d'un
tube en fer, de rayon extérieur 49mm et d'épaisseur 1mm (le fer est
de densité 7,87).
On peut utiliser la fonction
g à condition que l'on ait remarqué
qu'elle calculait le volume d'un cylindre, de rayon le premier
argument de la fonction et de hauteur le second argument de la
fonction. Notons bien que l'expression de calcul de la fonction
g
(que l'on utilise ou non la fonction
f, que l'on écrive
p r2 h
ou
h p r2...) nous importe peu pour calculer le poids au mètre
d'un tube en fer; tout ce qui nous intéresse c'est que cette fonction
calcule le volume d'un cylindre, de rayon le premier argument de la
fonction et de hauteur le second argument de la fonction. Cette
information est la
spécification de la fonction et, si l'on
veut réutiliser une fonction, on doit donner sa spécification:
g :
Nombre ×
Nombre -->
Nombre
g(
r,
h) renvoie le volume du cylindre de rayon
r et de hauteur
h.
voici l'expression pour calculer le poids au mètre:
7.87 × (
g(0.49, 10) -
g(0.48, 10))
Dans le premier énoncé précédent, pour la fonction
f, vous avez reconnu le
calcul de l'aire d'un disque, aussi prenons-nous un identificateur plus
« parlant ».
;;;
;;;
(define (aire-disque r)
(* 3.1416 (* r r))) ;
et on peut appliquer cette fonction:
;;;
(aire-disque 22) ->
1520.5344
;;;
(aire-disque (sqrt 2)) ->
6.283200000000002
Autre exemple:
;;;
;;;
;;;
(define (volume-cylindre r h)
(* 3.1416 r r h)) ;
et on peut appliquer cette fonction:
;;;
(volume-cylindre 22 5) ->
7602.6720000000005
Un dernier exemple:
;;;
;;;
(define (negative? x)
(< x 0))
fonction que l'on doit aussi essayer:
;;;
(negative? -5) ->
#T
(negative? 0) ->
#F
(negative? 5) ->
#F
Définition: un
prédicat est une fonction qui rend un booléen.
Convention: les prédicats ont des noms qui se terminent par
un point d'interrogation.
Une définition de fonction suit la règle de grammaire suivante:
<définition> |
-> |
(define (<nom-fonction><variable>*)
<corps> ) |
|
|
|
Cette règle de grammaire comporte une étoile derrière l'unité
syntaxique
<variable>. Cela indique qu'il y a, dans les mots
générés par cette règle de grammaire, un nombre quelconque
-- éventuellement 0 -- d'éléments de cette unité syntaxique.
Ainsi une définition de fonction débute par une parenthèse ouvrante et
le mot clef «
define » puis entre parenthèses il y a le nom
de la fonction suivi d'un nombre quelconque -- éventuellement 0 -- de
variables, différentes deux à deux, nécessaires à la fonction (autant
de variables qu'il y aura d'arguments lors de l'application de la
fonction) et enfin du corps de la fonction qui exprime comment on doit
calculer ce qu'elle rend et qui répond à la règle de grammaire suivante:
<corps> |
-> |
<définition> <corps> |
|
|
<expression> <expression>* |
|
|
|
Cette règle de grammaire est écrite sur deux lignes. Cela indique que
l'on peut prendre l'une ou l'autre des possibilités: un corps est une
définition suivie d'un corps ou une expression suivie d'un nombre
quelconque (éventuellement 0) d'expressions (ou encore un nombre
quelconque non nul d'expressions).
Remarque: dans ce cours, dans un premier temps, le corps sera
une expression.
Systématiquement, pour toute définition de fonction, on écrit sa
spécification sous forme de commentaires placés avant la définition,
chacune des lignes de commentaire débutant par trois points-virgules:
-
la première ligne (éventuellement les premières lignes pour des
raisons de présentation) de la spécification comporte la signature
de la fonction, le signe --> étant remplacé par -> et le
signe × étant remplacé par *;
- les lignes suivantes expliquent, en français, ce que renvoie la
fonction; pour faciliter les explications, cette partie débute par
une application de la fonction aux variables utilisées dans la
définition de cette dernière (par exemple, pour la fonction
aire-disque, la définition commence par(define
(aire-disque r) et l'explication commence par
(aire-disque r) rend:
...
;;;
;;;
(define (aire-disque r)
...
Il y a de nombreux exemples de spécifications ainsi écrites
dans la
carte de référence.
Intuitivement -- rappelons que nous aurons une vision plus formelle
ultérieurement --, l'évaluation d'une définition ajoute une fonction
-
que le programmeur peut utiliser dans l'écriture d'une
application,
sous réserve qu'il écrive le bon nombre d'arguments (à
savoir le nombre des variables de la définition de la fonction),
- en mémorisant comment on doit évaluer une telle application
(c'est le rôle du corps de la définition).