DEV Community

Maksim Ivanov
Maksim Ivanov

Posted on

Should Pure Functions Be Self-contained

I my last video about pure functions I said that to be pure a function should be self-contained i.e it should only access values from it's own scope.

function pureFunction(){
  return 'Some string literal';
  // Doesn't perform side effects, is deterministic
  // thus we can be sure that it's pure 
}

function thisWontBePure(){
  return pureFunction();
  // Isn't pure because calls function from global scope.
  // Even though the function we are calling here is pure.
}
Enter fullscreen mode Exit fullscreen mode

So if you want a function to be pure it should only access values from it's arguments:

function nowItsPure(anotherPureFunction){
  return anotherPureFunction();
  // Isn't pure because calls function from global scope.
}
Enter fullscreen mode Exit fullscreen mode

What do you think about this? Can pure function call other pure functions from global scope and still remain pure?

Top comments (15)

Collapse
 
vonheikemen profile image
Heiker

In the first snippet i would say that thisWontBePure is pure. As far as i know pureFunction is a constant. What could possibly change the value returned by pureFunction at runtime?

Consider this:

function add(a) {
  return function inner(b) {
    return a + b;
  };
}
Enter fullscreen mode Exit fullscreen mode

I would say that inner is still a pure function because the value of a can't change once is locked in the closure.

If a function doesn't have side effects and mantains referential transparency, to me that is a pure function.

Collapse
 
geolamp profile image
George Lampadaridis • Edited

mmm you got me thinking. What if :

var c = 0;
var obj1 = {
        valueOf: function () {
            c++;
            return 1;
        }
    };
var obj2 = {
        valueOf: function () {
            c++
            return 2;
        }
    };
function add(a) {
  return function inner(b) {
    return a + b;
  };
}
console.log(add(obj1)(obj2));
console.log(c);
Collapse
 
vonheikemen profile image
Heiker • Edited

Fair question. This is javascript, right? In a dynamic language you can only write code in a functional style and hope that no one does a trick like the one you did there.

In your example inner becomes impure because valueOf is impure (it changes some state outside of its scope). So if an impure function gets executed inside of a "pure" function than it is no longer pure.

Collapse
 
xania profile image
Ibrahim ben Salah

obj1.valueOf is not referential transparent!

Collapse
 
geolamp profile image
George Lampadaridis

I messed up the code format. Used from stack overflow... Sorry for asking this here, how can I format code in a comment?

Thread Thread
 
vonheikemen profile image
Heiker • Edited

The syntax highlight can be activated with a block closed in triple backticks, and optionaly a language name. Like this:

```javascript
console.log('hello');
// some code
```

Thread Thread
 
geolamp profile image
George Lampadaridis

Thank you sir. Sorry for the irrelevant question again.

Collapse
 
xania profile image
Ibrahim ben Salah

not all side effects are the same, only observed side effects are relevant for the definition of pure function.

Collapse
 
t4rzsan profile image
Jakob Christensen

As you know a pure function has the following two requirements:

  1. It must not have any side effects, i.e. it is not allowed to change any state of the program or of external ressources.
  2. It must be deterministic, i.e. for a given set of inputs it must almost return the same output. This is also called memoizable.

That does not imply that you cannot call other functions but if the called functions change behaviour you are breaking rule #2.

Functional programming languages have immutable values (at least by default) so you cannot "override" functions or change variables. By definition an immutable variable is not really a variable but just a value.

If you are trying to do functional programming in JavaScript or C# which have references, well, then you have to enforce those rules by coding style and self-discipline. The runtime will not help you.

Collapse
 
geolamp profile image
George Lampadaridis

Well If the functions called are pure as well, then yes, I think it doesnt defeat the purpose.

Collapse
 
satansdeer profile image
Maksim Ivanov

But what if that function in global scope will be overridden by non-pure function?

Global scope can be altered from other parts of the code.

Collapse
 
geolamp profile image
George Lampadaridis

Yes then this function became not pure. So just like a var can change from a number to function, I believe a function can be rendered pure or not while it changes.

Thread Thread
 
satansdeer profile image
Maksim Ivanov • Edited

Then it looks like it's not the function that can be pure or not, but a function call.

So we can have pure function calls and impure function calls.

Thread Thread
 
geolamp profile image
George Lampadaridis

I have to agree

Thread Thread
 
satansdeer profile image
Maksim Ivanov

Would be awesome to summon some FP pro here to clarify the terminology.