Quel est le terme utilisé pour décrire une fonction / méthode qui modifie l'objet auquel elle est appelée?

12

Désolé pour la question générique. J'ai cherché partout et trouvé tellement de fils similaires à celui-ci, mais pas un qui répond à ma question spécifique - peut-être parce que le terme que je recherche n'existe même pas.

Un de mes amis apprend la programmation, JavaScript en particulier, et il m'a demandé pourquoi cela ne fonctionnait pas:

var a = "Hello World";
a.replace("Hello", "Goodbye");

console.log(a)  // Logs "Hello World"

La raison en est que replacene modifie pas a, car les chaînes sont immuables dans JavaSript. Étant donné qu'il renvoie une chaîne, vous devez faire quelque chose comme ...

var a = "Hello World";
a = a.replace("Hello", "Goodbye");

console.log(a);  // Logs "Goodbye World"

Cependant, l'alternative est une fonction comme JavaScript reverse(), car elle modifie tout ce qui l'appelle. Par exemple:

var fruits = ["Apples", "Oranges", "Bananas"];
fruits.reverse();

console.log(fruits)  // ["Bananas", "Oranges", "Apples"]

Quand mon ami m'a demandé pourquoi replaceil ne fonctionnait pas, j'ai réalisé que je cherchais un mot que je ne connaissais pas (pour autant que je sache) ...

"Vous devez définir la chaîne sur" string dot replace ", car la fonction de remplacement est ________."

Vous n'avez pas besoin de définir un tableau égal à "tableau dot reverse", car reverse est ________. "

Je connais bien les fonctions prototypes mais je ne crois pas que ce soit le mot que je recherche. Quelqu'un peut-il m'aider à remplir ces blancs?

Santi
la source
6
Peut-être que le mot est "mutateur"? comme dans: You don't need to set an array equal to "array dot reverse", because reverse is a mutator function. Je pense que j'ai entendu cette terminologie pour désigner les fonctions qui "mutent" l'instance qui les appelle. Mais vous devriez probablement vérifier cela ailleurs.
FrustratedWithFormsDesigner
Appréciez-le! Je viens de faire quelques lectures sur les méthodes de mutation et je pense que cela s'intègre très bien dans cette conversation. Certainement dans le domaine de ce que je recherche.
Santi
Je suis confus: dans le titre, vous posez des questions sur une fonction qui modifie l'objet qui l'a appelé, mais dans vos exemples, vous montrer les méthodes qui modifient l'objet qu'ils sont appelés à , à savoir l'exact opposé du titre. Lequel des deux est-ce?
Jörg W Mittag
Bien sûr, celui expliqué en 30 lignes de détail. Je vais modifier le titre pour être précis, merci pour l'avertissement!
Santi

Réponses:

12

La paire de concepts que vous recherchez sont les paramètres modifiables / immuables et les résultats sur place / restitués.

Dans vos exemples:

Vous devez définir la chaîne sur "string dot replace", car la fonction replace opère sur une chaîne qui, en python, est immuable, de sorte que la fonction replace renvoie une nouvelle chaîne.

Pour un programmeur C / C ++, cela est plus connu sous le nom de paramètres "passés par valeur", plutôt que "passés par référence", ce qui les rend immuables et renvoie le résultat.

Vous n'avez pas besoin de définir un tableau égal à "tableau dot reverse", parce que reverse fonctionne sur un tableau, qui est mutable , donc est capable de faire des changements sur place avant de revenir.

Dans des langages tels que C / C ++, cela s'appelle des paramètres "passés par référence", c'est-à-dire en passant l'adresse qui, si elle n'est pas modifiée par const, permet à la fonction de changer, de muter , le contenu de cette adresse modifiant les résultats en place avant de revenir.

Bien sûr, il n'est pas inhabituel d'avoir une fonction qui renvoie des résultats par les deux mécanismes, par exemple, int SomeFn(int p1, int p2, int *ErrCode)peut potentiellement renvoyer des résultats à la fois dans la valeur de retour et en modifiant le contenu de ErrCode.

