Y a-t-il une raison pour laquelle les fonctions ne retournent qu'une seule valeur
Dans la plupart des langages de programmation ? Partagez vos avis

Le , par Stéphane le calme

0PARTAGES

8  0 
Y a-t-il une raison pour laquelle les fonctions dans la plupart des langages de programmation, bien que supportant un grand nombre de paramètres en entrée, ne retournent qu’une seule valeur ? C’est la question qu’un développeur a posée sur le réseau Stack Exchange. Pour lui, même s’il est possible de contourner cette limitation (par exemple en retournant des pointeurs ou en définissant / retournant des structures / classes), il semble étrange que les langages n’aient pas été pensés pour supporter un retour de valeurs multiples d’une façon plus « naturelle ». Voici quelques-unes des réponses qui ont reçu le plus de votes favorables :

  • Certains langages, comme Python, supportent nativement un retour de valeurs multiples, tandis que certains autres, comme C#, ne les supportent que via leur bibliothèque de base. Mais, en général, même dans les langages qui les supportent, les valeurs multiples de retour ne sont pas souvent utilisées parce qu’elles sont imprécises :

    1. Les fonctions qui retournent des valeurs multiples sont difficiles à nommer clairement
    2. Il est aisé de se tromper dans l’ordre des valeurs retournées

      Code : Sélectionner tout
      (password, username) = GetUsernameAndPassword()
      (pour cette même raison, nombreux sont ceux qui évitent d’entrer trop de paramètres dans leur fonction, certains vont même jusqu’à dire qu’une fonction ne devrait pas avoir deux paramètres du même type)
    3. Les langages POO ont déjà une meilleure alternative aux valeurs de retour multiples : les classes. Elles sont plus fortement typées, elles maintiennent les valeurs de retour groupées comme une unité logique et elles gardent les noms / propriétés des valeurs retour suffisamment consistants.

      Le seul endroit où elles seraient assez pratiques se trouve être dans des langages (comme Python) où les valeurs de retour multiples d’une fonction peuvent être utilisées comme de multiples paramètres d’entrée pour l’autre. Mais, les cas d’utilisation où ces configurations sont plus adaptées que les classes sont assez restreints.

  • Parce que les fonctions sont des constructions mathématiques qui permettent d’effectuer un calcul et de retourner un résultat. En effet, bien des matériaux « sous le capot » de nombreux langages de programmation se concentrent uniquement sur une entrée et une sortie, avec les entrées multiples qui sont tout simplement une mince enveloppe autour de l’entrée. Cela n’a pas changé parce que les programmeurs ont découvert que les paramètres sont des constructions maladroites qui ne s’avèrent utiles que dans un ensemble de scénarios limités. Comme beaucoup d’autres choses, le support n’est pas présent parce que la demande / le besoin n’y est pas non plus.
  • En mathématiques, une fonction « bien définie » n’a qu’une seule sortie pour une entrée donnée (comme N.B, vous pouvez avoir des fonctions d’entrée unique et obtenir sémantiquement des entrées multiples en utilisant le currying)

    Pour des fonctions à valeurs multiples (par exemple la racine carrée d’un nombre entier positif), il suffit de retourner une collection ou une séquence de valeurs.

    Pour les types de fonctions dont vous parlez (les fonctions qui retournent différentes valeurs de différents types), je le perçois un peu différemment de ce que vous semblez voir : je vois la nécessité / le besoin de l’utilisation des paramètres de sortie comme solution de contournement pour un meilleur design ou une structure de données plus utile. Par exemple, j’aurais préféré que les méthodes *.TryParse(...) retournent une monade Maybe<T> au lieu d’utiliser un paramètre de sortie. Regardez un peu ce code dans F#:

    Code : Sélectionner tout
    1
    2
    3
    4
    let s = "1"
    match tryParse s with
    | Some(i) -> // do whatever with i
    | None -> // failed to parse
    Le compilateur / l’IDE / le support d’analyse est très bon pour ces constructions. Ceci résoudrait la plupart des « besoins » de paramètres de sortie. Pour être complètement honnête, je n’arrive pas à imaginer d’autres méthodes où ce ne serait pas la solution.

    Pour les autres scénarios, ceux dont je ne me souviens pas, un simple tuple est suffisant.


