9

While going through the definition for pure functions, it's generally defined with two traits:

1) Should produce same output given the same input

2) Should not produce any side effects

Does it also imply that a pure function shouldn't be asynchronous? If no, how so? If yes, I would love to see some examples of asynchronous pure function in JavaScript.

Anish K.
  • 2,402
  • 3
  • 19
  • 25
  • In your opinion, does `new Promise(() => {}) !== new Promise(() => {})` violate trait 1? Other than not being the same object, the promises behave identically. – Patrick Roberts Oct 06 '18 at 15:31
  • 1
    @PatrickRoberts I guess it does violate the rule#1, since technically my outputs won't be the same while calling the same function twice. – Anish K. Oct 06 '18 at 15:35
  • 2
    Disagree - if referential equality is a requirement for purity, then any function that returns an object in javascript could not be considered pure. – dvlsg Oct 06 '18 at 19:57

2 Answers2

13

Yes, an asynchronous function usually isn't pure, as it conflicts with requirement #2: no side effects.

Most things that we use asynchronous functions for are inherently side-effectful: I/O, network stuff, timers. But even if we ignore those, promises alone rely on some kind of global state for their asynchrony: the event loop. This typically doesn't fit within our definition of purity.

On the other hand, we can simply ignore those when arguing about purity of our functions, just as we ignore all the low-level effects and timings that a computation has on our real-world machine. If you want to argue that your asynchronous function is pure, you should however always state this assumption explicitly. When arguing about the equivalence of two asynchronous values, you will need to have a sophisticated idea of how you model asynchronous effects, e.g. in the evaluation of Promise.race.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
2

yes, async functions are no different from regular functions except that async means it returns Promise<T> rather just T, with that said, this is the only difference from the sync functions which can be pure, hence async functions can be pure too

example:

async function willBeValue<T>(value: T): Promise<T> { return await value; }
Trident D'Gao
  • 18,973
  • 19
  • 95
  • 159
  • 2
    Unlike C#, the `await` there is unnecessary. – Patrick Roberts Oct 06 '18 at 15:27
  • 1
    ```async function willBeValue(value) { return await value; } let x = willBeValue(1) let y = willBeValue(2) x==y >false``` – Anish K. Oct 06 '18 at 15:38
  • @AnishK. What are you trying to check by `x == y`? – Bergi Oct 06 '18 at 16:02
  • @Bergi I meant to write ```willBeValue(1) == willBeValue(1)```, returns false, thus violating rule#1. Couldn't edit the comments though, since it gets locked after 5 mins. – Anish K. Oct 06 '18 at 16:04
  • 3
    @AnishK. No, when we want to judge functions for their purity, they need to return *equivalent* results. Not the exactly same ones. `==` checks for object identity, which is not what we want. We want to consider an array `[1]` and a different array `[1]` to be *equal* (usually), even if they are not the *same* array. – Bergi Oct 06 '18 at 16:08
  • aparently this example and @bergi – TruongSinh Feb 23 '19 at 13:14