Earlier quoted context omitted.
let accumulator = 0 for (let item of array) { const value = await item // your code here } Is identical, doesn't use 'cool' reduce features but is much easier to read in my opinion.
Wouldn’t this code only execute 1 promise at a time? I thought Promise.all allowed promises to be resolved in parallel
Folding Promises in JavaScript
41–48 of 48 posts
Re: Folding Promises in JavaScript
#42Earlier quoted context omitted.
I feel the code I wrote while on this bandwagon is the hardest to understand for others and for me myself today. pullAllBy(pluck(things, 'bar').map(compose(xor, lol, rofl)).reduce(differenceWith('id')) Just write your transformations inline and go work on the next feature.
I feel like the functional code you wrote was written to intentionally obfuscate what is being done. For instance, composing a bunch of methods inline doesn't have any utility for it unless you define what compose(xor, lol, rofl) really means. Ideally this is how it should be written for maximum readability. things |> pluck('bar') |> map(xor) |> map(lol) |> map(rofl) |> reduce(differenceWith('id') The code is written…
things
|> pluck('bar')
|> map(compose(rofl, lol, xor))
|> reduce(differenceWith('id')Re: Folding Promises in JavaScript
#43Earlier quoted context omitted.
I feel like the functional code you wrote was written to intentionally obfuscate what is being done. For instance, composing a bunch of methods inline doesn't have any utility for it unless you define what compose(xor, lol, rofl) really means. Ideally this is how it should be written for maximum readability. things |> pluck('bar') |> map(xor) |> map(lol) |> map(rofl) |> reduce(differenceWith('id') The code is written…
I agree, but you shouldn't map 3 times when you can map once over the data. things |> pluck('bar') |> map(compose(rofl, lol, xor)) |> reduce(differenceWith('id')
Composing xor, rofl, lol isn't any better (esp in terms of readability) than it is individual maps.
What would be better is this:
const makeHilarious = compose(rofl, lol, xor);
things
|> pluck('bar')
|> map(makeHilarious)
|> reduce(differenceWith('id')Re: Folding Promises in JavaScript
#44Earlier quoted context omitted.
> Pointless abstraction is one of my pet peeves in this industry. This looks like it has gone from a fairly straightforward, if kludgy, piece of code to something far more complex. Why not just: [code] Your example code works just fine for promises of course, but not all monads support a coalescing operation like Promise.all. So even though this article only discusses folding over Promises, the core idea here can be…
> not all monads support a coalescing operation like Promise.all. Actually, they do. Haskell calls it sequence :: (Traversable t, Monad m) => t (m a) -> m (t a) [1] It works by consuming the structure outside the monad and rebuilding it inside. A possible implementation specialized for lists is sequence [] = return [] sequence (h:t) = do h' [1] http://hackage.haskell.org/package/base-4.10.0.0/docs/Prelud...
Promise.all is not just sequence though, there's some additional subtleties to it. In particular the fail-fast behaviour:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
That's the kind of fundamental coalescing operation that you cannot implement with bind on plain monads.
Re: Folding Promises in JavaScript
#45Earlier quoted context omitted.
I agree, but you shouldn't map 3 times when you can map once over the data. things |> pluck('bar') |> map(compose(rofl, lol, xor)) |> reduce(differenceWith('id')
I made my case against the compose in the post. Composing xor, rofl, lol isn't any better (esp in terms of readability) than it is individual maps. What would be better is this: const makeHilarious = compose(rofl, lol, xor); things |> pluck('bar') |> map(makeHilarious) |> reduce(differenceWith('id')
things
.map(thing => x.bar)
.map(thing => {
// whatever happens in rofl
// whatever happens in lol
})
.reduce((acc, thing) => {
// more stuff
}, {})
This is code that is easy to understand and safe to change. The maps could be combined into one function body if it's convenient.Re: Folding Promises in JavaScript
#46Earlier quoted context omitted.
I made my case against the compose in the post. Composing xor, rofl, lol isn't any better (esp in terms of readability) than it is individual maps. What would be better is this: const makeHilarious = compose(rofl, lol, xor); things |> pluck('bar') |> map(makeHilarious) |> reduce(differenceWith('id')
This means that to change this code you first have to look for the makeHilarious definition, then the definitions of rofl, lol and xor, then figure out what they all do separately and together, and if you can change them without breaking anything else in your application. things .map(thing => x.bar) .map(thing => { // whatever happens in rofl // whatever happens in lol }) .reduce((acc, thing) => { // more stuff }, {}…
It is one thing to quickly be able to understand that the person is doing a xor, then a rofl and then a lol of each element of an array, and a whole another thing to understand what the combination of these three actions over an array means. The python school of "code is read more than it's written" heavily stresses on explaining how easily the code should be understandable the first time someone reads it, but not whether it's easy to reason about or not.
The beauty of declarative style programming isn't to get more readable code immediately, but rather that once you understand the vocabulary, how easy it is for you to understand and reason about the code.
For instance, imagine reading a novel which is written like this:
"After Jack was done from the place where he went to do things for money everyday, he entered an establishment which served drinks that get you inebriated for money. This establishment was one he frequented regularly and preferred it over the others. He asked the man behind the counter for a wheat fermented brewed drink. After putting the drink to his lips and pouring it in to his mouth, he felt a sense of calmness enter his mind. It pushed all the thoughts which occupied his mind away, as he earlier desired before entering this establishment."
As opposed to:
"Jack really needed a drink after hard day at work. He went to his favorite pub, and ordered his favorite beer. After finishing the pint, he finally felt relaxed."
The Python philosophy (which is permeated everywhere in imperative world) is to describe everything in the simplest possible terms just in case there are people who may not understand what work, pub, beer, bartender, and relaxed means. But this just prevents from understanding of the actual purpose of the code.
This is at least the basic philosophy behind not using for loops everywhere.
Re: Folding Promises in JavaScript
#47Earlier quoted context omitted.
Endomorphism has less implied structure. Lots of dumb things are endomorphisms. Homomorphism implies "structure preservation" which can make it more specific.
I'm surprised to read this coming from you.
https://ncatlab.org/nlab/show/endomorphism
I think "endomorphism is a homomorphism ..." is more common, but notably is not the usage in Haskell (https://hackage.haskell.org/package/base/docs/Data-Monoid.ht...)
Re: Folding Promises in JavaScript
#48Earlier quoted context omitted.
I'm surprised to read this coming from you.
It seems "endomorphism" is used both ways (in, presumably, different contexts). https://ncatlab.org/nlab/show/endomorphism I think "endomorphism is a homomorphism ..." is more common, but notably is not the usage in Haskell ( https://hackage.haskell.org/package/base/docs/Data-Monoid.ht... )