Source : Stack Exchange

Et vous ?

Qu'en pensez-vous ?

Forum Langage de Programmation

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de heid
Membre confirmé https://www.developpez.com
Le 14/09/2015 à 19:12
Réponse de uncle bob :
Si les x paramètre n'ont pas de cohésion c'est qu'il faut x fonctions, et si oui, et bien une classe représente bien la notion de cohésion entre variables

Réponse du dev sénior :
Parce que avec un seul paramètre de retour vous arrivez déjà à pondre du codé dégeu alors x j'imagine pas.
24  3 
Avatar de sevyc64
Modérateur https://www.developpez.com
Le 14/09/2015 à 20:57
La toute première raison est une raison historique. Les premières fonctions de l'histoire étaient simplement des fonctions, ou opérations mathématiques. hors les opérations mathématiques ne retournent bien souvent qu'un seul résultat, le résultat du calcul effectué.
C'est historique et, on le sait tous très bien, en informatique l'historique à la vie très dure, il ne se fait pas déboulonné facilement.

Citation Envoyé par Gugelhupf Voir le message
De plus un passage par copie de référence (Java) ou référence (C++) suffit largement pour avoir une fonction qui modifie plusieurs variables.
Tu prend le problème, pardon la solution à l'envers. Ce n'est pas que ça suffit largement, c'est que ça a été la méthode la plus simple et la plus élégante de contourner le problème.
Et encore, un problème récent, parce qu'au départ, les paramètres de fonctions étaient passé par référence. La raison était la quantité limitée de ressource. On allait pas s'amuser à dupliquer une valeur en mémoire quand chaque octet, chaque bit même était compté au plus juste.
Ce n'est que lorsque les ressources, en mémoire et en puissance de calcul se sont faites un peu plus large que l'idée est venue de passer les paramètres par valeur pour les sécuriser.

Citation Envoyé par codec_abc Voir le message
1. Je vois pas pourquoi les fonctions qui retournent plusieurs argument seraient nécessairement plus dures à nommer. C'est clair que si on utilise trop de "valeurs de retours" ça devient confus mais pas forcément plus que les fonctions/méthodes qui prennent un grand nombre d'arguments.
Je pense que tu n'as pas bien compris l'exemple.
Ce qui est appelé nommage concerne bien le sens premier, c'est à dire le nom de la fonction
- Une fonction qui retourne un nom d'utilisateur sera écrite username = GetUsername() .
- Une fonction qui retourne un nom d'utilisateur et son mot de passe sera écrite (username, password) = GetUsernameAndPassword() .
- Une fonction qui retourne un nom d'utilisateur, son mot de passe et un identifiant sera écrite (username, password, matricule)= GetUsernameAndPasswordAndMatricule().
- Une autre (username, password, matricule, age)= GetUsernameAndPasswordAndMatriculeAndAgeDuCapitaine().

Ca devient vite impossible

Mais il est vrai qu'avec la POO, le problème est résolu, puisque même si l'on ne retourne toujours qu'un seul résultat, c'est une classe que l'on retourne, donc un ensemble de données cohérentes.

