9
votes

Pourquoi les langues ne permettent pas de surcharger des méthodes par la valeur de retour?

C, Java et de nombreuses autres langues ne font pas attention aux valeurs de retour.

int i = func(func(func(func2(func3())))) //you dont know what you are getting


2 commentaires

Avez-vous essayé Lisp ?? Sinon, essayez-le, cela pourrait résoudre votre problème.


Dupliqué possible de surcharge de fonction par type de retour?


8 Réponses :


14
votes

Disons que c'était autorisé, lequel appelait cet appelait: xxx

qui peut ne pas être la réponse complète, mais je crois que c'est une raison pour laquelle ce n'est pas légal.


5 commentaires

c'est un bon point. Les paramètres sont généralement requis pour les fonctions, mais la gestion de la valeur de retour n'est pas.


Je pense que c'est une mauvaise pratique de ne pas gérer les valeurs de retour. Cela devrait être annulé à la diffusion d'une exception ou de la valeur de retour doit être vérifiée. Cependant Var V = Func (); (Affectation de style C #) Peut causer des problèmes ... (hmmmm))


Je ne suis pas sûr que je suis d'accord avec vous sur la partie "mauvaise pratique", du moins pas dans le cas général. Ce n'est certainement pas quelque chose qui devrait être explicitement interdit. La langue devrait donc être capable de gérer cela.


Un bon point, mais des règles pourraient également être ajoutées pour définir une implémentation par défaut de Func (), explicitement ou par un ensemble de règles.


@ acidzombie24: Si la langue s'est opposée à ignorer les valeurs de retour, il s'agirait d'une nuisance pour Mode chaîning



17
votes

Quoi de ce cas? XXX

Il existe déjà des problèmes d'ambiguïté lorsque vous autorisez une surcharge d'un seul nom de fonction qui prennent des arguments différents. Avoir à vérifier le type de retour aussi, il suffirait probablement de résoudre la bonne fonction beaucoup plus difficile.

Je suis sûr qu'une langue pourrait mettre en œuvre cela, mais cela ferait beaucoup plus compliqué et gagnerait généralement le code plus difficile à comprendre.


3 commentaires

De même, quel devrait system.out.println (func () + func ()) sortie?


Cela rendrait le code plus difficile à comprendre. +1. Peut-être que je vais marquer cela comme correct (je veux voir d'autres réponses)


Que diriez-vous d'exiger que l'une des surcharges soit marquée comme «préférée», avec d'autres utilisées uniquement lorsque le type de retour serait immédiatement moulé ou contraint à un autre type (pour lequel une surcharge plus précise est fournie), ou lorsque le type de retour est ignoré (auquel cas un Void surcharge serait utilisé s'il est fourni)?



6
votes

Pour un exemple C ++, envisagez:

void g(int x);
void g(float x);
g(func());


2 commentaires

Dans ce cas, il pourrait faire ce que C ++ fait parfois et compile avec une erreur ambiguë forçant l'utilisateur à écrire g ((float_or_intytype) Func ());


Même cela ne voudrait pas aider. Et si vous avez plusieurs méthodes qui renvoient un type pouvant être valablement jeté à l'objet que vous coulez? int Peut être jeté pour flotter et vice-versa.



1
votes

La plupart des langues permettent des opérations en mode mixte avec la coercition automatique (par exemple float + int), où plusieurs interprétations sont légales. Sans contrainte, travailler avec de multiples types numériques (court, int, long, flotteur, double) deviendrait très encombrant; Avec la coercition, le désambigation basé sur le retour entraînerait un code difficile à comprendre.


0 commentaires

1
votes

Permettre à ceux-ci peut introduire des problèmes. Par exemple:

int i = func2(func());
int func() { return 5; }
float func() { return 1.3; }
int func2(float a) { return a; }
int func2(int a) { return a; }


1 commentaires

Qu'est-ce qui ne va pas dans la spécification de la signature de chaque méthode doit avoir une implémentation marquée comme étant préférée, sauf lorsque le résultat de la fonction était soit attribué à une variable ou immédiatement typée?



3
votes

Perl permet un certain degré de variation de type de retour, dans ces fonctions, vous pouvez indiquer quel type de contexte est évalué. Par exemple, une fonction pouvant renvoyer une matrice peut voir qu'il fonctionne dans un contexte scalaire et Retournez simplement la longueur de putative directement, épargnant l'allocation et l'initialisation de la matrice pour obtenir sa longueur.


2 commentaires

Ce qui fonctionne pour Perl, mais il y a plusieurs choses à Perl que je ne pense pas travaillerait dans une langue plus conventionnelle. Sans parler que Perl n'a pas de système de type dans le sens normal: les types sont $ scalaires, @arrays, #Hashes, @typeglobs, et il me semble que j'en ai oublié un. Il n'y a pas de distinction entre entier, flotteur et la chaîne et les opérateurs doivent déterminer s'il faut agir numériquement ($ i + 1) ou avec des chaînes ($ i + "1").


@David: Je ne pense pas que je louais des vertus de Perl dans ma réponse, ni de suggérer que de telles choses devraient être ajoutées à d'autres langues. Je répondais simplement à la question de la question qui demande ce qui est là-bas.



10
votes

Oui, permettant la surcharge sur les types de retour complique une langue. Il complique la résolution des identifiants surchargés (E.G. Noms de fonction). Mais ce n'est pas impossible, par exemple. Haskell permet de surcharger la fonction sur la base de leur type de retour. xxx

num est une classe de type dans HASKELLL avec une méthode appelée de_Integer qui est Une fonction d'une taille arbitraire integer à un type arbitraire qui a une instance de num . Le mécanisme de classe de type Haskell est plutôt différent du concept de classe de langues orientées objet. Par conséquent, mon explication peut sembler étrange.

Mais, le résultat est que je peux utiliser la fonction de confiance et, en fonction du contexte appelant, différentes implémentations sont chooen à la compilation.

Il y a toute une ligne de recherche sur type Les systèmes, qui ont rendu cette fonctionnalité possible. Par conséquent, je dirais que cela est faisable dans des langues typées statiquement. Les langues dynamiquement dactylographiées nécessiteraient soit des idées de déplacement de temps, soit des idées intelligentes.


0 commentaires

9
votes

Pour éviter toute ambiguïté.

a( int )
a( bool )
int b()
bool b()

a( b() ) -- Which b?


3 commentaires

Il existe de nombreuses situations ambiguës, mais cela n'impliquerait pas que la surcharge ne pourrait pas être utile si la (1) une fonction "primaire" devrait être utilisée sauf dans les cas où une autre était clairement supérieure, et (2) dans des cas qui seraient toujours Soyez ambigu, un compilateur pourrait utiliser soit. Considérons des fonctions (int32, int32) -> int32, (int32, int32) -> INT64 et (intT64, INT64) -> INT64. S'ils donnent un comportement sémantiquement identique dans les cas où la valeur calculée dans un INT32, un compilateur pourrait utiliser (INT64, INT64) -> INT64 toujours, mais la performance pourrait être meilleure si (int32, int32) -> int32 a été utilisé à la place.


Cela pourrait être résolu par une hiérarchie pour les types (la surcharge est choisie par la surcharge pour int , puis ...). Cela laisse toujours le problème des types définis par l'utilisateur. Dans l'exemple C ++, il serait probablement préférable de permettre uniquement à quelque chose comme des fonctions de modèle d'avoir des types de retour surchargés et de donner une erreur de compilateur en cas d'ambiguïté. L'utilisateur pourrait se déplacer cela en disant B () si nécessaire.


-1 pour l'inférence de type mention. Eh bien, Haskell a une surcharge sur les types de retour et l'inférence de type acyclique. L'inférence de type est compliquée à cause de nombreuses choses, par ex. boucles ou dépendances récursives.