Étant donné que la pureté d'un paramètre d'entrée est inconnue jusqu'à l'exécution, une fonction est-elle immédiatement considérée comme impure si elle prend une fonction comme paramètre d'entrée?
Connexes: si une fonction applique une fonction pure qui est définie en dehors de la fonction, mais qui n'est pas transmise en tant que paramètre, est-elle toujours pure si elle remplit les critères de l'absence d'effets secondaires et la sortie dépend uniquement de l'entrée?
Pour le contexte, j'écris du code fonctionnel en JavaScript.
functional-programming
pure-function
Dancrumb
la source
la source
foo = function(function bar){ print(bar.toString()) }
foo = function(function bar) { return 3; }
est pur et prend une fonction en argument.toString()
(c'est-à-dire celle que vous trouveriez sur l'objet Java).Réponses:
Tant que toutes les valeurs utilisées dans la fonction sont définies uniquement par ses paramètres, c'est une fonction pure.
La facette que la sortie est la même à chaque fois pour la même entrée est contrôlée par la pureté des paramètres. Si vous supposez que les paramètres (comme un argument de fonction) sont également purs, alors c'est pur.
Dans un langage comme Javascript où la pureté n'est pas appliquée, cela signifie qu'il est possible de faire en sorte qu'une fonction par ailleurs pure ait un comportement impur en invoquant une fonction impure passée en paramètre.
Cela signifie effectivement que pour les langages qui n'imposent pas la pureté (c'est-à-dire presque tous), il est impossible de définir une fonction pure qui invoque des fonctions passées en arguments. Il est toujours utile de les écrire aussi pur que possible et de les raisonner en tant que fonctions pures, mais vous devez faire preuve de prudence car l'hypothèse selon laquelle elle est pure sera brisée si vous passez les mauvais arguments.
D'après mon expérience dans la pratique, ce n'est généralement pas un gros problème - je trouve rare que des fonctions impures soient utilisées comme arguments de fonction pour des fonctions pures.
la source
areaOfCircle r => Math.Pi * r * r
, seraareaOfCircle
-t-elle non pure car elle n'utilisera pas seulement des paramètres?f(f2)
qui invoquef2
ne dépend pas de façon transitoire de quoi que ce soitf2
. Une fonction qui pourrait appeler des fonctions transmises arbitrairement n'est pas pure.function compose(f, g) {return function h(x) {return f(g(x));};}
, ce qui est pur malgré la prise de fonctions comme arguments.find
programme un prédicat impur qui renvoie "vrai" pour le troisième élément correspondant qu'il rencontre, ou un certain non-sens.Non. Contre-exemple:
Peu importe qu'il s'agisse d'
other_function
une fonction pure, d'une fonction impure ou pas du tout. Lapure
fonction est pure.Autre contre-exemple:
Cette fonction est pure, même si elle
x
est impure.identity(impure_function)
sera toujours de retourimpure_function
, peu importe combien de fois vous répétez l'appel. Peu importe que celaidentity(impure_function)()
renvoie toujours la même chose; La valeur de retour d'une valeur de retour d' une fonction n'affecte pas sa pureté.En général, si une fonction peut appeler une fonction, elle a été passée en argument, elle n'est pas pure. Par exemple, une fonction
function call(f) {f();}
n'est pas pure, car même si elle ne fait mention d'aucun état global ou mutable, celaf
pourraitalert
provoquer des effets secondaires visibles.Si une fonction prend des fonctions comme arguments, mais qu'elle ne les appelle pas ou ne les fait pas appeler, elle peut être pure. Il pourrait encore être impur s'il fait une autre chose impure. Par exemple,
function f(ignored_function) {alert('This isn't pure.');}
est impur, même s'il n'appelle jamaisignored_function
.la source
Techniquement, oui, sauf s'il existe un moyen dans votre langue de garantir que la fonction d'entrée est également pure.
Oui. Concentrons-nous donc sur ce qui compte ici. Appeler une fonction pure ou non n'est pas en soi utile. Les fonctions pures sont utiles car produire la même sortie pour n'importe quelle entrée et ne pas dépendre de l'état ou avoir des effets secondaires est un ensemble de propriétés très utile. Cela signifie qu'une fois que votre fonction a été exécutée, vous pouvez vous «souvenir» de la réponse pour cette entrée et ce sera toujours vrai. Vous n'avez pas non plus besoin d'exécuter à nouveau la fonction pour générer des effets secondaires. Et vous pouvez exécuter cette fonction en parallèle (ou dans le désordre) avec d'autres fonctions et savoir qu'elles n'auront pas d'interactions cachées qui se comportent mal.
Ces propriétés utiles restent valables si la fonction utilise d'autres fonctions en lecture seule pour effectuer son travail, quelle que soit la façon dont elle les référence.
la source
Comme Telastyn l'a dit: Techniquement, oui, à moins qu'il n'y ait un moyen dans votre langue de garantir que la fonction d'entrée est également pure.
Ce n'est pas hypothétique, il existe en effet de bons moyens de garantir cela. Au moins dans une langue fortement typée.
Une telle fonction ~ pure que vous écririez en JavaScript
peut être traduit directement en Haskell:
Maintenant, en JavaScript, vous pouvez faire des trucs diaboliques comme
Ce n'est pas possible à Haskell . La raison en est que quelque chose d'effet secondaire
console.log()
doit toujours avoir un type de résultatIO something
, pas seulementsomething
seul.Pour que cette expression soit vérifiée, nous aurions besoin de donner
foo
la signature de typeMais il s'avère que je ne peux plus l'implémenter alors: parce que la fonction d'argument a
IO
dans son résultat, je ne peux pas l'utiliser à l'intérieurfoo
.La seule façon dont je pourrais utiliser une
IO
actionfoo
est si le résultat defoo
aIO Int
lui-même le type :Mais à ce stade, il ressort clairement de la signature
foo
que ce n'est pas une fonction pure non plus.la source
unsafeIO
:-)IO
. Soit dit en passant, il peut également être utilisé pour provoquer le chaos en masquant les effets secondaires dans une fonction «pure», mais ce n'est vraiment pas sûr dans Haskell car il n'y a pas vraiment de moyen fiable de spécifier l'ordre d'évaluation des fonctions pures.unsafeIO
; c'est une trappe d'évacuation de dernier recours qui contourne les garanties du système de type, et donc la vôtre n'est pas un bon point.Non ça ne l'est pas.
Si la fonction passée est impure ET que votre fonction appelle la fonction passée, alors votre fonction sera considérée comme impure.
La relation pure / impure est un peu comme sync / async dans JS. Vous pouvez librement utiliser du code pur impur, mais pas l'inverse.
la source