Pourquoi les effets secondaires sont-ils considérés comme pervers dans la programmation fonctionnelle?

69

Je pense que les effets secondaires sont un phénomène naturel. Mais cela ressemble à un tabou dans les langages fonctionnels. Quelles sont les raisons?

Ma question est spécifique au style de programmation fonctionnelle. Pas tous les langages / paradigmes de programmation.

Gulshan
la source
6
Un programme sans effets secondaires est inutile, donc les effets secondaires ne sont ni démoniaques ni tabous. Mais FP encurage en délimitant le code avec des effets secondaires, de sorte qu’une partie aussi importante que possible du code sont des fonctions libres d’effets secondaires. Ceci est encouragé car les fonctions et sous-systèmes libres d’effets secondaires sont plus faciles à comprendre, à analyser, à tester et à optimiser.
JacquesB
@JacquesB Ce serait une bonne réponse d'expliquer pourquoi ils sont plus faciles à comprendre, à analyser, à tester et à optimiser.
Ceving

Réponses:

72

Écrire vos fonctions / méthodes sans effets secondaires - de sorte que ce sont des fonctions pures - facilite la réflexion sur l'exactitude de votre programme.

Cela facilite également la composition de ces fonctions pour créer un nouveau comportement.

Cela permet également certaines optimisations, où le compilateur peut par exemple mémoriser les résultats de fonctions ou utiliser Common Elimination Expression.

Edit: à la demande de Benjol: Comme une grande partie de votre état est stockée dans la pile (flux de données, pas de flux de contrôle, comme Jonas l’a appelé ici ), vous pouvez paralléliser ou réorganiser l’exécution de parties de votre calcul indépendantes de L'une et l'autre. Vous pouvez facilement trouver ces parties indépendantes, car une partie ne fournit pas d'entrées à l'autre.

Dans les environnements avec des débogueurs qui vous permettent de restaurer la pile et de reprendre l'informatique (comme Smalltalk), des fonctions pures vous permettent de voir très facilement comment une valeur change, car les états précédents sont disponibles pour l'inspection. Dans un calcul comportant beaucoup de mutations, à moins d'ajouter explicitement des actions à / annuler à votre structure ou à votre algorithme, vous ne pouvez pas voir l'historique des calculs. (Cela renvoie au premier paragraphe: écrire des fonctions pures facilite l' inspection de l'exactitude de votre programme.)

Frank Shearar
la source
4
Peut-être envisagez-vous d'ajouter quelque chose à propos de la simultanéité dans votre réponse?
Benjol
5
Les fonctions gratuites à effets secondaires sont plus faciles à tester et à réutiliser.
LennyProgrammers
@ Lenny222: je pensais à la réutilisation en parlant de la composition des fonctions.
Frank Shearar
@ Frank: Ah, ok, navigation trop superficielle. :)
LennyProgrammers
@ Lenny222: C'est bon; c'est probablement une bonne chose à préciser.
Frank Shearar
23

Extrait d'un article sur la programmation fonctionnelle :

