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(){ ....... ........ }
13 Réponses :
Simplifier la matière. P>
Vous pouvez toujours revenir un Il ne vaut pas la peine de changer la sémantique de la langue tellement pour un gain si peu. p>
t [] code>,
paire
définir
Questions connexes h3>
True Vous pouvez toujours revenir à l'objet qui contient des variables variées. Mais la question reste toujours la raison pour laquelle ils pensaient le faire? retourner une seule valeur.
@sushil: Parce que ce que vous demandez des quantités de sucres syntaxiques, et bien qu'il n'y ait rien de mal à tenter par des tentatives prudentes d'adoucir une langue, il existe également des arguments pour une langue plus simple, simple et pratique.
Il y a des arguments pour une langue plus simple. Je ne pense pas que ces arguments étaient la principale force de conduite derrière des langues comme C ++. :-)
Une fonction (dans des langues que vous avez mentionnées dans vos balises) a une seule sortie Aussi, notez que vous pouvez également transmettre plusieurs arguments d'entrée
Et noter que les langues fonctionnelles ont une seule entrée i> 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).
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 :) p>
Google's Go prend en charge plusieurs Valeurs de retour P>
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.
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 +...) ...
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 B> 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 (); code>. C ++ 0x ajoute du sucre syntaxique pour la construction du tuple:
tuple
Vous pouvez le faire dans Perl: et constructions similaires dans d'autres langues. P> p>
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.
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). P>
+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 i>).
Ericchaefer: Dans certaines langues, c'est vrai. Dans d'autres langues (comme Lisp Machine Lisp et Lisp commun), des fonctions DO i> 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
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. p>
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. P>
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 }
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.
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. P>
En plus de cela, il est beaucoup plus facile pour un être humain de lire une fonction avec une valeur de retour. p>
Lua prend également en charge plusieurs valeurs de retour: vous pouvez par exemple écrire ce qui suit: 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
Qu'en est-il du changement de contexte pour votre réponse
Daniel Weinreb - qui a travaillé sur les deux dialectes LISP (qui avaient plusieurs valeurs de retour) et Java (qui n'a pas), 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. P>
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 ... "). P>
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. P>
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. P>
blockQuote>
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.
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 P>
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 CODE> et attribuer comme
A, B = FUNC () code>, où a obtient 1 et b obtient 3 ou
c = func () code> où c obtient le tuple
(1, 3) code>
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.