Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chapter 3 example function decrementHP is not pure. #244

Closed
tkivela opened this issue Jan 29, 2016 · 4 comments
Closed

Chapter 3 example function decrementHP is not pure. #244

tkivela opened this issue Jan 29, 2016 · 4 comments

Comments

@tkivela
Copy link

tkivela commented Jan 29, 2016

Chapter 3's function decrementHP is not pure. The function has side effects if variable passed to it is not Immutable.

By definition pure function always evaluates the same result value given the same argument value(s). decrementHP function mutates player-object depending on the object type, so the function has dependency to object type and with some object types is impure. As an example the source code below with the original decrementHP function. From console you can see how it mutates the given object.

Example (ES6):
var decrementHP = function(player) {
return player.set("hp", player.get("hp")-1);
};

var jobe = new Map();
jobe.set("name", "Jobe");
jobe.set("hp", 20);
jobe.set("team", "red");

console.log('original jobe object:', jobe);
decrementHP(jobe);
console.log('jobe object after decrementHP:', jobe);

@Soreine
Copy link
Member

Soreine commented Jan 29, 2016

@Thundechile You're right, pure functions, as said in the beginning of chapter 3, must satisfy two condition:

  • They return the same value for the same input values, and depend only on that
  • They do not have side-effects

But the example from the chapter 3 uses Immutable.Map structures (which are immutable), and not the native Map object as in your (perfectly valid) example.

Referring to the documentation of Immutable.Map, the set() method does not mutate the map but returns a completely new and different Map object. But you're right that the native Map.set() method does mutate the map

@Soreine
Copy link
Member

Soreine commented Jan 29, 2016

As a sidenote: That's a problem with JavaScript. There's no static type system, so you can't ensure pureness, unless you rely on informal rules (such as documentation). Anyone can make up a fake Immutable.Map object with a totally impure and malicious set() function and feed it to the innocent decrementHP function. In a JavaScript world, we can just trust the developers and precise the input types:

/* Immutable.Map -> Immutable.Map */
var decrementHP = function(player) {
  return player.set("hp", player.get("hp")-1);
};

@tkivela
Copy link
Author

tkivela commented Jan 30, 2016

Ok, that cleared things for me, thank you!

So from those comments we can derive that you cannot determine just from the function signature & body if the function actually acts as a pure function, or does it mutate the objects/parameters given to it? Basically you have to look all of the references to the function and look the types sent, if you want to be sure.

@KtorZ
Copy link
Member

KtorZ commented Jan 31, 2016

Indeed. Technically, it's a contract between you and the library provider. Because it's a JavaScript world, you cannot ensure that the function will not mutate the input unless it's explicitly indicated. Keep in mind that all of this does not aim at being a pure functional language but merely a way to introduce FP and FRP concepts easily through a known language, namely, JavaScript.

@KtorZ KtorZ closed this as completed in ab1353b Feb 20, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants