0

Consider

class Service {
    methodA(input: string[]): number {
        const resB = this.methodB(input);
        return resB * 2;
    }
    methodB(input: string[]): number {
        return input.length;
    }
}

If MethodB is a pure function, can MethodA also be considered a pure function?

What about the case, when MethodB is a pure function from an injected class?

class Service {
    constructor(helper:Helper){}
    methodA(input: string[]): number {
        const resB = this.helper.methodB(input);
        return resB * 2;
    }
}

In both cases I argued yes in my team, because both cases no side effects takes place and the input>output is deterministic.

On the other side, let alone the the fact, that MethodA was using this. inside its function body was enough for other to say no.

Han Che
  • 8,239
  • 19
  • 70
  • 116
  • 2
    The litmus test for purity is "it shouldn't cause observable side-effects and it should work the same each invocation". The method fulfils both. Then again, I am not sure why that would matter that much. *So what* if it's pure? Or impure? – VLAZ Mar 29 '22 at 13:35
  • In addition to *VLAZ*' statement ... let's consider we deal with pure **functions** only. Now the functions are *nailed* to a namespace (other than the global object, ... let's say a module) which technically makes them _"pure methods"_. Now, what is the advantage of implementing such methods which do neither access nor compute/mutate any `this` context as non/prototypal (and/or static) class methods in comparison to the module implementation? – Peter Seliger Mar 29 '22 at 13:46
  • Given that Javascript is very mutable, a pure function may suddenly be replaced with an impure one at runtime for whatever bizarre reasons… So… what's the distinction *really* useful for then? This isn't Haskell, where it makes an actual difference to the compiler. – deceze Mar 29 '22 at 13:51
  • 1
    @PeterSeliger `this` isn't really special. It can be treated as an argument to the function. Because it is. Especially if you use `.call()` or `.apply()` where you actually pass it in as argument. And a pure function should produce the same result given the same arguments - whether you do `getProp({name: "Fred"}, "name")` (which returns `"Fred"`) or `getProp.call({name: "Fred"}, "name")` the result is the same. It's referentially transparent, too: first might be implemented as `obj[prop]` the second as `this[prop]` but both can be substituted with `({name: "Fred"})["name"]`. – VLAZ Mar 29 '22 at 13:59
  • 1
    @deceze Purity is not just a tool for the compiler, but an aid in reasoning about and understanding how a function works. And people ignore bizarre edge cases for that. – Bergi Mar 29 '22 at 14:58
  • 1
    "*the the fact, that `MethodA` was using `this.` inside its function body was enough for other to say no*" - they're wrong. Only if `this` is mutated (its properties are written to), the function is no longer pure. – Bergi Mar 29 '22 at 15:00
  • @VLAZ ... I'm aware of that. But then one could pass such data (what was the `this` context) as a normal object to pure functions. I'm not against pure methods, I was just questioning the approach of implementing pure functionality with classes as shown by the OP. If there was a plausible answer/reason to it, nothing prevents the OP continuing with this path. If not, the OP should use a simple module based approach. – Peter Seliger Mar 29 '22 at 15:20
  • Hey guys, thanks for this interesting thread :) We concluded internally, that since we are working with javaScript it doesn't make make sense to argue purity for purities sake. So as long as not side effects/mutations are being caused and the result is deterministic, it's pure. – Han Che Mar 30 '22 at 14:39
  • "*So as long as not side effects/mutations are being caused and the result is deterministic, it's pure.*" that's the usual definition of purity. – VLAZ Mar 30 '22 at 15:48

0 Answers0