6
votes

Pourquoi les fonctions dans certaines langues populaires ne renvoient-elles qu'un seul type de résultat?

Pourquoi les fonctions dans certaines langues populaires ne renvoient qu'un seul type de résultat?

I.e Je veux dire pourquoi les compilateurs donnent une erreur sur la syntaxe P>

public int int  returnTwoIntegers(){
.......
........
}


4 commentaires

Le titre de la question est un peu faux. Le programme n'est pas la même chose avec la langue de programmation et "tout" est un mot fort. Certaines langages de programmation (p. Ex. Python) peuvent revenir plus d'une valeur. Cette chose s'appelle un tuple.


FYI, vous pouvez retourner plusieurs valeurs à partir d'une fonction Python, comme Retour 1, 3 et attribuer comme A, B = FUNC () , où a obtient 1 et b obtient 3 ou c = func () où c obtient le tuple (1, 3)


Tout d'abord, les fonctions ne renvoient aucune valeur uniquement. Les fonctions peuvent renvoyer une valeur sans valeur (vide), une valeur de retour unique et des tuples. Vous devez donc les concevoir en fonction de vos besoins.


Je suis d'accord avec Amargosh. Bien que, après avoir examiné la mise en œuvre de tuples dans Python / Scala et ont tendance à croire que la valeur renvoyée est encore célibataire et que le retour du tuple n'est que Syntaxtic Sugar? (Je peux me tromper). Question ici davantage de la perspective de la gestion de la mémoire et de la gestion de la pile que de la syntaxie.


13 Réponses :



18
votes

Une fonction (dans des langues que vous avez mentionnées dans vos balises) a une seule sortie , mais que la sortie ne doit pas nécessairement être une seule valeur . Votre sortie peut facilement être une classe qui encapsule toute quantité de données que vous souhaitez.

Aussi, notez que vous pouvez également transmettre plusieurs arguments d'entrée par référence à votre fonction, augmentant ainsi le nombre de sorties retournées.


3 commentaires

Et noter que les langues fonctionnelles ont une seule entrée aussi. Les tuples de currying ou de passage sont aussi artificiels que de retourner une tuple ou une fonction.


@Alex: +1 De moi, Dieu, comment j'aime l'implicite de Haskell Currying :)


L'objet de retour d'une classe ne signifie pas renvoyer plusieurs valeurs. L'objet représente toujours une valeur (référence à cet objet).



0
votes

La fonction renvoie une réponse, pourquoi serait-elle conçue pour donner plus de réponses? Et cette réponse peut être n'importe quelle structure de données que vous le souhaitez, il pourrait contenir de nombreuses valeurs :)


0 commentaires

2
votes

Google's Go prend en charge plusieurs Valeurs de retour


3 commentaires

Erlang and Scala aussi: il s'appelle des tuples. Je pense que nous pourrions trouver d'autres langues avec cette fonctionnalité, en particulier dans la famille fonctionnelle.


En Python, vous pouvez utiliser un déballage de tuple implicite de telle sorte que si myfunc () renvoie un tuple, et que vous effectuez un, b = myfunc (), A et B prendront les valeurs appropriées du tuple.


En C ++ aussi, il s'appelle std :: vecteur .. oh .. non .. Ça s'appelle STD :: Liste .. même des tuples ne sont que "une valeur", c'est un "objet" qui a des sous-types. Cette question ne concerne pas quelles langues prétendent avoir plus d'une valeur de retour.



6
votes

Ma meilleure estimation est qu'elle soit reportée de mathématiques. Là, vous pouvez avoir une fonction avec plusieurs paramètres et la valeur est le résultat.

f1(x1, x2, ...) = y1 (perhaps y1 = x1 + x2^1 + ... like above)
f2(x1, x2, ...) = y2 (and y2 = x1 - x2^2 + x3^3 - x4^4 +...)
...


3 commentaires

Malheureusement, les fonctions dans des langues impératives n'ont presque rien à voir avec les fonctions mathématiques.


Je vous prie de différer, Fortran qui est le langage de programmation la plus ancienne pour la formule traduisant ou plus précisément (comme le premier projet de spécification a été appelé) 'La formule IBM Mathématique Traduction du système ". LISP qui est le deuxième plus ancien a été conçu initialement comme une «notation mathématique pratique pour les programmes informatiques» (de Wikipedia). Les mathématiques ont beaucoup à voir avec des programmes informatiques (ou du moins dans les premiers jours).