Une 3ème méthode

Pour être complet, un troisième mécanisme de retour des résultats se fait par effet secondaire ou global , c'est-à-dire en modifiant la portée du fichier, l'ensemble du programme, les valeurs partagées ou environnementales. Ceci est généralement considéré comme une mauvaise nouvelle car, à moins d'être très bien documenté, vous ne pouvez découvrir ce qui est modifié qu'en lisant attentivement le code. Dans des langages tels que C / C ++, cela est trop facile à faire en ayant une variable de portée externe avec un nom donné, peut-être même dans un autre module, et sans masquer la variable de portée locale du même nom. En Python, bien que vous puissiez lire les valeurs des valeurs dans les étendues externes, à moins que les valeurs des étendues externes ne soient explicitement définies comme disponibles pour être modifiées avec leglobal , essayer de modifier une variable de portée externe crée automatiquement une section locale du même nom.

Steve Barnes
la source
Ah, je connais ces termes, bien que je ne sois pas sûr s'il y avait un mot réel qui décrit la fonction elle-même . Comme dans, (The reverse function is a _______ function.) Cela étant dit, c'est presque une réponse identique à celle que j'ai fini par donner à mon ami, donc j'apprécie votre confirmation - bien que je me demande toujours s'il y a des termes spécifiques. Je vais laisser la question ouverte un peu, mais j'accepterai certainement cela comme la réponse au cas où ces mots n'existeraient tout simplement pas.
Santi
2
Dans certains langages, tels que python, vous pouvez également avoir des classes qui se modifient - alors que dans certains contextes, ce "patch de singe" est considéré comme une bonne chose dans de nombreux cas, il est considéré comme du "code auto-modifiant" et est interdit. Vous pouvez également avoir un "code évolutif" où les fragments de code sont "mutés" et / ou combinés de manière aléatoire puis testés et sélectionnés pour les "meilleures" performances d'une certaine manière.
Steve Barnes
-1. Que les chaînes soient modifiables ou immuables n'a rien à voir avec la fonction qui les opère. La fonction n'est ni modifiable ni immuable, et elle n'est pas "de retour ou en place". Les fonctions peuvent modifier leurs arguments et toujours revenir.
Miles Rout
@MilesRout a ajouté que les fonctions qui modifient en place retournent toujours et quelques exemples C / C ++ pour plus de clarté et les résultats par effets secondaires pour être complet.
Steve Barnes
4

Ma façon préférée de l'exprimer est:

  • La reverseméthode Array est en mutation . C'est un mutateur . Un cas spécial commun est un setter .

  • La replaceméthode String ne mute pas . Ce n'est pas un mutateur . S'il ne modifie rien , il est sans effet secondaire . Un cas spécial commun est un getter .

  • Étant donné que les chaînes JavaScript sont immuables , les méthodes de chaîne ne peuvent pas subir de mutation.

    "Hello World" .replace ("Bonjour", "Au revoir");

    devrait vous mettre mal à l'aise. Il ne modifie pas un littéral de chaîne. Il rejette le résultat. Les analyseurs de code statique peuvent parfois détecter de tels bogues.

  • Étant donné que les tableaux JavaScript sont mutables , les méthodes de tableau peuvent être en mutation. JavaScript a tendance à utiliser les tableaux en tant que bacs de stockage locaux, facilement modifiés et rarement copiés.
Jerry101
la source
2

Parfois, lorsqu'il est utilisé dans le contexte d'une programmation fonctionnelle pure, j'ai entendu des fonctions qui modifient la valeur d'entrée (et donc ne sont pas des fonctions pures) appelées destructives . Je ne sais pas si c'est le terme correct, cependant.

Dans votre cas, vous diriez:

Vous devez définir la chaîne sur "string dot replace", car la fonction replace n'est pas destructrice .

Vous n'avez pas besoin de définir un tableau égal à "tableau dot reverse", car le revers est destructif .

Challenger5
la source
1

Peut-être que le mot que vous recherchez est pur ?

