Envoyé par
Stéphane le calme
Y a-t-il une raison pour laquelle les fonctions, dans la plupart des langages de programmation,
ne retournent qu'une seule valeur ? Partagez vos avis
Oui, elle est très simple et pourtant personne ne semble l'avoir mise dans les commentaires.
La raison, c'est qu'un appel de fonction est destiné à être intégré dans une expression plus complexe: c'est à dire que x := f(y) est l'exception, le plus souvent c'est e(f(y)) où e est une expression (pas forcément un appel de fonction) plus complexe.
Prenons l'exemple donné dans l'article:
(password, username) = GetUsernameAndPassword()
Ce qui me gêne avec ce genre de fonction, ce n'est pas qu'on puisse se tromper dans l'ordre des paramètres. Imaginons que je dispose d'une fonction trouvant le nom de famille à partir du login (dans une base de données par exemple). Si je cherche un nom à partir de la fonction précédente je vais devoir écrire
1 2 3
|
(user, pass) = GetUserNameAndPassword()
return RealName (user) |
là où avec une fonction retournant une seule valeur j'aurais pu écrire
return RealName(GetUserName())
Comme vous voyez, loin de simplifier l'écriture, la présence de plusieurs paramètres oblige à passer par des variables temporaires.
A moins bien entendu qu'il existe un opérateur sur les tuples permettant d'en extraire le premier élément:
return RealName (GetUserNameAndPassword() [0])
et on comprend alors que la fonction supposée rendre plusieurs valeurs renvoie en réalité une seule valeur de type tuple, c'est bien un type à part avec des opérateurs associés... à condition de les définir, ce que l'auteur de l'article n'a pas pris la peine de faire.
De même, si une autre fonction prend plusieurs paramètres, il faut définir une sémantique pour qu'un résultat de type tuple puisse être intégré: en Perl par exemple, si j'écris F(GetUserNameAndPassword()), le résultat de l'appel à GetUserNameAndPassword va être "applati" ce qui veut dire que la fonction F va recevoir deux paramètres. Mais d'autres langages pourraient considérer ce résultat comme un tuple passé comme premier paramètre de F - et d'ailleurs, serait-il passé par valeur ou par référence? Comme vous voyez, loin de simplifier les choses, ça oblige à définir une sémantique complexe.
En mathématiques, à la base les choses sont spécifiées clairement : une fonction a un ensemble de définition et un ensemble résultat. Si une fonction a deux paramètres entiers, c'est qu'en réalité son ensemble de définition est N² : elle prend en paramètre un vecteur à deux composantes. Et rien ne lui interdit de renvoyer un vecteur à deux composantes : au moment de l'appel on dispose de tous les opérateurs définis pour le type N² et seulement ceux-là. Si ensuite je veux passer le résultat dans une autre fonction, soit celle-ci prend un type N² et je peux reprendre mon résultat tel quel, soit elle prend autre chose et il faut des opérateurs pour convertir.
La question est alors de savoir quels opérateurs sont définis sur N², et là il faut reconnaitre que les matheux ont été assez peu rigoureux pour les définir. Généralement ils utilisent .x .y et .z sans se rendre compte que ce sont des opérateurs et on se demande alors ce qui se passe au delà de 4 composantes, mais ils n'y ont pas réfléchi. Un informaticien au contraire serait obligé de définir un type structuré et de nommer explicitement les composantes à l'avance.
Partager