Afaik, Python retourne un seul objet tuple et le sucre syntaxique est le déballage automatique du tuple dans des variables distinctes. Les tuples existent également en C ++ (boost, TR1), sauf sans sucre syntaxique pour le déballage. L'équivalent C ++ est: cravate (x, y) = f (); . C ++ 0x ajoute du sucre syntaxique pour la construction du tuple: tuple f () {return {1, 2}; }



0
votes

Vous pouvez le faire dans Perl: xxx

et constructions similaires dans d'autres langues.


3 commentaires

Puis-je savoir comment ces valeurs sont transmises à la fonction d'appel


Sagar, la fonction My ($ A, $ B) est votre fonction d'appel et le retour (10, 20) est votre fonction appelée. Vous retournez simplement la liste complète des articles que vous souhaitez revenir entouré de parenthèses et du côté de l'appelant, recevez-les de la même manière.


ne pas vraiment retourner plusieurs valeurs; Toute langue peut faire ça.



22
votes

Les fonctions ne renvoient qu'une seule valeur car sa façon de "ils" l'ont inventé dans les anciens jours d'assembleur. Fondamentalement, ce qui se passe est que cette fonction pousse la valeur de retour sur la pile. L'appelant apparaît alors la valeur de la pile. Si la fonction renvoyait plus de valeurs, l'appelant ne savait pas combien de valeurs à POP et la pile serait déséquilibrée (conduisant à un accident de programme).


6 commentaires

+1 pour être la seule réponse réelle à la question initiale.


Cela explique que l'assembleur est comme ça, mais il existe des langues avec de multiples valeurs de retour (tuples) et de la prise en charge de la boxe directe / de la boxing --So qu'ils peuvent être directement utilisés comme si plus d'un élément était renvoyé ...


Mais un tuple n'est qu'une valeur (que contient des valeurs multiples ).


Ericchaefer: Dans certaines langues, c'est vrai. Dans d'autres langues (comme Lisp Machine Lisp et Lisp commun), des fonctions DO retour de plusieurs valeurs - pas des tuples.


Notez que dans la plupart des conventions d'appel binaire X86 communes, les valeurs de retour ne sont pas sur la pile, mais dans le registre EAX.


Cela saurait le nombre de valeurs de retour de la même manière qu'il connaît le nombre d'arguments à passer. C ++ Exemple Void F (int A) => 0 Valeurs de retour, un argument. C ++ Exemple 2 String FF () => Renvoie une chaîne, 0 args. Alors pourquoi ne serait-il pas int int f3 () => 2 int Retours et 0 arguments fonctionnent? Eh bien, il fait avec une paire f3 () => doit renvoyer les deux valeurs sur la pile.



1
votes

Je suppose que dans la plupart des cas, une valeur de retour est suffisante et la notion mathématique d'une fonction (ou de Calulus Lambda) a également une valeur de retour également, il est donc un peu compréhensible que les concepteurs de langue essaient de coller avec la "standard". En fait, plusieurs fonctions nécessitant plusieurs valeurs de retour peuvent être déroutantes et peuvent être un signe de la conception médiocre, par ex. une classe composée manquante.

L'approche "classique" pour renvoyer plusieurs valeurs utilise des tuples. Certaines langues ont un type de tuple intégré (comme Scala), mais vous pouvez la définir vous-même dans toutes les langues prenant en charge les paramètres de type sous une forme (modèles, génériques ...). Pour Java, il y a le Nice JavaTuple lib.


0 commentaires

0
votes

C'est pour aider à lire le code source. C'est tellement sympathique humain de cette façon! Si cette fonction aurait plus d'une valeur de retour, cette ligne n'a pas pu être écrite:

 if (SomeFunction(a, b) != SUCCESS)
 {
    // do error handling
 }


1 commentaires

bien sûr que ça l'est. :) Ceci est une façon que vous utilisez une fonction qui renvoie une valeur. Si cela reviendrait plus de valeurs, vous ne pouvez pas utiliser ses valeurs de retour dans des expressions aussi directement que celle-ci.



1
votes

Une fonction doit remplir une tâche clairement définie. Outre le fait que vous pouvez toujours retourner un tableau: probablement quelque chose a été complètement faux avec votre SoftwareDesign si vous auriez besoin de renvoyer différentes valeurs de différents types de données.

En plus de cela, il est beaucoup plus facile pour un être humain de lire une fonction avec une valeur de retour.


0 commentaires

1
votes