En pratique, les applications doivent avoir des effets secondaires. Simon Peyton-Jones, un contributeur majeur au langage de programmation fonctionnel Haskell, a déclaré ce qui suit: "En fin de compte, tout programme doit manipuler l'état. Un programme qui n'a aucun effet secondaire est une sorte de boîte noire. Tout ce que vous pouvez dire, c'est que la boîte devient plus chaude. " ( http://oscon.blip.tv/file/324976 ) L'important est de limiter les effets indésirables, de les identifier clairement et d'éviter de les disperser dans le code.

Peter Stuifzand
la source
23

Vous vous trompez, la programmation fonctionnelle encourage la limitation des effets secondaires pour rendre les programmes faciles à comprendre et à optimiser. Même Haskell vous permet d'écrire dans des fichiers.

En gros, ce que je dis, c'est que les programmeurs fonctionnels ne pensent pas que les effets secondaires sont néfastes, ils pensent simplement qu'il est bon de limiter l'utilisation de ces effets secondaires. Je sais que cela peut sembler être une distinction si simple, mais cela fait toute la différence.

ChaosPandion
la source
C'est pourquoi ils sont "quelque chose comme un tabou" - les FPL vous encouragent à limiter les effets secondaires.
Frank Shearar
+1 pour l'approche. les effets secondaires existent toujours. en effet, ils sont limités
Belun
Pour plus de clarté, je n'ai pas dit «pourquoi les effets secondaires ne sont pas autorisés dans la programmation fonctionnelle» ou «pourquoi les effets secondaires ne sont pas nécessaires». Je sais que cela est autorisé dans les langages fonctionnels et est parfois indispensable. Mais il est très découragé dans la programmation fonctionnelle. Pourquoi? C'était ma question.
Gulshan
@Gulshan - Parce que les effets secondaires rendent les programmes plus difficiles à comprendre et à optimiser.
ChaosPandion
dans le cas de haskell, le principal problème n'est pas de "limiter les effets secondaires". les effets secondaires sont impossibles à exprimer dans la langue. ce qui fonctionne, readFilec'est définir une séquence d'actions. Cette séquence est fonctionnellement pure et ressemble un peu à un arbre abstrait décrivant QUE faire. les effets secondaires réels sont alors effectués par le moteur d'exécution.
Sara
13

Quelques notes:

  • Les fonctions sans effets secondaires peuvent être exécutées en parallèle, alors que les fonctions avec effets secondaires nécessitent généralement une sorte de synchronisation.

  • Les fonctions sans effets secondaires permettent une optimisation plus agressive (par exemple, en utilisant de manière transparente un cache de résultats), car tant que nous obtenons le bon résultat, le fait que la fonction soit réellement exécutée n'a pas d'importance

utilisateur281377
la source
Point très intéressant: peu importe que la fonction soit réellement exécutée ou non . Il serait intéressant de se retrouver avec un compilateur capable de se débarrasser des appels ultérieurs aux fonctions libres d’effets secondaires avec des paramètres équivalents.
Noel Widmer
1
@NoelWidmer Quelque chose comme ça existe déjà. PL / SQL d'Oracle propose une deterministicclause pour les fonctions sans effets secondaires, afin qu'elles ne soient pas exécutées plus souvent que nécessaire.
user281377
Hou la la! Cependant, je pense que les langues doivent être sémantiquement expressives pour que le compilateur puisse le comprendre lui-même sans avoir à spécifier un drapeau explicite (je ne suis pas sûr de ce qu'est une clause). Une solution pourrait être de spécifier que les paramètres doivent être modifiables / immuables En général, cela nécessiterait un système de type fort dans lequel des hypothèses sur les effets secondaires peuvent être formulées par le compilateur. Et la fonctionnalité doit pouvoir être désactivée si vous le souhaitez. Désinscription au lieu de souscrire. C'est juste mon avis, basé sur la connaissance limitée que j'ai depuis que j'ai lu votre réponse :)
Noel Widmer
La deterministicclause est juste un mot-clé qui indique au compilateur qu'il s'agit d'une fonction déterministe, comparable à la façon dont le finalmot - clé en Java indique au compilateur que la variable ne peut pas être modifiée.
user281377
11

Je travaille principalement dans le code fonctionnel maintenant, et de ce point de vue, cela semble aveuglant. Les effets secondaires créent une énorme charge mentale sur les programmeurs qui essaient de lire et de comprendre le code. Vous ne remarquerez pas ce fardeau tant que vous n'en serez plus libéré pendant un moment, puis vous devrez soudainement lire à nouveau le code avec des effets secondaires.

Considérez cet exemple simple:

val foo = 42
// Several lines of code you don't really care about, but that contain a
// lot of function calls that use foo and may or may not change its value
// by side effect.

// Code you are troubleshooting
// What's the expected value of foo here?

Dans un langage fonctionnel, je sais qu'il en fooreste 42. Je n'ai même pas à regarder le code entre les deux, encore moins le comprendre, ni à regarder la mise en œuvre des fonctions qu'il appelle.

Tout ce qui concerne la simultanéité, la parallélisation et l'optimisation est une bonne chose, mais c'est ce que les informaticiens ont mis dans la brochure. Ne pas avoir à se demander qui mue votre variable et quand est ce que j'apprécie vraiment dans la pratique quotidienne.

Karl Bielefeldt
la source
6

Peu ou pas de langues rendent impossible de provoquer des effets secondaires. Les langues totalement libres d’effets secondaires seraient extrêmement difficiles (presque impossibles) à utiliser, sauf dans des cas très limités.

Pourquoi les effets secondaires sont considérés comme pervers?

Parce qu’ils rendent beaucoup plus difficile la tâche de raisonner sur ce que fait exactement un programme et de prouver qu’il fait ce que vous attendez de lui.

À un niveau très élevé, imaginez que vous testiez un site Web à trois niveaux avec uniquement des tests en boîte noire. Bien sûr, c'est faisable, selon l'échelle. Mais il y a certainement beaucoup de doublons. Et s'il est un bug (qui est lié à un effet secondaire), alors vous pourriez potentiellement casser l'ensemble du système pour des tests supplémentaires jusqu'à ce que le bogue est diagnostiqué et fixe, et le correctif est déployé dans l'environnement de test.

Avantages

Maintenant, réduisez-le. Si vous étiez assez bon pour écrire du code libre à effets secondaires, à quel point iriez-vous plus vite pour raisonner ce que certains codes existants ont fait? Combien de temps pourriez-vous écrire des tests unitaires? À quel point penseriez-vous que le code sans effets secondaires était garanti sans bugs et que les utilisateurs pouvaient limiter leur exposition aux bugs qu'il avait ?

Si le code n'a pas d'effets secondaires, le compilateur peut également effectuer des optimisations supplémentaires. Il peut être beaucoup plus facile de mettre en œuvre ces optimisations. Il peut être beaucoup plus facile même de conceptualiser une optimisation pour un code sans effets secondaires, ce qui signifie que le fournisseur de votre compilateur peut implémenter des optimisations difficiles à impossibles dans un code avec des effets secondaires.

La simultanéité est également considérablement plus simple à mettre en œuvre, à générer automatiquement et à optimiser lorsque le code n'a pas d'effets secondaires. En effet, toutes les pièces peuvent être évaluées en toute sécurité dans n'importe quel ordre. Permettre aux programmeurs d'écrire du code hautement concurrent est largement considéré comme le prochain défi de taille auquel l'informatique doit s'attaquer, et comme l'une des dernières zones de couverture contre la loi de Moore .

Merlyn Morgan-Graham
la source
1
Ada rend très difficile les effets secondaires. Ce n'est pas impossible cependant, mais vous savez clairement ce que vous faites alors.
mouviciel
@mouviciel: Je pense qu'il existe au moins quelques langues utiles qui rendent les effets secondaires très difficiles, et essayez de les reléguer au rang de Monads.
Merlyn Morgan-Graham
4

Les effets secondaires sont comme des "fuites" dans votre code qui devront être traités plus tard, soit par vous-même, soit par un collègue peu méfiant.

Les langages fonctionnels évitent les variables d'état et les données modifiables, ce qui permet de rendre le code moins dépendant du contexte et plus modulaire. La modularité assure que le travail d'un développeur n'affectera pas / ne nuira pas au travail d'un autre.

La vitesse de développement proportionnelle à la taille de l'équipe est aujourd'hui un "Saint Graal" du développement logiciel. Lorsque vous travaillez avec d'autres programmeurs, peu de choses sont aussi importantes que la modularité. Même le plus simple des effets secondaires logiques rend la collaboration extrêmement difficile.

Suis-je
la source
+1 - "ou un collègue sans méfiance"
Merlyn Morgan-Graham Le
1
-1 pour les effets secondaires étant "les fuites qui doivent être traitées." Créer des "effets secondaires" (code non purement fonctionnel) est l’objectif premier de l’écriture de tout programme informatique non trivial.
Mason Wheeler
Ce commentaire vient six ans plus tard, mais il y a des effets secondaires et des effets secondaires. Le type souhaitable d'effets secondaires, qui font d' E / S et ainsi de suite, sont en effet nécessaires à tout programme, parce que vous devez donner vos résultats à l'utilisateur en quelque sorte - mais l'autre type d'effets secondaires, où votre code change d' état sans un bon comme faire des E / S, sont en effet une "fuite" qui devra être traitée plus tard. L'idée de base est la séparation commande-requête : une fonction qui renvoie une valeur ne doit pas avoir d'effet secondaire.
Munitions
4

Eh bien, à mon humble avis, c'est assez hypocrite. Personne n'aime les effets secondaires, mais tout le monde en a besoin.

Ce qui est tellement dangereux avec les effets secondaires, c’est que si vous appelez une fonction, cela aura peut-être un effet non seulement sur le comportement de la fonction lors de son appel suivant, mais aussi sur d’autres fonctions. Ainsi, les effets secondaires introduisent un comportement imprévisible et des dépendances non triviales.

Les paradigmes de programmation tels que OO et fonctionnel répondent tous deux à ce problème. OO réduit le problème en imposant une séparation des préoccupations. Cela signifie que l'état de l'application, qui comprend un grand nombre de données mutables, est encapsulé dans des objets, chacun étant responsable de la gestion de son propre état uniquement. De cette façon, le risque de dépendance est réduit et les problèmes sont beaucoup plus isolés et plus faciles à suivre.

La programmation fonctionnelle adopte une approche beaucoup plus radicale, où l'état de l'application est simplement immuable du point de vue du programmeur. C'est une bonne idée, mais rend le langage inutile par lui-même. Pourquoi? Parce que TOUT fonctionnement I / O a des effets secondaires. Dès que vous lisez un flux d'entrée, l'état de votre application est susceptible de changer car, lors de la prochaine invocation de la même fonction, le résultat sera probablement différent. Vous êtes peut-être en train de lire différentes données ou, éventuellement, l’opération peut échouer. La même chose est vraie pour la sortie. Même la sortie est une opération avec des effets secondaires. Vous ne vous en rendez pas souvent compte, mais imaginez que vous n’avez que 20 Ko pour votre sortie et que si vous restez plus productif, votre application se bloque parce que vous n’avez plus assez d’espace disque.

Alors oui, les effets secondaires sont méchants et dangereux du point de vue d'un programmeur. La plupart des bugs proviennent de la façon dont certaines parties de l'état de l'application sont imbriquées de manière presque obscure, par le biais d'effets secondaires inconsidérés et souvent inutiles. Du point de vue de l'utilisateur, les effets secondaires sont le point essentiel de l'utilisation d'un ordinateur. Ils ne se soucient pas de ce qui se passe à l'intérieur ou de la manière dont cela est organisé. Ils font quelque chose et s'attendent à ce que l'ordinateur change en conséquence.

back2dos
la source
Fait intéressant, la programmation logique n’a pas seulement des effets secondaires fonctionnels; mais vous ne pouvez même pas changer la valeur d'une variable une fois assignée.
Ilan
@Ilan: Ceci est également vrai pour certains langages fonctionnels et c'est un style facile à adopter.
back2dos
"La programmation fonctionnelle adopte une approche beaucoup plus radicale, où l'état de l'application est tout simplement immuable du point de vue du programmeur. C'est une bonne idée, mais rend le langage inutile par lui-même. Pourquoi? Parce que TOUT fonctionnement I / O a "effets": la PF n'interdit pas les effets secondaires, elle les limite plutôt lorsque cela n'est pas nécessaire. Par exemple (1) I / O -> les effets secondaires sont nécessaires; (2) calcul d'une fonction d'agrégation à partir d'une séquence de valeurs -> effet secondaire (par exemple, boucle avec variable d'accumulation) non nécessaire.
Giorgio
2

Tout effet secondaire introduit des paramètres d’entrée / sortie supplémentaires qui doivent être pris en compte lors des tests.

Cela rend la validation du code beaucoup plus complexe car l’environnement ne peut pas être limité au seul code en cours de validation, mais doit intégrer tout ou partie de l’environnement environnant (le global qui est mis à jour vit dans ce code là-bas, ce qui dépend code, qui dépend à son tour de la vie sur un serveur Java EE complet ....)

En essayant d'éviter les effets secondaires, vous limitez la quantité d'externalisme nécessaire à l'exécution du code.


la source
1

D'après mon expérience, une bonne conception de la programmation orientée objet oblige à utiliser des fonctions ayant des effets secondaires.

Par exemple, prenons une application de bureau d'interface utilisateur de base. J'ai peut-être un programme en cours d'exécution qui a sur son tas un graphe d'objet représentant l'état actuel du modèle de domaine de mon programme. Les messages parviennent aux objets de ce graphique (par exemple, via des appels de méthodes invoqués à partir du contrôleur de couche de l'interface utilisateur). Le graphe d'objet (modèle de domaine) sur le tas est modifié en réponse aux messages. Les observateurs du modèle sont informés de tout changement, l'interface utilisateur et éventuellement d'autres ressources sont modifiées.