Mais effectivement, ça aurait une grande utilité que personne n'a mentionné.
Une fonction, en réalité, a besoin de retourner 2 résultats, et pas un seul
- le résultat du calcul, certes
- mais aussi et surtout le résultat de l’exécution du calcul, s'il s'est bien effectué, avec ou sans erreur, etc.
Sur ce point, on a tous pris l'habitude de donner des valeurs particulières au résultat (du calcul) pour faire passer l'information sur l’exécution de ce même calcul. Parce qu'on a pas vraiment le choix, mais conceptuellement c'est quand même une belle aberration. Qui pourrait être résolue pas les fonctions multi-retour
11  0 
Avatar de xapon
Membre régulier https://www.developpez.com
Le 15/09/2015 à 13:50
Sauf erreur de ma part, la définition mathématique d'une fonction est du type :
Y=f(X) ou Y=f(X1,X2, ..., Xn)
Elle ne retourne qu'une seule variable.
Après, la variable peut-être complexe.
Une fonction qui retourne une couleur retournera probablement un triplet (C,M,Y) ou (R,G,B) donc pas une seule valeur mais trois.
Idem pour une vitesse dans un espace tridimensionnel, V=(Vx,Vy,Vz) ou V=(v,&#952;,&#936
Une fonction peut aussi retourner les coordonnées d'une personne.
Bref, je ne vois pas où est le problème ?
6  0 
Avatar de lankoande
Membre confirmé https://www.developpez.com
Le 14/09/2015 à 20:13
A mon avis l'une des premières raisons c'est la simplicité. Et puis je pense qu'on a vraiment pas assez de mal pour contourner ce cas. Dans les langages structurales comme le C moi je retourne un tableau de pointeurs ou de structures selon le besoin et dans les langages OO je retourne des objets ou des tableaux d'objets.
5  0 
Avatar de Sve@r
Expert éminent sénior https://www.developpez.com
Le 19/09/2015 à 20:04
Citation Envoyé par jovalise Voir le message
Pour moi, une fonction c'est un traitement et pas deux donc ça ne doit retourné qu'un seul résultat.
Tu ne peux pas être aussi restrictif. Il existe des traitements qui produisent plusieurs résultats. Par exemple une division euclidienne, telle qu'on l'apprend au primaire, fournit 2 nombres en sortie: un quotient et un reste. C'est donc un traitement qui produit deux résultats.
Autre exemple: résoudre une équation du second degré à une inconnue est aussi un traitement qui produit lui aussi deux résultats.
C'est d'ailleurs parce qu'il existe des traitements de ce type que les mathématiciens donnent aux traitements qui ne produisent qu'au maximum un résultat (pour pouvoir y inclure aussi les traitements qui n'en produisent pas) le nom d'"application". Afin justement de les distinguer des autres. Et ils vont même jusqu'à subdiviser les applications en deux sous-ensembles: les bijections (applications qui, pour un résultat donné, ne peut avoir qu'une valeur en entrée qui amènera à ce résultat) et les autres (applications qui, pour un résultat donné, peut avoir plusieurs valeurs).
Ainsi f(x)=1/x est une application (pour tout nombre x je n'ai au maximum qu'un seul inverse) et aussi une bijection (tout inverse n'a qu'un seul antécédent)
En revanche, f(x)=x² est aussi une application (pour tout nombre x je n'ai au maximum qu'un seul carré) mais ce n'est pas une bijection (parmis tous les carrés possibles, certains pourront avoir jusqu'à 2 antécédents)
Et enfin f(a,b,c)=solution de l'équation ax²+bx+c=0 n'est pas une application puisque cette fonction pourra sortir jusqu'à 2 nombres. Et n'étant pas une application, elle ne peut pas être une bijection...
4  0 
Avatar de DonQuiche
Expert confirmé https://www.developpez.com
Le 15/09/2015 à 13:13
Citation Envoyé par MichaelREMY Voir le message
je vois bcp de commentaires avec du code dedans...
Contourner cette limite est pourtant très simple depuis plus de 20ans : sérialiser la valeur retournée ! Avec PHP c'est automatique, sinon avec les autres langages on peut le faire manuellement.
si j'ai besoin de retourner 5 valeurs de types distincts par exemple :
-465
-True
-2012-12-15
-Michael
-12.45

il suffit de les sérialiser manuellement, c'est-à-dire les concaténer en chaines de caractère :
"465#True#2012-12-15#Michael#12.45"
Vade retro satanas !

Les autres se sont déjà chargés d'expliquer plusieurs des nombreuses raisons pour lesquelles tout ça est une très mauvaise idée.
3  0 
Avatar de Sve@r
Expert éminent sénior https://www.developpez.com
Le 17/09/2015 à 12:12
Citation Envoyé par MichaelREMY Voir le message
Contourner cette limite est pourtant très simple depuis plus de 20ans : sérialiser la valeur retournée !
si j'ai besoin de retourner 5 valeurs de types distincts par exemple :
-465
-True
-2012-12-15
-Michael
-12.45