replace()est (ou semble être) pur parce qu'il ne semble pas avoir d'effets secondaires (c'est-à-dire, modifier la chaîne) alors qu'il reverse()est impur car il change l'état du tableau.

Kyle Rush
la source
C'est un concept connexe, mais implique également d'autres propriétés (par exemple, ne pas accéder à l'état global et produire toujours la même sortie pour la même entrée).
Jacob Raihle
1

Celles-ci sont généralement séparées en fonctions et méthodes (où les méthodes sont un sous-ensemble de fonctions). Une fonction est une section de code qui peut être appelée de manière isolée, tandis qu'une méthode a un concept de «contexte» actuel sur lequel elle opère. L'action d'une méthode modifie l'état de son contexte.

En programmation orientée objet, le contexte est l'instance sur laquelle la fonction fonctionne.

richzilla
la source
0

Je ne sais pas s'il existe une réponse officielle, mais en voici deux qui pourraient vous plaire.

Procédure

Seulement parce que cela semblait être une bonne réponse à cette question , qui ressemble beaucoup à votre question BTW - vous devriez la vérifier.

Fonctionnement unaire sur place

Consultez cette page: java.util.function . Il fournit une sorte de nom composé pour les délégués (signatures d'entrée / sortie) de divers prototypes, par exemple un délégué qui prend un argument et ne renvoie rien n'est appelé un consommateur .

Maintenant, en tant qu'étudiant astucieux de la POO, vous devez être conscient qu'une méthode a est juste une fonction qui prend un paramètre caché ( this). Puisqu'il est fourni comme référence, il sert à la fois de paramètre d'entrée et de sortie.

Selon ces gars de Java (et ils semblent assez intelligents), un délégué qui accepte une seule entrée et renvoie une valeur du même type est appelé un opérateur unaire .

Maintenant, dans le cas de array::Reverse(), un tableau n'est pas immuable et peut potentiellement prendre beaucoup de place, il est donc plus efficace et plus pratique d'effectuer l'opération en place. C'est donc Reverse()un opérateur unaire en place .

Mais pour moi, un "opérateur" est un symbole spécial (comme l'opérateur d'addition, également connu sous le nom +) ou un mot-clé mathématique comme mod. Par conséquent, je préfère l'appeler un operat ion , ce qui donne une opération unaire en place .

John Wu
la source
Vous mélangez des concepts. Reverse()est pas un opérateur, un opérateur unaire n'a pas besoin de retourner une valeur du même type (par exemple !, delete, typeof) et les opérateurs ne sont pas délégués. Mais "sur place" est un terme fin pour une méthode qui modifie son instance. [Je n'ai pas voté contre, mais il semble que quelqu'un ait voté contre toutes les réponses même si elles sont toutes utiles.]
Jerry101
Pas sûr que vous suivez. Tout prototype peut être représenté par un délégué. "Opérateur" ne fonctionne pas pour moi (comme je l'ai dit) donc je dis "Opération", et oui en effet, Reverse()c'est une opération unaire. Mais dans l'ensemble, je conviens que tout cela est un peu étrange, mais j'utilise textuellement la terminologie du document lié , qui semble avoir été créée par des gens assez intelligents. Au moins, c'est mieux que rien.
John Wu
Oh je vois! Notez que pour moderniser les lambdas en Java, ils se sont basés sur l'idée d'une interface fonctionnelle (une interface Java avec seulement 1 méthode) afin que nous puissions contourner les objets Java ordinaires pour les appliquer en tant que «fonctions». (Brian Goetz a une discussion technique sur l'ajout de lambdas. Plusieurs fois, il dit que "l'approche évidente aurait été nulle.") Lors de la création d' interfaces fonctionnelles pour des objets de traitement de flux, ils ont en quelque sorte utilisé des termes abusifs comme "opérateur". C'est déroutant! Ils ont dû manquer de bons noms. Je ne pense pas que ce soit une bonne source de termes pour les méthodes OOP qui modifient / ne modifient pas l'objet récepteur.
Jerry101