Loin d’être maléfique, l’arrangement correct de ces effets secondaires de modification de tas et de modification d’écran est au cœur de la conception OO (dans ce cas, le modèle MVC).

Bien entendu, cela ne signifie pas que vos méthodes doivent avoir des effets secondaires arbitraires. Et les fonctions sans effets secondaires ont leur place dans l'amélioration de la lisibilité et parfois des performances de votre code.

flamingpenguin
la source
1
Les observateurs (y compris l'interface utilisateur) doivent s'informer des modifications apportées en s'abonnant aux messages / événements envoyés par votre objet. Ce n'est pas un effet secondaire à moins que l'objet ne modifie directement l'observateur - ce qui serait une mauvaise conception.
ChrisF
1
@ChrisF Très certainement, c'est un effet secondaire. Le message transmis à l'observateur (dans une langue OO probablement dans un appel de méthode sur une interface) entraînera une modification de l'état du composant d'interface utilisateur sur le tas (et ces objets de tas sont visibles pour les autres parties du programme). Le composant UI n'est ni un paramètre de la méthode ni la valeur de retour. Formellement, pour qu'une fonction soit exempte d'effets secondaires, elle doit être idempotente. La notification dans le modèle MVC n'est pas, par exemple, l'interface utilisateur peut afficher une liste des messages qu'elle a reçus - la console - l'appelant deux fois entraîne un état de programme différent.
Flamingpenguin
0

Le mal est un peu excessif… tout dépend du contexte d'utilisation de la langue.

Une autre considération pour ceux déjà mentionnés est que cela simplifie beaucoup la preuve de la correction d'un programme s'il n'y a pas d'effets secondaires fonctionnels.

Ilan
la source
0

Comme les questions ci - dessus ont souligné, les langages fonctionnels ne pas-bien empêcher le code d'avoir des effets secondaires comme nous fournir des outils pour gérer les effets secondaires peuvent se produire dans un morceau de code donné et quand.

Cela s'avère avoir des conséquences très intéressantes. Premièrement, et bien évidemment, il existe de nombreuses choses que vous pouvez faire avec du code libre d’effets secondaires, qui ont déjà été décrites. Mais il y a d'autres choses que nous pouvons faire aussi, même lorsque vous travaillez avec du code qui a des effets secondaires:

  • Dans le code avec l'état mutable, nous pouvons gérer l'étendue de l'état de manière à nous assurer de manière statique qu'il ne puisse pas fuir en dehors d'une fonction donnée, ce qui nous permet de collecter des déchets sans comptage de référence ni schémas de style balise , mais soyez toujours assuré qu'aucune référence ne survivra. Les mêmes garanties sont également utiles pour la gestion des informations confidentielles, etc.
  • Lors de la modification de l'état partagé dans plusieurs threads, nous pouvons éviter les verrous en suivant les modifications et en effectuant une mise à jour atomique à la fin d'une transaction, ou en annulant la transaction et en la répétant si un autre thread effectuait une modification conflictuelle. Ceci n'est réalisable que parce que nous pouvons nous assurer que le code n'a pas d'autres effets que les modifications d'état (que nous pouvons abandonner volontiers). Cette opération est effectuée par la monade STM (Software Transactional Memory) de Haskell.
  • nous pouvons suivre les effets du code et le mettre en boîte de façon triviale, en filtrant tous les effets nécessaires pour garantir sa sécurité, permettant ainsi (par exemple) au code saisi par l'utilisateur d'être exécuté en toute sécurité sur un site Web.
Jules
la source
0

Dans les bases de code complexes, les interactions complexes des effets secondaires sont la chose la plus difficile à raisonner. Je ne peux parler personnellement que de la manière dont fonctionne mon cerveau. Les effets secondaires et les états persistants et les entrées en mutation, etc., me poussent à penser au «quand» et au «où» il arrive que la raison soit rationnelle, et pas seulement «ce qui» se passe dans chaque fonction.

Je ne peux pas me concentrer sur "quoi". Je ne peux pas conclure, après avoir testé de manière approfondie une fonction qui provoque des effets secondaires, qu'elle produira un air de fiabilité dans le code, car les appelants risquent de l'utiliser à mauvais escient en l'appelant au mauvais moment, à partir du mauvais thread, du mauvais ordre. Pendant ce temps, une fonction qui ne provoque aucun effet secondaire et renvoie simplement une nouvelle sortie à partir d’une entrée (sans toucher l’entrée) est quasiment impossible à utiliser de la sorte.

Mais je suis du genre pragmatique, ou du moins je l’essaye, et je ne pense pas que nous devions éliminer tous les effets secondaires au minimum pour pouvoir raisonner au sujet de l’exactitude de notre code (à tout le moins Je trouverais cela très difficile à faire dans des langues comme C). Il m'est très difficile de raisonner sur l'exactitude lorsque nous combinons des flux de contrôle complexes et des effets secondaires.

Les flux de contrôles complexes sont ceux qui sont de type graphique, souvent récursifs ou récursifs (files d'attente d'événements, par exemple, qui n'appellent pas directement des événements de manière récursive mais qui sont de nature "récursive"), peut-être que en train de traverser une structure de graphe liée réelle ou de traiter une file d'attente d'événements non homogène contenant un mélange éclectique d'événements à traiter, ce qui nous conduit à toutes sortes de parties différentes de la base de code et à toutes les différentes causes d'effets secondaires. Si vous essayez de tracer tous les endroits que vous allez finir dans le code, cela ressemblera à un graphe complexe et potentiellement avec des nœuds dans le graphe que vous n’auriez jamais imaginés se trouveraient à cet instant donné, et étant donné qu’ils sont tous provoquant des effets secondaires,

Les langages fonctionnels peuvent avoir des flux de contrôle extrêmement complexes et récursifs, mais le résultat est si facile à comprendre en termes de correction car il n’ya pas toutes sortes d’effets secondaires éclectiques dans le processus. Ce n'est que lorsque des flux de contrôle complexes rencontrent des effets secondaires éclectiques que j'ai du mal à me faire mal à la tête d'essayer de comprendre l'ensemble de ce qui se passe et de savoir si cela ira toujours dans le bon sens.

Ainsi, lorsque j’ai ces cas-là, j’ai souvent beaucoup de difficulté, voire d’impossibilité, à avoir confiance en la justesse de ce code, et encore moins à la possibilité de modifier ce code sans trébucher. Donc, la solution pour moi est de simplifier le flux de contrôle ou de minimiser / unifier les effets secondaires (en unifiant, je veux dire comme causant seulement un type d’effet secondaire à beaucoup de choses pendant une phase particulière du système, pas deux ou trois ou douzaine). J'ai besoin de l'une de ces deux choses pour permettre à mon cerveau simple de se sentir confiant quant à l'exactitude du code existant et à l'exactitude des modifications que je présente. Il est assez facile d’être confiant quant à l’exactitude du code introduisant des effets secondaires si les effets secondaires sont uniformes et simples, de même que le flux de contrôle, comme suit:

for each pixel in an image:
    make it red

Il est assez facile de raisonner sur l'exactitude d'un tel code, mais principalement parce que les effets secondaires sont si uniformes et que le contrôle des flux est tellement simple. Mais disons que nous avions un code comme celui-ci:

for each vertex to remove in a mesh:
     start removing vertex from connected edges():
         start removing connected edges from connected faces():
             rebuild connected faces excluding edges to remove():
                  if face has less than 3 edges:
                       remove face
             remove edge
         remove vertex

Ensuite, il s’agit d’un pseudocode ridiculement surimplifié qui impliquerait généralement beaucoup plus de fonctions et de boucles imbriquées et beaucoup plus de choses à faire (mise à jour de plusieurs cartes de texture, poids des os, états de sélection, etc.), mais même le pseudo-code le rend si difficile à utiliser. raison au sujet de l’exactitude en raison de l’interaction du flux de contrôle complexe de type graphique et des effets secondaires en cours. Donc, une stratégie pour simplifier cela consiste à différer le traitement et à se concentrer sur un type d’effet secondaire à la fois:

for each vertex to remove:
     mark connected edges
for each marked edge:
     mark connected faces
for each marked face:
     remove marked edges from face
     if num_edges < 3:
          remove face

for each marked edge:
     remove edge
for each vertex to remove:
     remove vertex

... quelque chose à cet effet comme une itération de simplification. Cela signifie que nous parcourons les données plusieurs fois, ce qui engendre un coût de calcul indéniable, mais nous constatons souvent que nous pouvons multithreading plus facilement du code résultant, maintenant que les effets secondaires et les flux de contrôle ont pris cette nature uniforme et plus simple. De plus, chaque boucle peut être rendue plus conviviale pour le cache que de parcourir le graphe connecté et d’avoir des effets secondaires au fur et à mesure (ex: utilisez un bit parallèle défini pour marquer ce qui doit être parcouru afin que nous puissions ensuite effectuer les passes différées dans un ordre séquentiel trié utilisant des bitmasks et des FFS). Mais surtout, je trouve la deuxième version tellement plus facile à raisonner en termes de correction et de modification sans causer de bugs. Pour que'

Et après tout, nous avons besoin que des effets secondaires se produisent à un moment donné, sinon nous aurions simplement des fonctions qui produiraient des données sans nulle part où aller. Nous avons souvent besoin d'enregistrer quelque chose dans un fichier, d'afficher quelque chose sur un écran, d'envoyer les données via un socket, quelque chose de ce genre, et tout cela est un effet secondaire. Mais nous pouvons certainement réduire le nombre d’effets secondaires superflus, ainsi que le nombre d’effets secondaires se produisant lorsque les flux de contrôle sont très compliqués, et je pense qu’il serait beaucoup plus facile d’éviter les bugs si nous le faisions.


la source
-1

Ce n'est pas mal. Mon avis, il est nécessaire de distinguer les deux types de fonctions - avec effets secondaires et sans. La fonction sans effets secondaires: - retourne toujours la même chose avec les mêmes arguments, ainsi par exemple une telle fonction sans aucun argument n'a aucun sens. - Cela signifie également que l'ordre dans lequel certaines de ces fonctions sont appelées ne joue aucun rôle - doit pouvoir s'exécuter et peut être débogué tout seul (!), Sans autre code. Et maintenant, lol, regarde ce que JUnit fait. Une fonction avec des effets secondaires: - présente en quelque sorte des "fuites", ce qui peut être automatiquement mis en évidence - elle est très importante pour le débogage et la recherche des erreurs, généralement causées par des effets secondaires. - Toute fonction avec des effets secondaires a également une "partie" d'elle-même sans effets secondaires, ce qui peut également être séparé automatiquement. Si mal sont ces effets secondaires,

utilisateur225623
la source
cela ne semble rien offrir de substantiel sur les points évoqués et expliqués dans les 12 réponses précédentes
gnat