2009-07-17 6 views
2

Pourquoi est-ce que tant de langages de programmation permettent à une fonction de modifier un objet qui lui est passé en paramètre, sans avoir une sorte de syntaxe pour le rendre clair à l'appelant? . Par exemple, considérer:Faire en sorte qu'une fonction puisse modifier ses paramètres

SomeObject A(15), B 
B = DoSomething(A) 
print(A + " " + B + "\n) 

lecture que le code que vous attendez que la sortie soit quelque chose comme « 15 75 », à savoir A est ce que vous avez construit à. Cependant la plupart des langages permettent à DoSomething de changer la valeur de A. En C++ vous pouvez dire si c'est possible ou non en regardant la déclaration de DoSomething, par exemple en regardant est le paramètre est défini comme une référence non constante. Cependant dans beaucoup de langues, telles que Python il n'y a vraiment aucun moyen de dire sans lire le code pour la fonction pour s'assurer qu'il ne change jamais A.

J'ai été mordu par ceci à quelques occasions, particulièrement en essayant de travailler avec le code de quelqu'un d'autre qui utilise ce comportement et conduit généralement à parcourir la totalité du code ligne par ligne pour essayer de trouver ce qui change le paramètre ...

Pourquoi est-ce que les langages n'exigent généralement pas de syntaxe explicite? par l'appel à dire "oui cet objet peut être modifié", par exemple dire "B = DoSomething (inout A)"?

Existe-t-il des normes de codage qui permettent d'éviter les problèmes, à l'exception du "ne jamais modifier un paramètre passé dans la fonction"?

+1

Choix de la langue; "tant de langages de programmation" est beaucoup de langues et les décisions de conception de chaque langue sont différentes. –

+0

Python, C, C++, Java sont tous ceux qui pourraient faire exactement comme montré dans mon exemple, et je soupçonne beaucoup plus que je ne sais pas/utiliser persoanlly. –

Répondre

1

Les «normes de codage» varient selon la langue et selon les utilisateurs/équipes. C++ a la const-justesse qui, lorsqu'elle est correctement utilisée, compte comme une norme de codage. C# a out et ref paramètres pour les cas évidents. Je dirais que la seule vraie cohérence dans un large éventail de langages est le fait que les modifications de paramètres doivent toujours être documentées dans les post-conditions de la fonction.

+0

Oui mais il est rare que les gens transtypent le type const pour chaque variable en C++ avant de le passer à une fonction, et comme montré dans mon exemple, du code appelant une passe de référence est invisible, vous devez regarder la fonction définition (qui avec les IDE modernes n'est pas si difficile, mais vous oblige toujours à vérifier chaque fonction, plutôt que de jeter un coup d'œil sur le code). La documentation est encore quelque chose qui ne se distingue pas en jetant un coup d'oeil sur un peu de code comme mon exemple, vous devez aller le chercher. –

1

Si vous regardez Java, une méthode ne peut pas vraiment changer le paramètre (Java n'a que des paramètres d'entrée). Mais le paramètre est souvent juste une référence à un objet avec lequel travailler, ce qui signifie que la méthode peut changer l'objet de toutes les façons possibles. Cela rend difficile le raisonnement sur la sémantique (sans regarder les docs), contrairement à la programmation des fonctions.

Vous avez raison de dire que ce n'est pas souhaitable, mais à court terme, cela a facilité les choses. Malheureusement, le plus souvent c'est le court terme qui compte, donc nous travaillons toujours avec des langages qui supportent les effets secondaires cachés ...

+0

Même alors, il y a des règles. Comme exemple simple, les getters ne devraient pas changer l'état du programme, donc vous pouvez généralement supposer ceci pendant que vous lisez le code. –

+0

Cela n'est pas vrai non plus pour les types POD. – scorpiodawg

0

Cela ne rend pas directement votre extrait de code plus clair, mais je veux quand même le mentionner : nous utilisons une convention de nommage pour que les paramètres affichent exactement ce que vous voulez. Nous utilisons les préfixes 'in', 'out' et 'io'. Ainsi, la déclaration DoSomething ressemblerait à DoSomething (ioSomeObject inA). Lorsque vous travaillez dans Visual Studio avec Visual Assist, vous obtenez une fenêtre avec les types et les noms des paramètres, ce qui documente les effets secondaires possibles. À mon avis, c'est plus clair que de documenter les conditions postérieures.

Cordialement,

Sebastiaan

+0

Utilisez au moins les attributs "InAttribute" et "OutAttribute" si vous devez le faire. Mais vraiment, il n'y a pas besoin de documenter les paramètres 'in' puisque c'est le cas attendu. –

+1

La documentation XML apparaît également dans l'IntelliSense, et vous obtenez énormément d'informations à ce sujet. Non seulement je suis * fortement * en désaccord avec cette convention, mais il viole des règles très bien établies pour nommer les paramètres dans les applications CLI et déclenche à la fois FxCop et StyleCop. –

1

Mon modèle de conception préférée pour c'est des classes de données immuables. Avec les classes modifiables, vous devez vous demander si elles sont modifiées. Un point de clarification, d'après ce que je comprends, Python est passé par valeur comme Java et C (sans modificateurs). Mais ce que vous passez est généralement un objet mutable.

(Edit:.. Presque toutes les langues traditionnelles suivent cette sémantique maintenant L'exception la plus importante est Lisp, où vous pouvez non seulement modifier les objets mutables, mais réassigner la valeur pointée par une variable)

+0

Python ne passe pas par valeur, et dans mon exemple il est parfaitement possible que python puisse changer le contenu de A si SomeObject n'est pas un type immuable, par exemple il pourrait appeler (supposer que le paramètre est appelé a dans la fonction) "a.SetValue (55) "et cela changerait la valeur de l'objet A. –

Questions connexes