Pure Functions: Does “No Side Effects” Imply “Always Same Output, Given Same Input”?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







83















The two conditions that define a function as pure are as follows:




  1. No side effects (i.e. only changes to local scope are allowed)

  2. Always return the same output, given the same input


If the first condition is always true, are there any times the second condition is not true?



I.e. is it really only necessary with the first condition?










share|improve this question




















  • 3





    Your premises are ill-specified. "Input" is too broad. Functions can be thought two have kinds of input. Their arguments, and "environmental"/"contextual". A function that returns the system time could be thought to be pure (even though it's obv not) if you don't distinguish between these two kinds of input.

    – Alexander
    Mar 5 at 3:22






  • 4





    @Alexander: In the context of "pure function", "input" is commonly understood to mean the parameters / arguments that are passed explicitly (by whatever mechanism the programming language uses). That's part of the definition of "pure function". But you are right, it's important to mind the definition.

    – sleske
    Mar 5 at 8:01






  • 3





    Trivial counter-example: return the value of a global variable. No side effects (the global is only ever read!), but still potentially different results every time. (If you don't like globals, return the address of a local variable which depends on the call stack at run time).

    – Peter A. Schneider
    Mar 5 at 15:17








  • 1





    You need to expand your definition of "side effects"; you say that a pure method does not produce side effects, but you need to also note that a pure method does not consume side effects produced elsewhere.

    – Eric Lippert
    Mar 5 at 15:28






  • 2





    @sleske Perhaps commonly understood, but the lack of that distinction is the exact cause of OP's confusion.

    – Alexander
    Mar 5 at 15:54


















83















The two conditions that define a function as pure are as follows:




  1. No side effects (i.e. only changes to local scope are allowed)

  2. Always return the same output, given the same input


If the first condition is always true, are there any times the second condition is not true?



I.e. is it really only necessary with the first condition?










share|improve this question




















  • 3





    Your premises are ill-specified. "Input" is too broad. Functions can be thought two have kinds of input. Their arguments, and "environmental"/"contextual". A function that returns the system time could be thought to be pure (even though it's obv not) if you don't distinguish between these two kinds of input.

    – Alexander
    Mar 5 at 3:22






  • 4





    @Alexander: In the context of "pure function", "input" is commonly understood to mean the parameters / arguments that are passed explicitly (by whatever mechanism the programming language uses). That's part of the definition of "pure function". But you are right, it's important to mind the definition.

    – sleske
    Mar 5 at 8:01






  • 3





    Trivial counter-example: return the value of a global variable. No side effects (the global is only ever read!), but still potentially different results every time. (If you don't like globals, return the address of a local variable which depends on the call stack at run time).

    – Peter A. Schneider
    Mar 5 at 15:17








  • 1





    You need to expand your definition of "side effects"; you say that a pure method does not produce side effects, but you need to also note that a pure method does not consume side effects produced elsewhere.

    – Eric Lippert
    Mar 5 at 15:28






  • 2





    @sleske Perhaps commonly understood, but the lack of that distinction is the exact cause of OP's confusion.

    – Alexander
    Mar 5 at 15:54














83












83








83


11






The two conditions that define a function as pure are as follows:




  1. No side effects (i.e. only changes to local scope are allowed)

  2. Always return the same output, given the same input


If the first condition is always true, are there any times the second condition is not true?



I.e. is it really only necessary with the first condition?










share|improve this question
















The two conditions that define a function as pure are as follows:




  1. No side effects (i.e. only changes to local scope are allowed)

  2. Always return the same output, given the same input


If the first condition is always true, are there any times the second condition is not true?



I.e. is it really only necessary with the first condition?







javascript functional-programming language-lawyer pure-function






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 5 at 8:42









Will Ness

46.6k469127




46.6k469127










asked Mar 4 at 22:07









MagnusMagnus

1,88011328




1,88011328








  • 3





    Your premises are ill-specified. "Input" is too broad. Functions can be thought two have kinds of input. Their arguments, and "environmental"/"contextual". A function that returns the system time could be thought to be pure (even though it's obv not) if you don't distinguish between these two kinds of input.

    – Alexander
    Mar 5 at 3:22






  • 4





    @Alexander: In the context of "pure function", "input" is commonly understood to mean the parameters / arguments that are passed explicitly (by whatever mechanism the programming language uses). That's part of the definition of "pure function". But you are right, it's important to mind the definition.

    – sleske
    Mar 5 at 8:01






  • 3





    Trivial counter-example: return the value of a global variable. No side effects (the global is only ever read!), but still potentially different results every time. (If you don't like globals, return the address of a local variable which depends on the call stack at run time).

    – Peter A. Schneider
    Mar 5 at 15:17








  • 1





    You need to expand your definition of "side effects"; you say that a pure method does not produce side effects, but you need to also note that a pure method does not consume side effects produced elsewhere.

    – Eric Lippert
    Mar 5 at 15:28






  • 2





    @sleske Perhaps commonly understood, but the lack of that distinction is the exact cause of OP's confusion.

    – Alexander
    Mar 5 at 15:54














  • 3





    Your premises are ill-specified. "Input" is too broad. Functions can be thought two have kinds of input. Their arguments, and "environmental"/"contextual". A function that returns the system time could be thought to be pure (even though it's obv not) if you don't distinguish between these two kinds of input.

    – Alexander
    Mar 5 at 3:22






  • 4





    @Alexander: In the context of "pure function", "input" is commonly understood to mean the parameters / arguments that are passed explicitly (by whatever mechanism the programming language uses). That's part of the definition of "pure function". But you are right, it's important to mind the definition.

    – sleske
    Mar 5 at 8:01






  • 3





    Trivial counter-example: return the value of a global variable. No side effects (the global is only ever read!), but still potentially different results every time. (If you don't like globals, return the address of a local variable which depends on the call stack at run time).

    – Peter A. Schneider
    Mar 5 at 15:17








  • 1





    You need to expand your definition of "side effects"; you say that a pure method does not produce side effects, but you need to also note that a pure method does not consume side effects produced elsewhere.

    – Eric Lippert
    Mar 5 at 15:28






  • 2





    @sleske Perhaps commonly understood, but the lack of that distinction is the exact cause of OP's confusion.

    – Alexander
    Mar 5 at 15:54








3




3





Your premises are ill-specified. "Input" is too broad. Functions can be thought two have kinds of input. Their arguments, and "environmental"/"contextual". A function that returns the system time could be thought to be pure (even though it's obv not) if you don't distinguish between these two kinds of input.

– Alexander
Mar 5 at 3:22





Your premises are ill-specified. "Input" is too broad. Functions can be thought two have kinds of input. Their arguments, and "environmental"/"contextual". A function that returns the system time could be thought to be pure (even though it's obv not) if you don't distinguish between these two kinds of input.

– Alexander
Mar 5 at 3:22




4




4





@Alexander: In the context of "pure function", "input" is commonly understood to mean the parameters / arguments that are passed explicitly (by whatever mechanism the programming language uses). That's part of the definition of "pure function". But you are right, it's important to mind the definition.

– sleske
Mar 5 at 8:01





@Alexander: In the context of "pure function", "input" is commonly understood to mean the parameters / arguments that are passed explicitly (by whatever mechanism the programming language uses). That's part of the definition of "pure function". But you are right, it's important to mind the definition.

– sleske
Mar 5 at 8:01




3




3





Trivial counter-example: return the value of a global variable. No side effects (the global is only ever read!), but still potentially different results every time. (If you don't like globals, return the address of a local variable which depends on the call stack at run time).

– Peter A. Schneider
Mar 5 at 15:17







Trivial counter-example: return the value of a global variable. No side effects (the global is only ever read!), but still potentially different results every time. (If you don't like globals, return the address of a local variable which depends on the call stack at run time).

– Peter A. Schneider
Mar 5 at 15:17






1




1





You need to expand your definition of "side effects"; you say that a pure method does not produce side effects, but you need to also note that a pure method does not consume side effects produced elsewhere.

– Eric Lippert
Mar 5 at 15:28





You need to expand your definition of "side effects"; you say that a pure method does not produce side effects, but you need to also note that a pure method does not consume side effects produced elsewhere.

– Eric Lippert
Mar 5 at 15:28




2




2





@sleske Perhaps commonly understood, but the lack of that distinction is the exact cause of OP's confusion.

– Alexander
Mar 5 at 15:54





@sleske Perhaps commonly understood, but the lack of that distinction is the exact cause of OP's confusion.

– Alexander
Mar 5 at 15:54












6 Answers
6






active

oldest

votes


















112














Here are a few counterexamples that do not change the outer scope but are still considered impure:




  • function a() { return Date.now(); }

  • function b() { return window.globalMutableVar; }

  • function c() { return document.getElementById("myInput").value; }


  • function d() { return Math.random(); } (which admittedly does change the PRNG, but is not considered observable)


Accessing non-constant non-local variables is enough to be able to violate the second condition.



I always think of the two conditions for purity as complementary:




  • the result evaluation must not have effects on side state

  • the evaluation result must not be affected by side state


The term side effect only refers to the first, the function modifying the non-local state. However, sometimes read operations are considered as side effects as well: when they are operations and involve writing as well, even if their primary purpose is to access a value. Examples for that are generating a pseudo-random number that modifies the generator's internal state, reading from an input stream that advances the read position, or reading from an external sensor that involves a "take measurement" command.






share|improve this answer





















  • 1





    Thanks Bergi. For some reason I thought side effects included reading variables outside of local scope, but I guess it is only a side effect if it writes such external variables.

    – Magnus
    Mar 5 at 6:40











  • Note that the two conditions are actually logically independent: This answer shows that 1. does not imply 2., but there are also many counterexamples that 2. does not imply 1. - for example, a function setDate(newDate) that sets the computer's current date to newDate has property 2. (the return value can be newDate or nothing), but it still violates 1. (it sets the current date).

    – sleske
    Mar 5 at 8:08








  • 17





    If prompt("you choose") does not have side effects, we should take a step back and clarify the meaning of side effects.

    – Holger
    Mar 5 at 8:57






  • 1





    @Magnus Yes, exactly that's what effect means. I'll try to clarify in my answer as well, I didn't expect such large attention and want to make answer worthy of dozens of votes :-)

    – Bergi
    Mar 5 at 13:09






  • 2





    Well for all you know Math.random() returns a thermal diode. It's not actually specified to use a bad RNG.

    – Joshua
    Mar 5 at 22:39



















28














The "normal" way of phrasing what a pure function is, is in terms of referential transparency. A function is pure if it is referentially transparent.



Referential Transparency, roughly, means that you can replace the call to the function with its return value or vice versa at any point in the program, without changing the meaning of the program.



So, for example, if C's printf were referentially transparent, these two programs should have the same meaning:



printf("Hello");


and



5;


and all of the following programs should have the same meaning:



5 + 5;

printf("Hello") + 5;

printf("Hello") + printf("Hello");


Because printf returns the number of characters written, in this case 5.



It gets even more obvious with void functions. If I have a function void foo, then



foo(bar, baz, quux);


should be the same as



;


I.e. since foo returns nothing, I should be able to replace it with nothing without changing the meaning of the program.



It is clear, then, that neither printf nor foo are referentially transparent, and thus neither of them are pure. In fact, a void function can never be referentially transparent, unless it is a no-op.



I find this definition much easier to handle as the one you gave. It also allows you to apply it at any granularity you want: you can apply it to individual expressions, to functions, to entire programs. It allows you, for example, to talk about a function like this:



func fib(n):
return memo[n] if memo.has_key?(n)
return 1 if n <= 1
return memo[n] = fib(n-1) + fib(n-2)


We can analyze the expressions that make up the function and easily conclude that they are not referentially transparent and thus not pure, since they use a mutable data structure, namely the memo array. However, we can also look at the function and can see that it is referentially transparent and thus pure. This is sometimes called external purity, i.e. a function that appears pure to the outside world, but is implemented impure internally.



Such functions are still useful, because while impurity infects everything around it, the external pure interface builds a kind of "purity barrier", where the impurity only infects the three lines of the function, but does not leak out into the rest of the program. These three lines are much easier to analyze for correctness than the entire program.






share|improve this answer





















  • 2





    That impurity affects the whole program once you have concurrency.

    – R..
    Mar 5 at 16:27











  • @R.. Can you think of a way that concurrency could make the described Fibonacci function externally impure? I can't. Writing to memo[n] is idempotent, and failing to read from it merely wastes CPU cycles.

    – Brilliand
    Mar 5 at 22:12











  • I agree with both of you. Impurity can lead to concurrency problems, but it doesn't in this specific case.

    – Jörg W Mittag
    Mar 5 at 22:17











  • @R.. It's not hard to imagine a concurrency-aware version.

    – immibis
    Mar 5 at 23:48






  • 1





    @Brilliand For example, memo[n] = ... may first create a dictionary entry, and then store the value into it. This leaves a window during which another thread could see an uninitialized entry.

    – immibis
    Mar 5 at 23:49



















12














It seems to me that the second condition you have described is a weaker constraint than the first.



Let me give you an example, suppose you have a function to add one that also logs to the console:



function addOneAndLog(x) {
console.log(x);
return x + 1;
}


The second condition you supplied is satisfied: this function always returns the same output when given the same input. It is, however, not a pure function because it includes the side effect of logging to the console.



A pure function is, strictly speaking, a function that satisfies the property of referential transparency. That is the property that we can replace a function application with the value it produces without changing the behaviour of the program.



Suppose we have a function that simply adds:



function addOne(x) {
return x + 1;
}


We can replace addOne(5) with 6 anywhere in our program and nothing will change.



By contrast, we cannot replace addOneAndLog(x) with the value 6 anywhere in our program without changing behaviour because the first expression results in something being written to the console whereas the second one does not.



We consider any of this extra behaviour that addOneAndLog(x) performs besides returning output as a side-effect.






share|improve this answer
























  • "It seems to me that the second condition you have described is a weaker constraint than the first." No, the two conditions are logically independent.

    – sleske
    Mar 5 at 8:03











  • @sleske you are mistaken. I have provided clear definitions for the terms pure and side-effect. Within these constraints, there is nothing that a function with no side effects besides return the same output for a given input. I have however provided examples where the second condition can be satisfied without the first. The fundamnetal concept to understand the notion of purity is referential transparency.

    – TheInnerLight
    Mar 5 at 9:11











  • Small typo: There is nothing that a function with no side effects can do besides returning the same output for a given input.

    – TheInnerLight
    Mar 5 at 9:18











  • What about something like returning the current time? That does not have side effects, but it does return a different output for the same input. Or more generally, any function where the result depends not only on the input parameters, but also on a (changeable) global variable.

    – sleske
    Mar 5 at 9:24








  • 2





    It seems you are using a different definition of "side effect" than what is commonly used. A side effect is commonly defined as "an observable effect besides returning a value" or an "observable change in state" - see e.g. Wikipedia , this post on softwareengineering.SE. You are totally right that Date.now() is not pure/referentially transparent, but not because it has side-effects, but because its result depends on more than just its input.

    – sleske
    Mar 5 at 10:05



















7














There could be a source of randomness from outside the system. Suppose that part of your calculation includes the room temperature. Then executing the function will yield different results each time depending on the random external element of room temperature. The state is not changed by executing the program.



All I can think of, anyway.






share|improve this answer





















  • 3





    According to me, these "randomness from outside the system" are a form of side effect. Functions with these behaviors are not "pures".

    – Joseph M. Dion
    Mar 5 at 1:06



















3














Problem with FP definitions is that they are very artificial. Each evaluation/calculation has side-effects on the evaluator. It's theoretically true. A deny of this shows only that FP apologists ignore philosophy and logic: an "evaluation" means changing of the state of some intelligent environment (machine, brain, etc). This is the nature of the evaluation process. No changes - no "calculi". The effect can be very visible: heating the CPU or its failure, shutting down the motherboard in case of overheating, and so on.



When you talk about referential transparency, you should understand that information about such transparency is available for human as a creator of the whole system and holder of semantical information and may be not available for the compiler. For example, a function can read some external resource and it will have IO monad in its signature but it will return the same value all the time (for example, the result of current_year > 0). The compiler does not know that function will return always the same result, so the function is impure but has referentially transparent property and can be substituted with True constant.



So, to avoid such inaccuracy, we should distinguish mathematical functions and "functions" in programming languages. Functions in Haskell are always impure and definition of purity related to them is always very conditionally: they are running on real hardware with real side-effects and physical properties, which is wrong for mathematical functions. This means that the example with "printf" function is totally incorrect.



But not all mathematical functions are pure too: each function which has t (time) as a parameter may be impure: t holds all effects and stochastic nature of the function: in common case you have input signal and have not idea about actual values, it can be even a noise.






share|improve this answer

































    2















    If the first condition is always true, are there any times the second
    condition is not true?




    Yes



    Consider simple code snippet below



    public int Sum(int a, int b) {
    Random rnd = new Random();
    return rnd.Next(1, 10);
    }


    This code will return random output for same given set of inputs - however it does not have any side effect.



    The overall effect of both the points #1 & #2 you mentioned when combined together means : At any point of time if function Sum with same i/p is replaced with its result in a program, overall meaning of program does not change. This is nothing but Referential transparency.






    share|improve this answer


























    • But in this case, the first condition is not verified: writing to the console is considered a side effect, since it changes the state of the machine itself.

      – Right leg
      Mar 5 at 8:30











    • @Rightleg thx for pointing it out. Somehow I misunderstood OP totally other way. corrected answer.

      – Rahul Agarwal
      Mar 5 at 8:41






    • 2





      Doesn't it change the state of the random generator?

      – Eric Duminil
      Mar 5 at 9:14






    • 1





      Generating a random number is itself a side effect, unless the state of the random number generator is supplied explicitly which would make the function satisfy condition 2.

      – TheInnerLight
      Mar 5 at 9:23






    • 1





      rnd doesn't escape the function, so the fact that its state changes doesn't matter to the purity of the function, but the fact that the Random constructor uses the current time as a seed value means that there are "inputs" other than a and b.

      – Sneftel
      Mar 5 at 11:14












    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54992302%2fpure-functions-does-no-side-effects-imply-always-same-output-given-same-inp%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    6 Answers
    6






    active

    oldest

    votes








    6 Answers
    6






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    112














    Here are a few counterexamples that do not change the outer scope but are still considered impure:




    • function a() { return Date.now(); }

    • function b() { return window.globalMutableVar; }

    • function c() { return document.getElementById("myInput").value; }


    • function d() { return Math.random(); } (which admittedly does change the PRNG, but is not considered observable)


    Accessing non-constant non-local variables is enough to be able to violate the second condition.



    I always think of the two conditions for purity as complementary:




    • the result evaluation must not have effects on side state

    • the evaluation result must not be affected by side state


    The term side effect only refers to the first, the function modifying the non-local state. However, sometimes read operations are considered as side effects as well: when they are operations and involve writing as well, even if their primary purpose is to access a value. Examples for that are generating a pseudo-random number that modifies the generator's internal state, reading from an input stream that advances the read position, or reading from an external sensor that involves a "take measurement" command.






    share|improve this answer





















    • 1





      Thanks Bergi. For some reason I thought side effects included reading variables outside of local scope, but I guess it is only a side effect if it writes such external variables.

      – Magnus
      Mar 5 at 6:40











    • Note that the two conditions are actually logically independent: This answer shows that 1. does not imply 2., but there are also many counterexamples that 2. does not imply 1. - for example, a function setDate(newDate) that sets the computer's current date to newDate has property 2. (the return value can be newDate or nothing), but it still violates 1. (it sets the current date).

      – sleske
      Mar 5 at 8:08








    • 17





      If prompt("you choose") does not have side effects, we should take a step back and clarify the meaning of side effects.

      – Holger
      Mar 5 at 8:57






    • 1





      @Magnus Yes, exactly that's what effect means. I'll try to clarify in my answer as well, I didn't expect such large attention and want to make answer worthy of dozens of votes :-)

      – Bergi
      Mar 5 at 13:09






    • 2





      Well for all you know Math.random() returns a thermal diode. It's not actually specified to use a bad RNG.

      – Joshua
      Mar 5 at 22:39
















    112














    Here are a few counterexamples that do not change the outer scope but are still considered impure:




    • function a() { return Date.now(); }

    • function b() { return window.globalMutableVar; }

    • function c() { return document.getElementById("myInput").value; }


    • function d() { return Math.random(); } (which admittedly does change the PRNG, but is not considered observable)


    Accessing non-constant non-local variables is enough to be able to violate the second condition.



    I always think of the two conditions for purity as complementary:




    • the result evaluation must not have effects on side state

    • the evaluation result must not be affected by side state


    The term side effect only refers to the first, the function modifying the non-local state. However, sometimes read operations are considered as side effects as well: when they are operations and involve writing as well, even if their primary purpose is to access a value. Examples for that are generating a pseudo-random number that modifies the generator's internal state, reading from an input stream that advances the read position, or reading from an external sensor that involves a "take measurement" command.






    share|improve this answer





















    • 1





      Thanks Bergi. For some reason I thought side effects included reading variables outside of local scope, but I guess it is only a side effect if it writes such external variables.

      – Magnus
      Mar 5 at 6:40











    • Note that the two conditions are actually logically independent: This answer shows that 1. does not imply 2., but there are also many counterexamples that 2. does not imply 1. - for example, a function setDate(newDate) that sets the computer's current date to newDate has property 2. (the return value can be newDate or nothing), but it still violates 1. (it sets the current date).

      – sleske
      Mar 5 at 8:08








    • 17





      If prompt("you choose") does not have side effects, we should take a step back and clarify the meaning of side effects.

      – Holger
      Mar 5 at 8:57






    • 1





      @Magnus Yes, exactly that's what effect means. I'll try to clarify in my answer as well, I didn't expect such large attention and want to make answer worthy of dozens of votes :-)

      – Bergi
      Mar 5 at 13:09






    • 2





      Well for all you know Math.random() returns a thermal diode. It's not actually specified to use a bad RNG.

      – Joshua
      Mar 5 at 22:39














    112












    112








    112







    Here are a few counterexamples that do not change the outer scope but are still considered impure:




    • function a() { return Date.now(); }

    • function b() { return window.globalMutableVar; }

    • function c() { return document.getElementById("myInput").value; }


    • function d() { return Math.random(); } (which admittedly does change the PRNG, but is not considered observable)


    Accessing non-constant non-local variables is enough to be able to violate the second condition.



    I always think of the two conditions for purity as complementary:




    • the result evaluation must not have effects on side state

    • the evaluation result must not be affected by side state


    The term side effect only refers to the first, the function modifying the non-local state. However, sometimes read operations are considered as side effects as well: when they are operations and involve writing as well, even if their primary purpose is to access a value. Examples for that are generating a pseudo-random number that modifies the generator's internal state, reading from an input stream that advances the read position, or reading from an external sensor that involves a "take measurement" command.






    share|improve this answer















    Here are a few counterexamples that do not change the outer scope but are still considered impure:




    • function a() { return Date.now(); }

    • function b() { return window.globalMutableVar; }

    • function c() { return document.getElementById("myInput").value; }


    • function d() { return Math.random(); } (which admittedly does change the PRNG, but is not considered observable)


    Accessing non-constant non-local variables is enough to be able to violate the second condition.



    I always think of the two conditions for purity as complementary:




    • the result evaluation must not have effects on side state

    • the evaluation result must not be affected by side state


    The term side effect only refers to the first, the function modifying the non-local state. However, sometimes read operations are considered as side effects as well: when they are operations and involve writing as well, even if their primary purpose is to access a value. Examples for that are generating a pseudo-random number that modifies the generator's internal state, reading from an input stream that advances the read position, or reading from an external sensor that involves a "take measurement" command.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Mar 5 at 13:34

























    answered Mar 4 at 22:10









    BergiBergi

    381k64585919




    381k64585919








    • 1





      Thanks Bergi. For some reason I thought side effects included reading variables outside of local scope, but I guess it is only a side effect if it writes such external variables.

      – Magnus
      Mar 5 at 6:40











    • Note that the two conditions are actually logically independent: This answer shows that 1. does not imply 2., but there are also many counterexamples that 2. does not imply 1. - for example, a function setDate(newDate) that sets the computer's current date to newDate has property 2. (the return value can be newDate or nothing), but it still violates 1. (it sets the current date).

      – sleske
      Mar 5 at 8:08








    • 17





      If prompt("you choose") does not have side effects, we should take a step back and clarify the meaning of side effects.

      – Holger
      Mar 5 at 8:57






    • 1





      @Magnus Yes, exactly that's what effect means. I'll try to clarify in my answer as well, I didn't expect such large attention and want to make answer worthy of dozens of votes :-)

      – Bergi
      Mar 5 at 13:09






    • 2





      Well for all you know Math.random() returns a thermal diode. It's not actually specified to use a bad RNG.

      – Joshua
      Mar 5 at 22:39














    • 1





      Thanks Bergi. For some reason I thought side effects included reading variables outside of local scope, but I guess it is only a side effect if it writes such external variables.

      – Magnus
      Mar 5 at 6:40











    • Note that the two conditions are actually logically independent: This answer shows that 1. does not imply 2., but there are also many counterexamples that 2. does not imply 1. - for example, a function setDate(newDate) that sets the computer's current date to newDate has property 2. (the return value can be newDate or nothing), but it still violates 1. (it sets the current date).

      – sleske
      Mar 5 at 8:08








    • 17





      If prompt("you choose") does not have side effects, we should take a step back and clarify the meaning of side effects.

      – Holger
      Mar 5 at 8:57






    • 1





      @Magnus Yes, exactly that's what effect means. I'll try to clarify in my answer as well, I didn't expect such large attention and want to make answer worthy of dozens of votes :-)

      – Bergi
      Mar 5 at 13:09






    • 2





      Well for all you know Math.random() returns a thermal diode. It's not actually specified to use a bad RNG.

      – Joshua
      Mar 5 at 22:39








    1




    1





    Thanks Bergi. For some reason I thought side effects included reading variables outside of local scope, but I guess it is only a side effect if it writes such external variables.

    – Magnus
    Mar 5 at 6:40





    Thanks Bergi. For some reason I thought side effects included reading variables outside of local scope, but I guess it is only a side effect if it writes such external variables.

    – Magnus
    Mar 5 at 6:40













    Note that the two conditions are actually logically independent: This answer shows that 1. does not imply 2., but there are also many counterexamples that 2. does not imply 1. - for example, a function setDate(newDate) that sets the computer's current date to newDate has property 2. (the return value can be newDate or nothing), but it still violates 1. (it sets the current date).

    – sleske
    Mar 5 at 8:08







    Note that the two conditions are actually logically independent: This answer shows that 1. does not imply 2., but there are also many counterexamples that 2. does not imply 1. - for example, a function setDate(newDate) that sets the computer's current date to newDate has property 2. (the return value can be newDate or nothing), but it still violates 1. (it sets the current date).

    – sleske
    Mar 5 at 8:08






    17




    17





    If prompt("you choose") does not have side effects, we should take a step back and clarify the meaning of side effects.

    – Holger
    Mar 5 at 8:57





    If prompt("you choose") does not have side effects, we should take a step back and clarify the meaning of side effects.

    – Holger
    Mar 5 at 8:57




    1




    1





    @Magnus Yes, exactly that's what effect means. I'll try to clarify in my answer as well, I didn't expect such large attention and want to make answer worthy of dozens of votes :-)

    – Bergi
    Mar 5 at 13:09





    @Magnus Yes, exactly that's what effect means. I'll try to clarify in my answer as well, I didn't expect such large attention and want to make answer worthy of dozens of votes :-)

    – Bergi
    Mar 5 at 13:09




    2




    2





    Well for all you know Math.random() returns a thermal diode. It's not actually specified to use a bad RNG.

    – Joshua
    Mar 5 at 22:39





    Well for all you know Math.random() returns a thermal diode. It's not actually specified to use a bad RNG.

    – Joshua
    Mar 5 at 22:39













    28














    The "normal" way of phrasing what a pure function is, is in terms of referential transparency. A function is pure if it is referentially transparent.



    Referential Transparency, roughly, means that you can replace the call to the function with its return value or vice versa at any point in the program, without changing the meaning of the program.



    So, for example, if C's printf were referentially transparent, these two programs should have the same meaning:



    printf("Hello");


    and



    5;


    and all of the following programs should have the same meaning:



    5 + 5;

    printf("Hello") + 5;

    printf("Hello") + printf("Hello");


    Because printf returns the number of characters written, in this case 5.



    It gets even more obvious with void functions. If I have a function void foo, then



    foo(bar, baz, quux);


    should be the same as



    ;


    I.e. since foo returns nothing, I should be able to replace it with nothing without changing the meaning of the program.



    It is clear, then, that neither printf nor foo are referentially transparent, and thus neither of them are pure. In fact, a void function can never be referentially transparent, unless it is a no-op.



    I find this definition much easier to handle as the one you gave. It also allows you to apply it at any granularity you want: you can apply it to individual expressions, to functions, to entire programs. It allows you, for example, to talk about a function like this:



    func fib(n):
    return memo[n] if memo.has_key?(n)
    return 1 if n <= 1
    return memo[n] = fib(n-1) + fib(n-2)


    We can analyze the expressions that make up the function and easily conclude that they are not referentially transparent and thus not pure, since they use a mutable data structure, namely the memo array. However, we can also look at the function and can see that it is referentially transparent and thus pure. This is sometimes called external purity, i.e. a function that appears pure to the outside world, but is implemented impure internally.



    Such functions are still useful, because while impurity infects everything around it, the external pure interface builds a kind of "purity barrier", where the impurity only infects the three lines of the function, but does not leak out into the rest of the program. These three lines are much easier to analyze for correctness than the entire program.






    share|improve this answer





















    • 2





      That impurity affects the whole program once you have concurrency.

      – R..
      Mar 5 at 16:27











    • @R.. Can you think of a way that concurrency could make the described Fibonacci function externally impure? I can't. Writing to memo[n] is idempotent, and failing to read from it merely wastes CPU cycles.

      – Brilliand
      Mar 5 at 22:12











    • I agree with both of you. Impurity can lead to concurrency problems, but it doesn't in this specific case.

      – Jörg W Mittag
      Mar 5 at 22:17











    • @R.. It's not hard to imagine a concurrency-aware version.

      – immibis
      Mar 5 at 23:48






    • 1





      @Brilliand For example, memo[n] = ... may first create a dictionary entry, and then store the value into it. This leaves a window during which another thread could see an uninitialized entry.

      – immibis
      Mar 5 at 23:49
















    28














    The "normal" way of phrasing what a pure function is, is in terms of referential transparency. A function is pure if it is referentially transparent.



    Referential Transparency, roughly, means that you can replace the call to the function with its return value or vice versa at any point in the program, without changing the meaning of the program.



    So, for example, if C's printf were referentially transparent, these two programs should have the same meaning:



    printf("Hello");


    and



    5;


    and all of the following programs should have the same meaning:



    5 + 5;

    printf("Hello") + 5;

    printf("Hello") + printf("Hello");


    Because printf returns the number of characters written, in this case 5.



    It gets even more obvious with void functions. If I have a function void foo, then



    foo(bar, baz, quux);


    should be the same as



    ;


    I.e. since foo returns nothing, I should be able to replace it with nothing without changing the meaning of the program.



    It is clear, then, that neither printf nor foo are referentially transparent, and thus neither of them are pure. In fact, a void function can never be referentially transparent, unless it is a no-op.



    I find this definition much easier to handle as the one you gave. It also allows you to apply it at any granularity you want: you can apply it to individual expressions, to functions, to entire programs. It allows you, for example, to talk about a function like this:



    func fib(n):
    return memo[n] if memo.has_key?(n)
    return 1 if n <= 1
    return memo[n] = fib(n-1) + fib(n-2)


    We can analyze the expressions that make up the function and easily conclude that they are not referentially transparent and thus not pure, since they use a mutable data structure, namely the memo array. However, we can also look at the function and can see that it is referentially transparent and thus pure. This is sometimes called external purity, i.e. a function that appears pure to the outside world, but is implemented impure internally.



    Such functions are still useful, because while impurity infects everything around it, the external pure interface builds a kind of "purity barrier", where the impurity only infects the three lines of the function, but does not leak out into the rest of the program. These three lines are much easier to analyze for correctness than the entire program.






    share|improve this answer





















    • 2





      That impurity affects the whole program once you have concurrency.

      – R..
      Mar 5 at 16:27











    • @R.. Can you think of a way that concurrency could make the described Fibonacci function externally impure? I can't. Writing to memo[n] is idempotent, and failing to read from it merely wastes CPU cycles.

      – Brilliand
      Mar 5 at 22:12











    • I agree with both of you. Impurity can lead to concurrency problems, but it doesn't in this specific case.

      – Jörg W Mittag
      Mar 5 at 22:17











    • @R.. It's not hard to imagine a concurrency-aware version.

      – immibis
      Mar 5 at 23:48






    • 1





      @Brilliand For example, memo[n] = ... may first create a dictionary entry, and then store the value into it. This leaves a window during which another thread could see an uninitialized entry.

      – immibis
      Mar 5 at 23:49














    28












    28








    28







    The "normal" way of phrasing what a pure function is, is in terms of referential transparency. A function is pure if it is referentially transparent.



    Referential Transparency, roughly, means that you can replace the call to the function with its return value or vice versa at any point in the program, without changing the meaning of the program.



    So, for example, if C's printf were referentially transparent, these two programs should have the same meaning:



    printf("Hello");


    and



    5;


    and all of the following programs should have the same meaning:



    5 + 5;

    printf("Hello") + 5;

    printf("Hello") + printf("Hello");


    Because printf returns the number of characters written, in this case 5.



    It gets even more obvious with void functions. If I have a function void foo, then



    foo(bar, baz, quux);


    should be the same as



    ;


    I.e. since foo returns nothing, I should be able to replace it with nothing without changing the meaning of the program.



    It is clear, then, that neither printf nor foo are referentially transparent, and thus neither of them are pure. In fact, a void function can never be referentially transparent, unless it is a no-op.



    I find this definition much easier to handle as the one you gave. It also allows you to apply it at any granularity you want: you can apply it to individual expressions, to functions, to entire programs. It allows you, for example, to talk about a function like this:



    func fib(n):
    return memo[n] if memo.has_key?(n)
    return 1 if n <= 1
    return memo[n] = fib(n-1) + fib(n-2)


    We can analyze the expressions that make up the function and easily conclude that they are not referentially transparent and thus not pure, since they use a mutable data structure, namely the memo array. However, we can also look at the function and can see that it is referentially transparent and thus pure. This is sometimes called external purity, i.e. a function that appears pure to the outside world, but is implemented impure internally.



    Such functions are still useful, because while impurity infects everything around it, the external pure interface builds a kind of "purity barrier", where the impurity only infects the three lines of the function, but does not leak out into the rest of the program. These three lines are much easier to analyze for correctness than the entire program.






    share|improve this answer















    The "normal" way of phrasing what a pure function is, is in terms of referential transparency. A function is pure if it is referentially transparent.



    Referential Transparency, roughly, means that you can replace the call to the function with its return value or vice versa at any point in the program, without changing the meaning of the program.



    So, for example, if C's printf were referentially transparent, these two programs should have the same meaning:



    printf("Hello");


    and



    5;


    and all of the following programs should have the same meaning:



    5 + 5;

    printf("Hello") + 5;

    printf("Hello") + printf("Hello");


    Because printf returns the number of characters written, in this case 5.



    It gets even more obvious with void functions. If I have a function void foo, then



    foo(bar, baz, quux);


    should be the same as



    ;


    I.e. since foo returns nothing, I should be able to replace it with nothing without changing the meaning of the program.



    It is clear, then, that neither printf nor foo are referentially transparent, and thus neither of them are pure. In fact, a void function can never be referentially transparent, unless it is a no-op.



    I find this definition much easier to handle as the one you gave. It also allows you to apply it at any granularity you want: you can apply it to individual expressions, to functions, to entire programs. It allows you, for example, to talk about a function like this:



    func fib(n):
    return memo[n] if memo.has_key?(n)
    return 1 if n <= 1
    return memo[n] = fib(n-1) + fib(n-2)


    We can analyze the expressions that make up the function and easily conclude that they are not referentially transparent and thus not pure, since they use a mutable data structure, namely the memo array. However, we can also look at the function and can see that it is referentially transparent and thus pure. This is sometimes called external purity, i.e. a function that appears pure to the outside world, but is implemented impure internally.



    Such functions are still useful, because while impurity infects everything around it, the external pure interface builds a kind of "purity barrier", where the impurity only infects the three lines of the function, but does not leak out into the rest of the program. These three lines are much easier to analyze for correctness than the entire program.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Mar 9 at 13:58

























    answered Mar 5 at 6:32









    Jörg W MittagJörg W Mittag

    294k63359557




    294k63359557








    • 2





      That impurity affects the whole program once you have concurrency.

      – R..
      Mar 5 at 16:27











    • @R.. Can you think of a way that concurrency could make the described Fibonacci function externally impure? I can't. Writing to memo[n] is idempotent, and failing to read from it merely wastes CPU cycles.

      – Brilliand
      Mar 5 at 22:12











    • I agree with both of you. Impurity can lead to concurrency problems, but it doesn't in this specific case.

      – Jörg W Mittag
      Mar 5 at 22:17











    • @R.. It's not hard to imagine a concurrency-aware version.

      – immibis
      Mar 5 at 23:48






    • 1





      @Brilliand For example, memo[n] = ... may first create a dictionary entry, and then store the value into it. This leaves a window during which another thread could see an uninitialized entry.

      – immibis
      Mar 5 at 23:49














    • 2





      That impurity affects the whole program once you have concurrency.

      – R..
      Mar 5 at 16:27











    • @R.. Can you think of a way that concurrency could make the described Fibonacci function externally impure? I can't. Writing to memo[n] is idempotent, and failing to read from it merely wastes CPU cycles.

      – Brilliand
      Mar 5 at 22:12











    • I agree with both of you. Impurity can lead to concurrency problems, but it doesn't in this specific case.

      – Jörg W Mittag
      Mar 5 at 22:17











    • @R.. It's not hard to imagine a concurrency-aware version.

      – immibis
      Mar 5 at 23:48






    • 1





      @Brilliand For example, memo[n] = ... may first create a dictionary entry, and then store the value into it. This leaves a window during which another thread could see an uninitialized entry.

      – immibis
      Mar 5 at 23:49








    2




    2





    That impurity affects the whole program once you have concurrency.

    – R..
    Mar 5 at 16:27





    That impurity affects the whole program once you have concurrency.

    – R..
    Mar 5 at 16:27













    @R.. Can you think of a way that concurrency could make the described Fibonacci function externally impure? I can't. Writing to memo[n] is idempotent, and failing to read from it merely wastes CPU cycles.

    – Brilliand
    Mar 5 at 22:12





    @R.. Can you think of a way that concurrency could make the described Fibonacci function externally impure? I can't. Writing to memo[n] is idempotent, and failing to read from it merely wastes CPU cycles.

    – Brilliand
    Mar 5 at 22:12













    I agree with both of you. Impurity can lead to concurrency problems, but it doesn't in this specific case.

    – Jörg W Mittag
    Mar 5 at 22:17





    I agree with both of you. Impurity can lead to concurrency problems, but it doesn't in this specific case.

    – Jörg W Mittag
    Mar 5 at 22:17













    @R.. It's not hard to imagine a concurrency-aware version.

    – immibis
    Mar 5 at 23:48





    @R.. It's not hard to imagine a concurrency-aware version.

    – immibis
    Mar 5 at 23:48




    1




    1





    @Brilliand For example, memo[n] = ... may first create a dictionary entry, and then store the value into it. This leaves a window during which another thread could see an uninitialized entry.

    – immibis
    Mar 5 at 23:49





    @Brilliand For example, memo[n] = ... may first create a dictionary entry, and then store the value into it. This leaves a window during which another thread could see an uninitialized entry.

    – immibis
    Mar 5 at 23:49











    12














    It seems to me that the second condition you have described is a weaker constraint than the first.



    Let me give you an example, suppose you have a function to add one that also logs to the console:



    function addOneAndLog(x) {
    console.log(x);
    return x + 1;
    }


    The second condition you supplied is satisfied: this function always returns the same output when given the same input. It is, however, not a pure function because it includes the side effect of logging to the console.



    A pure function is, strictly speaking, a function that satisfies the property of referential transparency. That is the property that we can replace a function application with the value it produces without changing the behaviour of the program.



    Suppose we have a function that simply adds:



    function addOne(x) {
    return x + 1;
    }


    We can replace addOne(5) with 6 anywhere in our program and nothing will change.



    By contrast, we cannot replace addOneAndLog(x) with the value 6 anywhere in our program without changing behaviour because the first expression results in something being written to the console whereas the second one does not.



    We consider any of this extra behaviour that addOneAndLog(x) performs besides returning output as a side-effect.






    share|improve this answer
























    • "It seems to me that the second condition you have described is a weaker constraint than the first." No, the two conditions are logically independent.

      – sleske
      Mar 5 at 8:03











    • @sleske you are mistaken. I have provided clear definitions for the terms pure and side-effect. Within these constraints, there is nothing that a function with no side effects besides return the same output for a given input. I have however provided examples where the second condition can be satisfied without the first. The fundamnetal concept to understand the notion of purity is referential transparency.

      – TheInnerLight
      Mar 5 at 9:11











    • Small typo: There is nothing that a function with no side effects can do besides returning the same output for a given input.

      – TheInnerLight
      Mar 5 at 9:18











    • What about something like returning the current time? That does not have side effects, but it does return a different output for the same input. Or more generally, any function where the result depends not only on the input parameters, but also on a (changeable) global variable.

      – sleske
      Mar 5 at 9:24








    • 2





      It seems you are using a different definition of "side effect" than what is commonly used. A side effect is commonly defined as "an observable effect besides returning a value" or an "observable change in state" - see e.g. Wikipedia , this post on softwareengineering.SE. You are totally right that Date.now() is not pure/referentially transparent, but not because it has side-effects, but because its result depends on more than just its input.

      – sleske
      Mar 5 at 10:05
















    12














    It seems to me that the second condition you have described is a weaker constraint than the first.



    Let me give you an example, suppose you have a function to add one that also logs to the console:



    function addOneAndLog(x) {
    console.log(x);
    return x + 1;
    }


    The second condition you supplied is satisfied: this function always returns the same output when given the same input. It is, however, not a pure function because it includes the side effect of logging to the console.



    A pure function is, strictly speaking, a function that satisfies the property of referential transparency. That is the property that we can replace a function application with the value it produces without changing the behaviour of the program.



    Suppose we have a function that simply adds:



    function addOne(x) {
    return x + 1;
    }


    We can replace addOne(5) with 6 anywhere in our program and nothing will change.



    By contrast, we cannot replace addOneAndLog(x) with the value 6 anywhere in our program without changing behaviour because the first expression results in something being written to the console whereas the second one does not.



    We consider any of this extra behaviour that addOneAndLog(x) performs besides returning output as a side-effect.






    share|improve this answer
























    • "It seems to me that the second condition you have described is a weaker constraint than the first." No, the two conditions are logically independent.

      – sleske
      Mar 5 at 8:03











    • @sleske you are mistaken. I have provided clear definitions for the terms pure and side-effect. Within these constraints, there is nothing that a function with no side effects besides return the same output for a given input. I have however provided examples where the second condition can be satisfied without the first. The fundamnetal concept to understand the notion of purity is referential transparency.

      – TheInnerLight
      Mar 5 at 9:11











    • Small typo: There is nothing that a function with no side effects can do besides returning the same output for a given input.

      – TheInnerLight
      Mar 5 at 9:18











    • What about something like returning the current time? That does not have side effects, but it does return a different output for the same input. Or more generally, any function where the result depends not only on the input parameters, but also on a (changeable) global variable.

      – sleske
      Mar 5 at 9:24








    • 2





      It seems you are using a different definition of "side effect" than what is commonly used. A side effect is commonly defined as "an observable effect besides returning a value" or an "observable change in state" - see e.g. Wikipedia , this post on softwareengineering.SE. You are totally right that Date.now() is not pure/referentially transparent, but not because it has side-effects, but because its result depends on more than just its input.

      – sleske
      Mar 5 at 10:05














    12












    12








    12







    It seems to me that the second condition you have described is a weaker constraint than the first.



    Let me give you an example, suppose you have a function to add one that also logs to the console:



    function addOneAndLog(x) {
    console.log(x);
    return x + 1;
    }


    The second condition you supplied is satisfied: this function always returns the same output when given the same input. It is, however, not a pure function because it includes the side effect of logging to the console.



    A pure function is, strictly speaking, a function that satisfies the property of referential transparency. That is the property that we can replace a function application with the value it produces without changing the behaviour of the program.



    Suppose we have a function that simply adds:



    function addOne(x) {
    return x + 1;
    }


    We can replace addOne(5) with 6 anywhere in our program and nothing will change.



    By contrast, we cannot replace addOneAndLog(x) with the value 6 anywhere in our program without changing behaviour because the first expression results in something being written to the console whereas the second one does not.



    We consider any of this extra behaviour that addOneAndLog(x) performs besides returning output as a side-effect.






    share|improve this answer













    It seems to me that the second condition you have described is a weaker constraint than the first.



    Let me give you an example, suppose you have a function to add one that also logs to the console:



    function addOneAndLog(x) {
    console.log(x);
    return x + 1;
    }


    The second condition you supplied is satisfied: this function always returns the same output when given the same input. It is, however, not a pure function because it includes the side effect of logging to the console.



    A pure function is, strictly speaking, a function that satisfies the property of referential transparency. That is the property that we can replace a function application with the value it produces without changing the behaviour of the program.



    Suppose we have a function that simply adds:



    function addOne(x) {
    return x + 1;
    }


    We can replace addOne(5) with 6 anywhere in our program and nothing will change.



    By contrast, we cannot replace addOneAndLog(x) with the value 6 anywhere in our program without changing behaviour because the first expression results in something being written to the console whereas the second one does not.



    We consider any of this extra behaviour that addOneAndLog(x) performs besides returning output as a side-effect.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Mar 4 at 23:03









    TheInnerLightTheInnerLight

    10.5k11944




    10.5k11944













    • "It seems to me that the second condition you have described is a weaker constraint than the first." No, the two conditions are logically independent.

      – sleske
      Mar 5 at 8:03











    • @sleske you are mistaken. I have provided clear definitions for the terms pure and side-effect. Within these constraints, there is nothing that a function with no side effects besides return the same output for a given input. I have however provided examples where the second condition can be satisfied without the first. The fundamnetal concept to understand the notion of purity is referential transparency.

      – TheInnerLight
      Mar 5 at 9:11











    • Small typo: There is nothing that a function with no side effects can do besides returning the same output for a given input.

      – TheInnerLight
      Mar 5 at 9:18











    • What about something like returning the current time? That does not have side effects, but it does return a different output for the same input. Or more generally, any function where the result depends not only on the input parameters, but also on a (changeable) global variable.

      – sleske
      Mar 5 at 9:24








    • 2





      It seems you are using a different definition of "side effect" than what is commonly used. A side effect is commonly defined as "an observable effect besides returning a value" or an "observable change in state" - see e.g. Wikipedia , this post on softwareengineering.SE. You are totally right that Date.now() is not pure/referentially transparent, but not because it has side-effects, but because its result depends on more than just its input.

      – sleske
      Mar 5 at 10:05



















    • "It seems to me that the second condition you have described is a weaker constraint than the first." No, the two conditions are logically independent.

      – sleske
      Mar 5 at 8:03











    • @sleske you are mistaken. I have provided clear definitions for the terms pure and side-effect. Within these constraints, there is nothing that a function with no side effects besides return the same output for a given input. I have however provided examples where the second condition can be satisfied without the first. The fundamnetal concept to understand the notion of purity is referential transparency.

      – TheInnerLight
      Mar 5 at 9:11











    • Small typo: There is nothing that a function with no side effects can do besides returning the same output for a given input.

      – TheInnerLight
      Mar 5 at 9:18











    • What about something like returning the current time? That does not have side effects, but it does return a different output for the same input. Or more generally, any function where the result depends not only on the input parameters, but also on a (changeable) global variable.

      – sleske
      Mar 5 at 9:24








    • 2





      It seems you are using a different definition of "side effect" than what is commonly used. A side effect is commonly defined as "an observable effect besides returning a value" or an "observable change in state" - see e.g. Wikipedia , this post on softwareengineering.SE. You are totally right that Date.now() is not pure/referentially transparent, but not because it has side-effects, but because its result depends on more than just its input.

      – sleske
      Mar 5 at 10:05

















    "It seems to me that the second condition you have described is a weaker constraint than the first." No, the two conditions are logically independent.

    – sleske
    Mar 5 at 8:03





    "It seems to me that the second condition you have described is a weaker constraint than the first." No, the two conditions are logically independent.

    – sleske
    Mar 5 at 8:03













    @sleske you are mistaken. I have provided clear definitions for the terms pure and side-effect. Within these constraints, there is nothing that a function with no side effects besides return the same output for a given input. I have however provided examples where the second condition can be satisfied without the first. The fundamnetal concept to understand the notion of purity is referential transparency.

    – TheInnerLight
    Mar 5 at 9:11





    @sleske you are mistaken. I have provided clear definitions for the terms pure and side-effect. Within these constraints, there is nothing that a function with no side effects besides return the same output for a given input. I have however provided examples where the second condition can be satisfied without the first. The fundamnetal concept to understand the notion of purity is referential transparency.

    – TheInnerLight
    Mar 5 at 9:11













    Small typo: There is nothing that a function with no side effects can do besides returning the same output for a given input.

    – TheInnerLight
    Mar 5 at 9:18





    Small typo: There is nothing that a function with no side effects can do besides returning the same output for a given input.

    – TheInnerLight
    Mar 5 at 9:18













    What about something like returning the current time? That does not have side effects, but it does return a different output for the same input. Or more generally, any function where the result depends not only on the input parameters, but also on a (changeable) global variable.

    – sleske
    Mar 5 at 9:24







    What about something like returning the current time? That does not have side effects, but it does return a different output for the same input. Or more generally, any function where the result depends not only on the input parameters, but also on a (changeable) global variable.

    – sleske
    Mar 5 at 9:24






    2




    2





    It seems you are using a different definition of "side effect" than what is commonly used. A side effect is commonly defined as "an observable effect besides returning a value" or an "observable change in state" - see e.g. Wikipedia , this post on softwareengineering.SE. You are totally right that Date.now() is not pure/referentially transparent, but not because it has side-effects, but because its result depends on more than just its input.

    – sleske
    Mar 5 at 10:05





    It seems you are using a different definition of "side effect" than what is commonly used. A side effect is commonly defined as "an observable effect besides returning a value" or an "observable change in state" - see e.g. Wikipedia , this post on softwareengineering.SE. You are totally right that Date.now() is not pure/referentially transparent, but not because it has side-effects, but because its result depends on more than just its input.

    – sleske
    Mar 5 at 10:05











    7














    There could be a source of randomness from outside the system. Suppose that part of your calculation includes the room temperature. Then executing the function will yield different results each time depending on the random external element of room temperature. The state is not changed by executing the program.



    All I can think of, anyway.






    share|improve this answer





















    • 3





      According to me, these "randomness from outside the system" are a form of side effect. Functions with these behaviors are not "pures".

      – Joseph M. Dion
      Mar 5 at 1:06
















    7














    There could be a source of randomness from outside the system. Suppose that part of your calculation includes the room temperature. Then executing the function will yield different results each time depending on the random external element of room temperature. The state is not changed by executing the program.



    All I can think of, anyway.






    share|improve this answer





















    • 3





      According to me, these "randomness from outside the system" are a form of side effect. Functions with these behaviors are not "pures".

      – Joseph M. Dion
      Mar 5 at 1:06














    7












    7








    7







    There could be a source of randomness from outside the system. Suppose that part of your calculation includes the room temperature. Then executing the function will yield different results each time depending on the random external element of room temperature. The state is not changed by executing the program.



    All I can think of, anyway.






    share|improve this answer















    There could be a source of randomness from outside the system. Suppose that part of your calculation includes the room temperature. Then executing the function will yield different results each time depending on the random external element of room temperature. The state is not changed by executing the program.



    All I can think of, anyway.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Mar 21 at 12:28









    hba23

    31




    31










    answered Mar 4 at 22:11









    user3340459user3340459

    13227




    13227








    • 3





      According to me, these "randomness from outside the system" are a form of side effect. Functions with these behaviors are not "pures".

      – Joseph M. Dion
      Mar 5 at 1:06














    • 3





      According to me, these "randomness from outside the system" are a form of side effect. Functions with these behaviors are not "pures".

      – Joseph M. Dion
      Mar 5 at 1:06








    3




    3





    According to me, these "randomness from outside the system" are a form of side effect. Functions with these behaviors are not "pures".

    – Joseph M. Dion
    Mar 5 at 1:06





    According to me, these "randomness from outside the system" are a form of side effect. Functions with these behaviors are not "pures".

    – Joseph M. Dion
    Mar 5 at 1:06











    3














    Problem with FP definitions is that they are very artificial. Each evaluation/calculation has side-effects on the evaluator. It's theoretically true. A deny of this shows only that FP apologists ignore philosophy and logic: an "evaluation" means changing of the state of some intelligent environment (machine, brain, etc). This is the nature of the evaluation process. No changes - no "calculi". The effect can be very visible: heating the CPU or its failure, shutting down the motherboard in case of overheating, and so on.



    When you talk about referential transparency, you should understand that information about such transparency is available for human as a creator of the whole system and holder of semantical information and may be not available for the compiler. For example, a function can read some external resource and it will have IO monad in its signature but it will return the same value all the time (for example, the result of current_year > 0). The compiler does not know that function will return always the same result, so the function is impure but has referentially transparent property and can be substituted with True constant.



    So, to avoid such inaccuracy, we should distinguish mathematical functions and "functions" in programming languages. Functions in Haskell are always impure and definition of purity related to them is always very conditionally: they are running on real hardware with real side-effects and physical properties, which is wrong for mathematical functions. This means that the example with "printf" function is totally incorrect.



    But not all mathematical functions are pure too: each function which has t (time) as a parameter may be impure: t holds all effects and stochastic nature of the function: in common case you have input signal and have not idea about actual values, it can be even a noise.






    share|improve this answer






























      3














      Problem with FP definitions is that they are very artificial. Each evaluation/calculation has side-effects on the evaluator. It's theoretically true. A deny of this shows only that FP apologists ignore philosophy and logic: an "evaluation" means changing of the state of some intelligent environment (machine, brain, etc). This is the nature of the evaluation process. No changes - no "calculi". The effect can be very visible: heating the CPU or its failure, shutting down the motherboard in case of overheating, and so on.



      When you talk about referential transparency, you should understand that information about such transparency is available for human as a creator of the whole system and holder of semantical information and may be not available for the compiler. For example, a function can read some external resource and it will have IO monad in its signature but it will return the same value all the time (for example, the result of current_year > 0). The compiler does not know that function will return always the same result, so the function is impure but has referentially transparent property and can be substituted with True constant.



      So, to avoid such inaccuracy, we should distinguish mathematical functions and "functions" in programming languages. Functions in Haskell are always impure and definition of purity related to them is always very conditionally: they are running on real hardware with real side-effects and physical properties, which is wrong for mathematical functions. This means that the example with "printf" function is totally incorrect.



      But not all mathematical functions are pure too: each function which has t (time) as a parameter may be impure: t holds all effects and stochastic nature of the function: in common case you have input signal and have not idea about actual values, it can be even a noise.






      share|improve this answer




























        3












        3








        3







        Problem with FP definitions is that they are very artificial. Each evaluation/calculation has side-effects on the evaluator. It's theoretically true. A deny of this shows only that FP apologists ignore philosophy and logic: an "evaluation" means changing of the state of some intelligent environment (machine, brain, etc). This is the nature of the evaluation process. No changes - no "calculi". The effect can be very visible: heating the CPU or its failure, shutting down the motherboard in case of overheating, and so on.



        When you talk about referential transparency, you should understand that information about such transparency is available for human as a creator of the whole system and holder of semantical information and may be not available for the compiler. For example, a function can read some external resource and it will have IO monad in its signature but it will return the same value all the time (for example, the result of current_year > 0). The compiler does not know that function will return always the same result, so the function is impure but has referentially transparent property and can be substituted with True constant.



        So, to avoid such inaccuracy, we should distinguish mathematical functions and "functions" in programming languages. Functions in Haskell are always impure and definition of purity related to them is always very conditionally: they are running on real hardware with real side-effects and physical properties, which is wrong for mathematical functions. This means that the example with "printf" function is totally incorrect.



        But not all mathematical functions are pure too: each function which has t (time) as a parameter may be impure: t holds all effects and stochastic nature of the function: in common case you have input signal and have not idea about actual values, it can be even a noise.






        share|improve this answer















        Problem with FP definitions is that they are very artificial. Each evaluation/calculation has side-effects on the evaluator. It's theoretically true. A deny of this shows only that FP apologists ignore philosophy and logic: an "evaluation" means changing of the state of some intelligent environment (machine, brain, etc). This is the nature of the evaluation process. No changes - no "calculi". The effect can be very visible: heating the CPU or its failure, shutting down the motherboard in case of overheating, and so on.



        When you talk about referential transparency, you should understand that information about such transparency is available for human as a creator of the whole system and holder of semantical information and may be not available for the compiler. For example, a function can read some external resource and it will have IO monad in its signature but it will return the same value all the time (for example, the result of current_year > 0). The compiler does not know that function will return always the same result, so the function is impure but has referentially transparent property and can be substituted with True constant.



        So, to avoid such inaccuracy, we should distinguish mathematical functions and "functions" in programming languages. Functions in Haskell are always impure and definition of purity related to them is always very conditionally: they are running on real hardware with real side-effects and physical properties, which is wrong for mathematical functions. This means that the example with "printf" function is totally incorrect.



        But not all mathematical functions are pure too: each function which has t (time) as a parameter may be impure: t holds all effects and stochastic nature of the function: in common case you have input signal and have not idea about actual values, it can be even a noise.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 9 at 12:22









        eFarzad

        604922




        604922










        answered Mar 8 at 8:53









        Paul-AGPaul-AG

        537212




        537212























            2















            If the first condition is always true, are there any times the second
            condition is not true?




            Yes



            Consider simple code snippet below



            public int Sum(int a, int b) {
            Random rnd = new Random();
            return rnd.Next(1, 10);
            }


            This code will return random output for same given set of inputs - however it does not have any side effect.



            The overall effect of both the points #1 & #2 you mentioned when combined together means : At any point of time if function Sum with same i/p is replaced with its result in a program, overall meaning of program does not change. This is nothing but Referential transparency.






            share|improve this answer


























            • But in this case, the first condition is not verified: writing to the console is considered a side effect, since it changes the state of the machine itself.

              – Right leg
              Mar 5 at 8:30











            • @Rightleg thx for pointing it out. Somehow I misunderstood OP totally other way. corrected answer.

              – Rahul Agarwal
              Mar 5 at 8:41






            • 2





              Doesn't it change the state of the random generator?

              – Eric Duminil
              Mar 5 at 9:14






            • 1





              Generating a random number is itself a side effect, unless the state of the random number generator is supplied explicitly which would make the function satisfy condition 2.

              – TheInnerLight
              Mar 5 at 9:23






            • 1





              rnd doesn't escape the function, so the fact that its state changes doesn't matter to the purity of the function, but the fact that the Random constructor uses the current time as a seed value means that there are "inputs" other than a and b.

              – Sneftel
              Mar 5 at 11:14
















            2















            If the first condition is always true, are there any times the second
            condition is not true?




            Yes



            Consider simple code snippet below



            public int Sum(int a, int b) {
            Random rnd = new Random();
            return rnd.Next(1, 10);
            }


            This code will return random output for same given set of inputs - however it does not have any side effect.



            The overall effect of both the points #1 & #2 you mentioned when combined together means : At any point of time if function Sum with same i/p is replaced with its result in a program, overall meaning of program does not change. This is nothing but Referential transparency.






            share|improve this answer


























            • But in this case, the first condition is not verified: writing to the console is considered a side effect, since it changes the state of the machine itself.

              – Right leg
              Mar 5 at 8:30











            • @Rightleg thx for pointing it out. Somehow I misunderstood OP totally other way. corrected answer.

              – Rahul Agarwal
              Mar 5 at 8:41






            • 2





              Doesn't it change the state of the random generator?

              – Eric Duminil
              Mar 5 at 9:14






            • 1





              Generating a random number is itself a side effect, unless the state of the random number generator is supplied explicitly which would make the function satisfy condition 2.

              – TheInnerLight
              Mar 5 at 9:23






            • 1





              rnd doesn't escape the function, so the fact that its state changes doesn't matter to the purity of the function, but the fact that the Random constructor uses the current time as a seed value means that there are "inputs" other than a and b.

              – Sneftel
              Mar 5 at 11:14














            2












            2








            2








            If the first condition is always true, are there any times the second
            condition is not true?




            Yes



            Consider simple code snippet below



            public int Sum(int a, int b) {
            Random rnd = new Random();
            return rnd.Next(1, 10);
            }


            This code will return random output for same given set of inputs - however it does not have any side effect.



            The overall effect of both the points #1 & #2 you mentioned when combined together means : At any point of time if function Sum with same i/p is replaced with its result in a program, overall meaning of program does not change. This is nothing but Referential transparency.






            share|improve this answer
















            If the first condition is always true, are there any times the second
            condition is not true?




            Yes



            Consider simple code snippet below



            public int Sum(int a, int b) {
            Random rnd = new Random();
            return rnd.Next(1, 10);
            }


            This code will return random output for same given set of inputs - however it does not have any side effect.



            The overall effect of both the points #1 & #2 you mentioned when combined together means : At any point of time if function Sum with same i/p is replaced with its result in a program, overall meaning of program does not change. This is nothing but Referential transparency.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 22 at 15:56









            demo

            2,41444084




            2,41444084










            answered Mar 5 at 7:27









            Rahul AgarwalRahul Agarwal

            1,70931129




            1,70931129













            • But in this case, the first condition is not verified: writing to the console is considered a side effect, since it changes the state of the machine itself.

              – Right leg
              Mar 5 at 8:30











            • @Rightleg thx for pointing it out. Somehow I misunderstood OP totally other way. corrected answer.

              – Rahul Agarwal
              Mar 5 at 8:41






            • 2





              Doesn't it change the state of the random generator?

              – Eric Duminil
              Mar 5 at 9:14






            • 1





              Generating a random number is itself a side effect, unless the state of the random number generator is supplied explicitly which would make the function satisfy condition 2.

              – TheInnerLight
              Mar 5 at 9:23






            • 1





              rnd doesn't escape the function, so the fact that its state changes doesn't matter to the purity of the function, but the fact that the Random constructor uses the current time as a seed value means that there are "inputs" other than a and b.

              – Sneftel
              Mar 5 at 11:14



















            • But in this case, the first condition is not verified: writing to the console is considered a side effect, since it changes the state of the machine itself.

              – Right leg
              Mar 5 at 8:30











            • @Rightleg thx for pointing it out. Somehow I misunderstood OP totally other way. corrected answer.

              – Rahul Agarwal
              Mar 5 at 8:41






            • 2





              Doesn't it change the state of the random generator?

              – Eric Duminil
              Mar 5 at 9:14






            • 1





              Generating a random number is itself a side effect, unless the state of the random number generator is supplied explicitly which would make the function satisfy condition 2.

              – TheInnerLight
              Mar 5 at 9:23






            • 1





              rnd doesn't escape the function, so the fact that its state changes doesn't matter to the purity of the function, but the fact that the Random constructor uses the current time as a seed value means that there are "inputs" other than a and b.

              – Sneftel
              Mar 5 at 11:14

















            But in this case, the first condition is not verified: writing to the console is considered a side effect, since it changes the state of the machine itself.

            – Right leg
            Mar 5 at 8:30





            But in this case, the first condition is not verified: writing to the console is considered a side effect, since it changes the state of the machine itself.

            – Right leg
            Mar 5 at 8:30













            @Rightleg thx for pointing it out. Somehow I misunderstood OP totally other way. corrected answer.

            – Rahul Agarwal
            Mar 5 at 8:41





            @Rightleg thx for pointing it out. Somehow I misunderstood OP totally other way. corrected answer.

            – Rahul Agarwal
            Mar 5 at 8:41




            2




            2





            Doesn't it change the state of the random generator?

            – Eric Duminil
            Mar 5 at 9:14





            Doesn't it change the state of the random generator?

            – Eric Duminil
            Mar 5 at 9:14




            1




            1





            Generating a random number is itself a side effect, unless the state of the random number generator is supplied explicitly which would make the function satisfy condition 2.

            – TheInnerLight
            Mar 5 at 9:23





            Generating a random number is itself a side effect, unless the state of the random number generator is supplied explicitly which would make the function satisfy condition 2.

            – TheInnerLight
            Mar 5 at 9:23




            1




            1





            rnd doesn't escape the function, so the fact that its state changes doesn't matter to the purity of the function, but the fact that the Random constructor uses the current time as a seed value means that there are "inputs" other than a and b.

            – Sneftel
            Mar 5 at 11:14





            rnd doesn't escape the function, so the fact that its state changes doesn't matter to the purity of the function, but the fact that the Random constructor uses the current time as a seed value means that there are "inputs" other than a and b.

            – Sneftel
            Mar 5 at 11:14


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54992302%2fpure-functions-does-no-side-effects-imply-always-same-output-given-same-inp%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Index of /

            Tribalistas

            Listed building