il suffit de les sérialiser manuellement, c'est-à-dire les concaténer en chaines de caractère :
"465#True#2012-12-15#Michael#12.45"
Ce principe de sérialisation est disponible dans tous les langages, donc je ne vois pas pourquoi on en fait tout un article et du tapage comme ça.
Mouais, très simple. Et moi je veux retourner
-465
-True
-2012#12#15
-#
- rien (le concept, pas le mot)
-12.45
=> "465#True#2012#12#15#####12.45"


De plus, cet article n'est pas fait pour indiquer comment résoudre ce problème (bien évidemment que tous les devs de ce forum savent le résoudre dans leurs langages de prédilection !!!), mais pour que chacun donne son avis sur les raisons du problème !!!
3  0 
Avatar de tomlev
Rédacteur/Modérateur https://www.developpez.com
Le 19/09/2015 à 2:39
Citation Envoyé par anonyme Voir le message
j'ai mis -1 à ceux qui ont mis -1 à plus de la moitié de mes posts de manière totalement injustifiable pour m'empecher de mettre un avatar "élevé au TO7-70"
Vu qu'il n'y a pas de moyen de savoir qui a mis -1 à tes posts, tu as du mettre des -1 un peu au hasard.
Et si tu crois vraiment que les gens s'amusent à te downvoter juste pour que tu n'aies pas droit à ton avatar, ça relève de la paranoïa... en général les gens mettent des -1 parce qu'ils ne sont pas d'accord, c'est tout.

Citation Envoyé par anonyme Voir le message
quelle étrange manière d'accueillir les nouveaux membres qui vous apprennent des choses vérifiables.
Quelle étrange manière d'arriver sur un forum en adoptant une attitude aussi arrogante. Je ne doute pas que tu connaisses plein de choses sur la programmation et l'architecture des processeurs, mais ce n'est pas une raison pour te comporter comme si tu avais la science infuse et que les gens qui ne sont pas de ton avis avaient forcément tort... A mon avis il ne faut pas chercher plus loin la cause de tes -1.
3  0 
Avatar de Bono_BX
Membre confirmé https://www.developpez.com
Le 14/09/2015 à 19:30
Réponse du dev sénior :
Parce que avec un seul paramètre de retour vous arrivez déjà à pondre du codé dégeu alors x j'imagine pas.


Merci pour ce grand moment de rire !
2  0 
Avatar de codec_abc
Membre confirmé https://www.developpez.com
Le 14/09/2015 à 19:59
Pour commencer je trouve l'article un peu brouillon et d'ailleurs c'est qui le "vous" dans l'article ? Le lecteur ?

Ensuite, je suis en désaccord (plus ou moins fort) avec tous les arguments avancées :
Pour la première partie :
1. Je vois pas pourquoi les fonctions qui retournent plusieurs argument seraient nécessairement plus dures à nommer. C'est clair que si on utilise trop de "valeurs de retours" ça devient confus mais pas forcément plus que les fonctions/méthodes qui prennent un grand nombre d'arguments.
2. On peut aussi se tromper pour les paramètres. Exemple getPixel(int x, int y) vs getPixel(int y, int x). Le nommage permet de lever l’ambiguïté (à condition qu'il soit bon). Ça peut aussi être le cas pour les paramètres de retours.
3. L'argument n'a aucun sens. Je vois pas en quoi avoir plusieurs valeurs de retour d'une fonction ferait perdre l'information de typage pour chaque valeur.

La deuxième partie n'est pas clair. Je ne comprends pas ou l'auteur veut en venir.

Pour le point 3, ce n'est parce qu'on a de multiple valeur de retours qu'une fonction n'est pas bijective (ou injective). Chaque valeur de retour peut très bien ne servir qu'a représenter une dimension. Exemple (x,y) = swapValue(i,j).
2  0 
Contacter le responsable de la rubrique Accueil

Partenaire : Hébergement Web