1

I'm currently going through my React project looking at where I can convert impure functions into pure functions in order to have less side effects, tidier and more understandable code.

I believe/hope converting to pure functions where possible will achieve this.

My question is, would using Object.keys() inside a function be considered an impurity?

Object.keys()

My thinking is that as although Object.keys() is a function that isn't within the getObjectKeys scope, it is global within vanilla JS and so it wouldn't be considered an impurity or need to be added to the function parameters in an effort to make the function pure by using Dependency Injection . So when asking if getObjectKeys is a pure function:

  • For the same input does it output the same -> yes.
  • Modifying any external variable or object property -> no
  • Are there any side effects -> no

Would you consider getObjectKeys a pure function?

function getObjectKeys(obj) {
    return Object.keys(obj)
}
daniel blythe
  • 946
  • 2
  • 16
  • 44
  • 1
    A pure function is a function which, for given a given input, will always return the same output, and have no side effects. `Object.keys()` fits within that category, so your function is still pure. What side effects are you referring to? Even if it were not part of the language and was actually a function provided by a random library, it would still be pure IMO – blex Dec 06 '20 at 23:26
  • Hi blex, funnily enough I was going to ask a second question, would cloneDeep (lodash) be considered impure how how impure would it be. But you've already answered that, thanks. – daniel blythe Dec 07 '20 at 09:29
  • I see what you refer to, now. When it requires another method to exist, you have a doubt whether that would make it impure. Yes, if that method does not exist, your function will fail. But that would not be due to impurity, it would be due to a programming error – blex Dec 07 '20 at 09:35
  • You are kind of misisng the point of pure functions: They can be global, because they are stateless and have no side effects. A pure function `foo` is the same as `const x = 123`. There is no harm using it in a global scope. Functions relying on other pure functions are quite common in FP. The only question that matters is whether to rely on a hard coded function depdendency or a dynamic one. The latter turns your function into a higher order one, which is more flexible in general. But sometimes you don't need this extra flexibility. –  Dec 07 '20 at 11:42
  • 1
    @scriptum but what, if I change the global reference of `Object.keys` somewhere in the program: `Object.keys = some other (possibly impure) function` ? A function declaration is not write-protected, as opposed to `const` - in fact, I *could* overwrite it. This specific case is rather theoretical I know - though it can be carried over to all mutable references in the global scope an (otherwise) pure function depends on. I would state, that most certainly `getObjectKeys` can be considered pure, but we would have to go through source code to be absolutely sure. – A_blop Dec 07 '20 at 11:53
  • @A_blop If you conduct global mutations it doesn't make sense to talk about purity anymore, because it is a systemic property. If something is impure in a scope, then the entire scope is impure. In JS the interpeter doesn't enforce purity so it is just a convention you need to stick to and rely on. If you need guarentees you shouldn't use JS. –  Dec 07 '20 at 12:41
  • I can't help but feel that you (and everyone else who asks similar questions because I see these a lot in the FP tag) are putting the cart before the horse. A lot of people (mostly new to FP) talk about purity as if it were an end in itself, but we're trying to solve problems with software here. Purity is a *means* to an end (better software) and is helpful only to the extent it serves that end. How does your proposed function make for better (along one or more of this non-exhaustive list of software quality metrics: concise, readable, maintainable, correct, performant, etc) software? – Jared Smith Dec 07 '20 at 12:48
  • Not to mention that the *software itself* is merely a means to end, so it's not just that list of quality metrics, how does worrying about that level of an abstract concept *help increase end-user value*? Because I like FP as much as the next person (I follow the tag here for a reason) but I again can't help but feel like this question misses the point... – Jared Smith Dec 07 '20 at 12:52

1 Answers1

0

It is (almost) pure. "Almost" because you assume that input gonna be an object and I think you can make it fail by feeding wrong input.

However, and it is indeed important, it is absolute nonsense to introduce

function getObjectKeys(obj) {
    return Object.keys(obj)
}

in your real codebase. It does not make any better, nor readable, nor maintainable. That's not what functional programming is all about.

Zazaeil
  • 3,900
  • 2
  • 14
  • 31
  • 1
    "I think you can make it fail by feeding wrong input" you can indeed, feeding any of that family of static methods (.entries, .keys, .values) null or undefined will throw. – Jared Smith Dec 07 '20 at 12:43
  • Throwing an exception doesn't mean it's not a pure function. – David Knipe May 08 '22 at 14:03
  • @DavidKnipe prove it :) – Zazaeil May 08 '22 at 14:19
  • Maybe it depends who you ask. An exception can be caught, so you can prevent a function like this from causing trouble. But you have to remember to add in the extra syntax. – David Knipe May 08 '22 at 14:32
  • Well if you catch exception inside so it never exposed outside — this is semantically equivalent to not throwing any exception at all. So what’s the point than? – Zazaeil May 08 '22 at 15:50