IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langages de programmation Discussion :

Y a-t-il une raison pour laquelle les fonctions ne retournent qu'une seule valeur ?


Sujet :

Langages de programmation

  1. #121
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 749
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 749
    Points : 10 666
    Points
    10 666
    Billets dans le blog
    3
    Par défaut
    Très récemment, le comité de normalisation C++ a débattu de la proposition suivante.

    Soit une fonction f() qui renvoie un tuple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tuple<int, string, float> f();
    la proposition consistait à pourvoir écrire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    auto { i, s, f } = f();
    ce qui aurait créé 3 variables i, s, f, en leur affectant automatiquement le type correspondant au tuple.

    Cette proposition a été présentée (mais non proposée) par le créateur même du langage, mais elle a été rejetée sans que j'en sache la raison.

  2. #122
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    Sur le plan sémantique il renvoie bien plusieurs valeurs et non pas un tuple. a, b, c := daFunk().
    Qu'est-ce que ça change ? Pour moi, ça renvoie un tuple de 3 éléments, que tu peux "déballer" (unpack) implicitement comme dans beaucoup d'autres langages. D'ailleurs au niveau de la déclaration de la fonction ça ressemble bien à un tuple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    func daFunk() (int, int, int) {
        return 1, 2, 3
    }
    Certes, il n'y a pas de type "tuple" explicitement matérialisé (enfin c'est ce que j'ai cru comprendre en tout cas), mais conceptuellement ça revient au même (si ce n'est que tu ne peux pas récupérer l'ensemble des valeurs retournées dans une seule variable, ce qui est un peu dommage à mon sens)

  3. #123
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Qu'est-ce que ça change ? Pour moi, ça renvoie un tuple de 3 éléments, que tu peux "déballer" (unpack) implicitement comme dans beaucoup d'autres langages.
    Fonctionnellement c'est équivalent, ce n'est qu'une nuance sémantique sas grande importance. Je répondais à la question posée.

  4. #124
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par funkygono Voir le message
    En fait, ça se fait de plus en plus avec les nouveaux langages qui poussent (Scala, Kotlin, etc.).
    Je viens de trouver un wiki qui ne parle que de ça : http://rosettacode.org/wiki/Return_multiple_values

    Ton site est un must.
    Même pour qui veut voir par exemple un simple 'HelloWorld' dans plus de 300 langages différents.
    Merci pour le lien.

  5. #125
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut Pascalet types enregistrement et C++ type structures
    Bonjour,

    En Pascal, une fonction peut renvoyer un type enregistrement (record) sans problème, et un enregistrement contient plusieurs valeurs.

    En C++, l'équivalent s'appelle les structures.

    Javascript peut renvoyer un tableau

    Bref, ça ne date pas d'aujourd'hui
    Bidouilleuse Delphi

  6. #126
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    417
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 417
    Points : 826
    Points
    826
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    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
    200 % d'accord. Et même plus.

  7. #127
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    C'est en partie à ça que servent les exceptions: Si le calcul s'est déroulé sans erreur, on peut utiliser la valeur de retour; sinon, la fonction ne retourne pas de valeur et lance une exception à la place, entraînant un chemin d'exécution différent.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #128
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    417
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 417
    Points : 826
    Points
    826
    Par défaut
    C'est vrai.
    C'est vrai aussi que la limitation est rarement réellement pénalisante et souvent assez facile à contourner.

  9. #129
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 550
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 550
    Points : 3 916
    Points
    3 916
    Par défaut
    Citation Envoyé par LadyWasky Voir le message
    Bonjour,

    En Pascal, une fonction peut renvoyer un type enregistrement (record) sans problème, et un enregistrement contient plusieurs valeurs.
    Je ne suis pas exactement d'accord car si cela peut être effectivement fait ainsi, cela peut demander de déclarer un type ad hoc uniquement pour une fonction en particulier, ce qui n'est pas la même chose que retourner un t-uple (comme en python p.ex.).

    Cdlt

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  10. #130
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Citation Envoyé par e-ric Voir le message
    Je ne suis pas exactement d'accord car si cela peut être effectivement fait ainsi, cela peut demander de déclarer un type ad hoc uniquement pour une fonction en particulier, ce qui n'est pas la même chose que retourner un t-uple (comme en python p.ex.).

    Cdlt
    Bon alors dans ce cas là, en pascal moderne on peut utiliser les variables de type TVariant qui est un type polymorphe, et qui intrinsèquement peut représenter n'importe quel type fondamental de variable (entier, chaîne de caractères, etc, voir même tableau de n'importe quel type fondamental).

    Dans tous les cas, peu importe le langage et dans le fond, on passe un seul et unique pointeur (le résultat) à une adresse (qui reçoit le résultat) , mais c'est "transparent" au niveau du code : hé oui, la brique élémentaire est écrite en assembleur. Le jour ou on aura un véritable calcul sur une variable unique passée avec des valeurs différentes possibles et un retour sur une variable unique mais avec un ensemble de valeurs correspondantes aux valeurs passée, c'est qu'on aura des ordinateurs quantique sous la main. C'est pas demain la veille
    Bidouilleuse Delphi

  11. #131
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 550
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 550
    Points : 3 916
    Points
    3 916
    Par défaut
    Salut

    Pour le type variant, pas trop d'accord non plus, c'est une autre forme de contournement aux t-uples.
    La façon dont le compilo réalise le code assembleur me chaut peu, l'essentiel est que le code généré soit efficace, mais à mon niveau, développeur d'application, le confort "syntaxique" est important, surtout si cela peut m'éviter des pirouettes.

    Cdlt

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  12. #132
    Membre régulier

    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Janvier 2010
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2010
    Messages : 120
    Points : 120
    Points
    120
    Billets dans le blog
    1
    Par défaut
    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.
    Je regrette : la racine carré d'un réel positif est toujours positive. C'est la solution à l'équation x² = 1 qui admet deux solutions : 1 et -1

    C'est un détail
    jdd deschamps
    RPL - VB6 - C# - Wordpress - Python3 - Xamarin

  13. #133
    Membre habitué
    Avatar de Benbout
    Homme Profil pro
    Avide de savoir
    Inscrit en
    Avril 2016
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Avide de savoir

    Informations forums :
    Inscription : Avril 2016
    Messages : 62
    Points : 142
    Points
    142
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    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
    C'est vrai, le code source de mon serveur de jeu (scripté en pawn un langage de script, héritier du small c) fait 80k de lignes et si je retirais tous les return -1; qui s’agglutinent tels des virus dans mes fonctions, le code serait bien moins cracra et plus plaisant à parcourir, puis parfois selon le resultat que doit retourner le calcul on doit changer de valeur d'erreur pour l’interpréter correctement ensuite sinon on risque de noyer le signal d'erreur en croyant que c'est le resultat du calcul etc etc. C'est vraiment casse tete parfois, et pour pas grand chose au final.

  14. #134
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 467
    Points : 681
    Points
    681
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    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
    Bon comme je passais par là et que je ne me souviens pas d'avoir répondu à cette remarque ces 9 dernières années :


    Je tiens à rectifier que tu fais une mauvaise interprétation AMHA. Ceci n'est pas un cas où la fonction devrait renvoyer deux résultats MAIS plutôt seulement un résultat différent pour deux cas de figures. Quand tu as un calcul correct tu n'as pas besoin de code d'erreur et quand t'as une erreur tu n'as pas de résultat de calcul. Il faudrait donc une fonction avec deux sorties chacune avec un résultat et pas une sortie avec deux résultats.


    Ce que permet la gestion des exceptions dans la plus part des langages tel le C++ et C# mais de manière lourde. Puisque l'idéale serait d'avoir une seconde sortie renvoyant un résultat de la même manière que la première sortie - c'est à dire juste une valeur à mettre dans la pile et un saut dans le code parfaitement défini et typé à la compilation.


    Je verrais une utilisation comme cela :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    try int i = int.Parse(s) otherwise i = 0;
     
    try int j = int.Parse(s) otherwise return;
     
    try int k = int.Parse(s) otherwise Console.WriteLine("impossible à parser"); // Erreur à la compilation car 'k' n'est pas toujours défini (pour la suite du code)
     
    try DX.DrawTriangles(vertices) otherwise(int error) { Console.WriteLine("Erreur dans le code n°" + error);  return; }

    Avec la possibilité d'utiliser classiquement ces méthodes/fonctions sans "try-otherwise" où les secondes sorties (d'erreur) seront traitées dans ce cas comme des exceptions classiques. J'imagine donc que le compilateur devra construire deux versions de ces méthodes : une avec exceptions classiques et une autre avec double sorties.

  15. #135
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 627
    Points : 10 548
    Points
    10 548
    Par défaut
    Citation Envoyé par ijk-ref Voir le message
    Ce que permet la gestion des exceptions dans la plus part des langages tel le C++ et C# mais de manière lourde.
    Justement , sevyc64 doit parler en pur C (vanilla C) où effectivement tu as besoin d'avoir 2 résultats.

    Un code erreur (qui est retourné pour tester si le résultat est ok) et le résultat du calcul (qui est un paramètre).

    Édit: Avec les boucles imbriquées qui font saigner les yeux et le cerveau des pro "try/catch partout"

    Parce qu'en cas d'erreur, le résultat est souvent indéfini (et on s'en fiche, il y a une erreur)

    Et des fois, tu peux ne pas avoir d'erreur, mais un résultat erroné (avec une valeur spéciale ... comme 0 ou 0xFF)

  16. #136
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 467
    Points : 681
    Points
    681
    Par défaut
    Citation Envoyé par foetus Voir le message
    Justement , sevyc64 doit parler en pur C (vanilla C) où effectivement tu as besoin d'avoir 2 résultats.

    Un code erreur (qui est retourné pour tester si le résultat est ok) et le résultat du calcul (qui est un paramètre).

    Édit: Avec les boucles imbriquées qui font saigner les yeux et le cerveau des pro "try/catch partout"

    Parce qu'en cas d'erreur, le résultat est souvent indéfini (et on s'en fiche, il y a une erreur)

    Et des fois, tu peux ne pas avoir d'erreur, mais un résultat erroné (avec une valeur spéciale ... comme 0 ou 0xFF)
    Je n'ai pas tout compris à ton message. Par contre je viens de relire la fin du message de sevyc64 où j'ai loupé son "multi-retour". J'étais sûr d'y avoir lu "multi-result". Super je relance le sujet pour expliquer qu'il ne faut pas les confondre et c'est la première chose que je fais ! Ou alors ce n'est p'être pas plus clair pour lui car je ne rien sur le sujet ailleurs... et puis en fait j'avais déjà fait une réponse il y a plus de un... bon je vais me je vais me tirer une balle... de ping-pong.

  17. #137
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 58
    Points : 76
    Points
    76
    Par défaut Go aime bien les fonctions qui retournent plusieurs valeurs.
    Go fait un excellent usage de cette extension du format de retour des fonctions. Je trouve que ça évite bien souvent de déclarer inutilement une structure qui n'a pour but que d'encapsuler les données à retourner. De plus ces retours multiples peuvent être nommés et chainés dans d'autres appels de fonction, ce qui facilite grandement la lecture du code.
    Go a peu de concepts mis en œuvre, mais ceux qui le sont sont en général tout à fait pertinents.

  18. #138
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 467
    Points : 681
    Points
    681
    Par défaut
    Bonjour, j'ai envie de relancer le sujet avec une nouvelle proposition qui me semble plus "générale/universelle".

    Je souhaite généraliser la classique fonction retournant un valeur et si impossible une exception.

    Beaucoup font l'erreur qu'il serait conceptuellement plus judicieux d'avoir "(valeur, erreur) = f()" alors qu'à mon avis l'utilisation de tuple dans ce cas reste autant une aberration puisque c'est ici non pas du "multiple-retours" mais du "multiple-sorties" - deux notions distinctes.

    Ainsi pour avoir mes "multiple-sorties" j'étendrai la syntaxe des méthodes (C#) par

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    int MaMethode(double a) 
    | float MaSortie2(float b) 
    | double MaSortie3(bool c)
    {
      var t = a + b + (c)? 0 : 1; // code pour montrer que a, b, et c sont utilisables dès l'entrée de la méthode 'étendue"
      if(/*code*/)
      {
        return 42; // sortie classique
      }
      else if(/*code*/)
      {
         MaSortie2.return 3.14f; // sortie secondaire
      }
      else
      {
         MaSortie3.return 1.414; // sortie tertiaire 
      }
    }

    Et qui s'utiliserait :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    MaMethode(1.618)->(int x)
    {
      Console.Writeline("un entier : " + x);
    }
    |MaSortie2(5.12f)->(float x)
    {
      Console.Writeline("un float : "+ x);
    }
    |MaSortie3(false)->(double x)
    {
      Console.Writeline("un double : " + x);
    }

    Ainsi avec cette écriture FloatParse deviendrait :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    float MyFloatParse(string str) | void Error()
    {
      if(/*code*/)
      {
         return 1.23f;
      }
      else
      {
        Error.return;
      }
    }

    Ce qui donnerait la possibilité de l'utiliser de 4 manières.

    (1) Méthode étendue complète
    (2) Méthode étendue sans la nécessité de traiter toutes les branches
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    MyFloatParse("3.14159")->(float x)
    {
      Console.Writeline("valeur : " + x);
    }
    |Erreur()->()  // branchement facultatif si on ne souhaite aucun traitement en cas d'erreur
    {
     Console.Writeline("valeur non reconnue");
    }

    (3) Méthode conventionnelle
    (4) Méthode conventionnelle avec valeur par défaut.
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    float x = MyFloatParse("3.14159"); // ici la sortie secondaire sera traitée comme une Exception conventionnelle 
     
    float y = MyFloatParse("3.14159") | Error() 0; // ici pas d'Exception. y = 0 si la conversion du texte est impossible.
                                                   // Note que la syntaxe ici laisse surement à désirer mais c'est l'idée qui compte ;-)
    Console.Writeline("valeurs : " + x + "; " + y);

    Voila cette "extension" permettrait :
    - de n'écrire qu'une seulement méthode là où il en faut minimum 3 pour traiter tous les cas.
    - d'avoir une vraie signature complète de méthode - ce que ne font pas les exceptions classiques puisqu'il faut les indiquer en commentaire.
    - d'éliminer pour de bon l'argument avec 'out'
    - d'avoir la valeur de sortie viable que dans son branchement, ce que ne permet pas un tuple ou un 'out'
    - de proposer un meilleur branchage que celui du lourd traitement des Exceptions try-catch.

    Et ça permettrait aussi des choses bien plus puissantes... mais je l'indiquerai... seulement si je ne suis pas le seul à voir les avantages d'une telle syntaxe.

  19. #139
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 749
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 749
    Points : 10 666
    Points
    10 666
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par Emile8 Voir le message
    Go fait un excellent usage de cette extension du format de retour des fonctions. Je trouve que ça évite bien souvent de déclarer inutilement une structure qui n'a pour but que d'encapsuler les données à retourner. De plus ces retours multiples peuvent être nommés et chainés dans d'autres appels de fonction, ce qui facilite grandement la lecture du code.
    Après quelques mois de Go, c'est un aspect qui me frustre un peu au final parce que justement les retour multiples empêchent de facilement composer les appels de fonctions.

    A l'école j'avais appris que la différence entre une procédure et une fonction, c'est que la fonction est utilisable dans une expression, typiquement :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    print("Hello %s!", getUserName())

    mais quand la fonction renvoie plusieurs valeurs et qu'on en veut qu'une seule, ben ça pousse (sinon oblige) à éclater ce genre d'expression en 2 lignes avec déclaration/affectation de variable temporaire

    @ijk-ref

    j'ai lu en diagonale ton post et je ne fais plus de C# depuis longtemps, mais pour une solution élégante au retour "(valeur, erreur)" tu devrais jeter un oeil au concept du "Maybe" en Haskell et autres langages fonctionnels du genre. En C++ cela inspire des wrappers tels que optional ou expected.

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    optional<string> readConfigValue();
     
    if (auto v = readConfigValue()) {
        std::cout << "value=" << *v << "\n";
    }
     
    std::cout << readConfigValue().value_or("default") << "\n";

    En Go, l'approche consiste à encapsuler le chaînage des appels au sein d'un objet qui va ignorer les appels suivants dès qu'une erreur est rencontrée :

    Code Go : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // wrapper type errWriter struct {
        w   io.Writer
        err error
    }
     
    func (ew *errWriter) write(buf []byte) {
        if ew.err != nil {
            return
        }
        _, ew.err = ew.w.Write(buf)
    }
     
    // utilisation
    ew := &errWriter{w: fd}
     
    ew.write(p0[a:b])
    ew.write(p1[c:d]) // non exécuté si le précédent a échoué
    ew.write(p2[e:f]) // non exécuté si le précédent a échoué
    // ...
     
    // unique test d'erreur
    if ew.err != nil {
        return ew.err
    }
    https://blog.golang.org/errors-are-values

  20. #140
    Membre averti
    Homme Profil pro
    Ergonome
    Inscrit en
    Octobre 2016
    Messages
    162
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ergonome
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Octobre 2016
    Messages : 162
    Points : 305
    Points
    305
    Par défaut
    En C, les arguments sont stockés sur la pile, avec les variables locales puis l'adresse de retour et l'ancien SP. Le compilo calcule la somme de ram requise et incrémente le registre Stack pointer (SP)

    Au return, La valeur de retour est stockée dans le registre accumulateur (ax), la sauvegarde SP est restaurée puis le code pointer.

    Il n'y a qu'une valeur de retour parce que la pile des arguments et des locales n'est plus protégée après le return. C'est pourquoi on passe la valeur par registre.

    Autre point important : une fonction/méthode est une "right value" càd qu'elle ne peut pas être à gauche de l'opérateur "=". Cette règle syntaxique a une priorité très élevée dans le parseur de code.

    A moins d'aimer les syntaxes ambigües, une right value ne peut pas pointer plus d'une valeur.

    Il y a des dizaines de méthodes pour retourner autant de valeurs qu'on veut. Personnellement, je privilégie l'emploi d'une propriété de la classe de la méthode ou une globale.
    Avec l'objet, le mot clé "new" associé aux arguments nommés sont très pratiques et seyants quoique lents à l'exécution. Passer des pointeurs en entrée : parfois, c'est très bien mais ça dépend un peu de la logique du code appelant... bon... c'est une discussion de comptoir mais ça occupe...

Discussions similaires

  1. [AC-2003] Une formule pour calculer les in et out d une table de pointage
    Par taz devil dans le forum Requêtes et SQL.
    Réponses: 10
    Dernier message: 29/06/2015, 13h46
  2. Réponses: 10
    Dernier message: 10/02/2010, 09h49
  3. Réponses: 6
    Dernier message: 06/05/2009, 16h35
  4. [Excel] fonction SOMME.SI avec une cellule pour critère
    Par repié dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 15/03/2006, 18h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo