28 votes

Les effets secondaires sont-ils tout ce qui ne peut être trouvé dans une fonction pure?

Est-il sûr de dire que la dichotomie suivante est valable:

Chaque fonction donnée est

  • soit pure
  • ou a des effets secondaires

Si c'est le cas, les effets secondaires (d'une fonction) sont tout ce qui ne peut pas être trouvé dans une fonction pure.

58voto

Tomas Petricek Points 118959

Cela dépend beaucoup des définitions que vous choisissez. Il est certainement juste de dire qu'une fonction est pur ou impur. Une pure fonction retourne toujours le même résultat et ne pas modifier l'environnement. Un impur fonction peut renvoyer des résultats différents lorsqu'il est exécuté à plusieurs reprises (ce qui peut être causé par faire quelque chose pour l'environnement).

Sont toutes les impuretés des effets secondaires? Je ne voudrais pas le dire - une fonction peut dépendre de quelque chose dans l'environnement dans lequel il s'exécute. Cela pourrait être la lecture de la configuration, de la localisation GPS ou la lecture de données à partir d'internet. Ce ne sont pas vraiment des "effets secondaires", car elle ne rien faire pour le monde.

Je pense qu'il ya deux différents types d'impuretés:

  • Sortie de l'impureté , c'est quand une fonction n'a quelque chose au monde. En Haskell, c'est modélisé à l'aide d'monades - un impur fonction a -> b est en fait une fonction a -> M bM capture les autres choses qu'il n'a pour le monde.

  • L'entrée de l'impureté est une fonction qui exige quelque chose de l'environnement. Un impur fonction a -> b peut être modélisé comme une fonction C a -> b lorsque le type C captures d'autres choses de l'environnement que la fonction peut accéder.

Les monades et de sortie des impuretés sont certainement mieux connu, mais je pense que l'entrée d'impuretés sont tout aussi importants. J'ai écrit ma thèse de Doctorat sur l'entrée d'impuretés que j'appelle coeffects, j'ai donc ce pourrait être une réponse biaisée si.

10voto

artemonster Points 423

Pour une fonction pure, elle doit:

  1. ne pas être affecté par les effets secondaires (c'est à dire retourne toujours la même valeur pour les mêmes arguments)
  2. de ne pas causer des effets secondaires

Mais, vous voyez, il définit fonctionnelle de pureté avec la propriété ou de l'absence d'effets secondaires. Vous êtes en essayant de l'appliquer à rebours de la logique de déduire de la définition des effets secondaires à l'aide de fonctions pures, ce qui logiquement devrait fonctionner, mais pratiquement la définition d'un effet secondaire n'a rien à voir avec la fonctionnelle de la pureté.

6voto

user3237465 Points 1197

Je ne vois pas de problèmes avec la définition de fonction pure: une pure fonction est une fonction. I. e. il dispose d'un domaine, d'une arrivée et de cartes les éléments de l'ancien pour les éléments de ce dernier. Elle est définie sur toutes les entrées. Il ne fait rien pour l'environnement, parce que "l'environnement" à ce point, n'existe pas: il n'y a pas de machines qui peuvent exécuter (pour une définition de "execute") une fonction donnée. Il y a juste un total de cartographie à partir de quelque chose à quelque chose.

Puis certains capitaliste décide d'envahir le monde de fonctions bien déterminées et d'asservir ces pures créatures, mais leur juste essence ne peuvent pas survivre dans notre cruelle réalité, les fonctions de devenir sale et commencer à faire de la CPU plus chaud.

C'est donc l'environnement est responsable de la prise de CPU chauffe et il est parfaitement logique de parler de pureté avant que son propriétaire a été abusé et exécuté. De la même manière référentielle de la transparence est une propriété d'une langue, il ne tient pas dans l'environnement en général, car il y a peut être un bug du compilateur ou d'une météorite peut tomber sur votre tête et votre programme va arrêter de produire le même résultat.

Mais il y a d'autres créatures: le sombre habitants de la pègre. Ils ressemblent à des fonctions, mais ils sont conscients de l'environnement et peut interagir avec: à lire variables, envoyer des messages et lancer des missiles. Nous appelons ces tombée proches de fonctions "impures" ou "effectful" et d'éviter autant que possible, parce que leur nature est si sombre qu'il est impossible de raisonner sur eux.

Donc, il y a clairement une grosse différence entre les fonctions qui peuvent interagir avec l'extérieur et ceux qui ne l'est pas. Toutefois, la définition de "l'extérieur" peut varier aussi. L' State monade est modélisée en utilisant uniquement pur des outils, mais nous pensons f : Int -> State Int Int comme sur effectful calcul. En outre, la non-résiliation et exceptions (error "...") sont des effets, mais haskellers l'habitude de ne pas considérer de la sorte.

En résumant, une pure fonction est bien définie concept mathématique, mais nous avons l'habitude de considérer que les fonctions dans les langages de programmation et ce qui est pur, il dépend de votre point de vue, de sorte qu'il n'a pas beaucoup de sens à parler de dichotomies lorsque les concepts ne sont pas bien définis.

5voto

erisco Points 6101

Un moyen de définir la pureté d'une fonction f est ∀x∀y x = y ⇒ f x = f y, c'est à dire d'accorder le même argument, la fonction renvoie le même résultat, ou il préserve l'égalité.

Ce n'est pas ce que généralement les gens veulent dire quand ils parlent de "pure fonctions"; il signifie "pur" comme "ne pas avoir d'effets secondaires". Je n'ai pas compris comment qualifier un "effet secondaire" (commentaires bienvenus!) donc, je n'ai rien à dire à ce sujet.

Néanmoins, je vais explorer cette notion de pureté car elle peut être liée à la compréhension. Je ne suis pas expert ici; c'est surtout moi juste la randonnée. Toutefois, j'ai de l'espoir qu'elle suscite quelques perspicace (et correctives!) commentaires.

Pour comprendre la pureté nous devons savoir ce que l'égalité dont nous parlons. Qu'est - x = y moyenne de, et de quoi est - f x = f y moyenne?

Un choix est le Haskell sémantique de l'égalité. C'est, de l'égalité, de la sémantique Haskell attribue à ses termes. Autant que je sache, il n'y a aucune denotational de la sémantique pour Haskell, mais Wikibooks Haskell Denotational Sémantique offre une norme raisonnable que je pense que la communauté plus ou moins d'accord pour ad-hoc. Lorsque Haskell dit ses fonctions sont de la pure c'est l'égalité, il se réfère.

Un autre choix est définie par l'utilisateur et pour l'égalité (c'est à dire (==)) en dérivant l' Eq classe. C'est pertinent lors de l'utilisation de denotational conception - qui est, nous sommes attribution de notre propre sémantique des termes. Avec ce choix, nous pouvons accidentellement écrire des fonctions qui sont impures; Haskell n'est pas concerné par notre sémantique.

Je vais consulter le Haskell sémantique de l'égalité en tant que = et défini par l'utilisateur de l'égalité en tant que ==. Aussi je suppose qu' == est une égalité de relation ce n'est pas valable pour certains cas d' == comme pour l' Float.

Lorsque j'utilise x == y comme une proposition vraiment ce que je veux dire, est - x == y = True ∨ x == y = ⊥car x == y :: Bool et ⊥ :: Bool. En d'autres termes, quand je dis x == y est vrai, je veux dire que si on calcule à quelque chose d'autre que ⊥ puis il calcule la valeur True.

Si x et y sont égaux selon Haskell sémantique, alors ils sont égaux selon toute autre sémantique, nous pouvons choisir.

La preuve: si x = y alors x == y ≡ x == x et x == x est vrai, car == est pur (selon =) et réflexive.

De même, nous pouvons prouver ∀f∀x∀y x = y ⇒ f x == f y. Si x = y alors f x = f y (parce qu' f est pur), par conséquent f x == f y ≡ f x == f x et f x == f x est vrai, car == pure et réflexive.

Voici un exemple stupide de la façon dont nous pouvons nous débarrasser de la pureté pour un utilisateur défini par l'égalité.

data Pair a = Pair a a

instance (Eq a) => Eq (Pair a) where
  Pair x _ == Pair y _ = x == y

swap :: Pair a -> Pair a
swap (Pair x y) = Pair y x

Maintenant, nous avons:

Pair 0 1 == Pair 0 2

Mais:

swap (Pair 0 1) /= swap (Pair 0 2)

Remarque: ¬(Pair 0 1 = Pair 0 2) si nous n'étions pas la garantie que notre définition de l' (==) seraient d'accord.

Plus irrésistible exemple est de considérer Data.Set. Si x, y, z :: Set A , alors vous serait espère que cela vaut, par exemple:

x == y ⇒ (Set.union z) x == (Set.union z) y

Surtout lorsqu' Set.fromList [1,2,3] et Set.fromList [3,2,1] dénoter le même ensemble mais probablement avoir différentes (caché) de représentations (pas d'équivalent en Haskell sémantique). C'est-à-dire que nous voulons être sûrs que ∀z Set.union z est pur selon (==) pour Set.

Ici, c'est un type que j'ai joué avec:

newtype Spry a = Spry [a]

instance (Eq a) => Eq (Spry a) where
  Spry xs == Spry ys = fmap head (group xs) == fmap head (group ys)

Un Spry est une liste qui a la non-égalité des éléments adjacents. Exemples:

Spry [] == Spry []
Spry [1,1] == Spry [1]
Spry [1,2,2,2,1,1,2] == Spry [1,2,1,2]

Compte tenu de cela, ce qui est une pure mise en œuvre (selon == pour Spry) pour flatten :: Spry (Spry a) -> Spry a telle que si l' x est un élément d'un sous-spry il est également un élément de la aplati spry (c'est à dire quelque chose comme ∀x∀xs∀i x ∈ xs[i] ⇒ x ∈ flatten xs)? Exercice pour le lecteur.

Il est également intéressant de noter que les fonctions dont nous avons parlé sont dans le même domaine, de sorte qu'ils sont de type A → A. C'est, sauf lorsque nous avons prouvé ∀f∀x∀y x = y ⇒ f x == f y qui traverse de Haskell domaine sémantique de notre propre. Cela pourrait être un homomorphism de quelques sortes... peut-être un théoricien de la catégorie pourrait peser dans les ici (et s'il vous plaît le faire!).

1voto

jcast Points 948

Effets secondaires font partie de la définition de la langue. Dans l'expression

f e

les effets secondaires de l' e toutes les pièces de l' es'comportement qui sont "déplacés" et de devenir une partie du comportement de l'application de l'expression, plutôt que d'être envoyés en f comme partie de la valeur de e.

Pour un exemple concret, considérons ce programme:

f x = x; x
f (print 3)

où, conceptuellement, la syntaxe x; x signifie "run x, puis exécutez-le à nouveau et retourner le résultat'.

Dans une langue où l' print écrit sur la sortie standard stdout comme un effet secondaire, il écrit

3

parce que la production est une partie de la sémantique de l'application de l'expression.

Dans une langue où la sortie de l' print n'est pas un effet secondaire, il écrit

3
3

parce que la production est une partie de la sémantique de l' x variable à l'intérieur de la définition de l' f.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X