Lua prend également en charge plusieurs valeurs de retour: vous pouvez par exemple écrire ce qui suit: xxx pré>

après exécution, A, B, C, C, C, les valeurs 1, 2, 3 et D être nulle. Vous pouvez de même que ce qui suit: P>

a, b, c = bar()
if a then
   -- do something intelligent
end


1 commentaires

Qu'en est-il du changement de contexte pour votre réponse



2
votes

Daniel Weinreb - qui a travaillé sur les deux dialectes LISP (qui avaient plusieurs valeurs de retour) et Java (qui n'a pas), explique pourquoi :

Lorsque nous avons ajouté la fonctionnalité de retour à valeur multiple à la machine LISP LISP (d'où il est allé dans la LISP commune), je pense que le désir d'éviter de consentir était l'une des motivations graves. À l'époque, nous n'avions pas de bonne technologie GC et n'édentifoions pas de programmes LISP pour minimiser soigneusement le consentement était très courant.

L'autre raison était pour l'expressivité: pour préciser que la fonction revenait vraiment plus d'un résultat, plutôt que d'introduire un petit "type" (par exemple "une deux liste de la poignée de fichier et un booléen à dire Que ce soit ... ").

En Java, j'ai vu des définitions de petites classes dont le seul but est d'être un moyen de renvoyer plusieurs valeurs. L'avantage de cette approche est que les types et les significations des valeurs retournées sont documentés (au moins si vous choisissez des noms clairs et mettez en commentaires!). Mais c'est plutôt verbeux, à mon avis.

Quand j'étais en train de passer en revue le début des spécifications Java, j'ai été surpris de voir qu'il n'y avait aucun moyen de retourner plusieurs valeurs. Je voulais faire pression pour ajouter cela, alors j'ai essayé de trouver un cas d'utilisation à la fois simple et très convaincant. J'étais incapable de le faire! Donc, je n'ai pas essayé de lobbying pour cela. Les designers de Java essayaient assez clairement d'éviter beaucoup de cloches et de sifflets (et de sucre syntaxique), et il y a certainement beaucoup à dire pour cela.


5 commentaires

Quel est l'effet de l'allocation de pile sur la valeur de retour


Il existe une million de stratégies pour la mise en œuvre d'un compilateur LISP. Selon # 2F à groups.google.com/group/comp.lang .LISP / MSG / 96D32A463068044E Allegro les transmet dans les mêmes registres que ARGS, Franz les poussa sur la pile et les compilateurs utilisant un intermédiaire C reposent sur des méthodes moins efficaces. Donc, probablement n'importe où de "zéro" à "beaucoup" à "une couche méta-couche sur" beaucoup "". :-)


@Ken l'avantage de renvoyer une "petite classe" n'est pas auto-documentation, c'est le fait que les deux valeurs appartiennent presque certainement ensemble (à moins que votre fonction ne fasse trop trop) et partagera des opérations communes - mais d'où mettez-vous ces opérations? La seule option consiste à les aligner dans certains codes indirectement liés à la réutilisation beaucoup plus difficile. J'aime vraiment votre dernier paragraphe qui vous suggère de divertir des pensées similaires. Je pense que comme des tuples et des propriétés, Java a laissé de nombreuses choses parce qu'ils mènent simplement à de mauvaises pratiques - aucun bon ne peut venir d'eux alors pourquoi les inclure?


Quelques cas simples d'utilisation pour plusieurs valeurs de retour: (1) une fonction qui renvoie le sinus et le cosinus d'un angle [certaines implémentations peuvent être beaucoup plus rapides que de calculer les deux valeurs séparément]; (2) une fonction qui divise deux nombres et renvoie quotient et reste; (3) une fonction de requête de carte dans les cas où les clés peuvent "faire correspondre" sans être "identique" [par exemple. une recherche insensible à une casse], ou où les valeurs peuvent être nuls; (4) une méthode d'analyse-en-partie qui devrait indiquer si les données source étaient un entier légitime.


«Les designers de Java essayaient assez clairement d'éviter beaucoup de cloches et de sifflets» ... LOL, doit être de tourner dans leurs tombes maintenant.



0
votes

Je pense que la question concerne l'allocation de mémoire et l'organisation de la pile La principale chose est la commutation de contexte au moment de l'appel de la fonction. Le cadre de fonction est stocké sur la pile Le cadre contient des variables de fonction, des registres généraux et des valeurs de retour Je sais que


0 commentaires