2 ms·
I do find it annoying. Let's say in JS I have `result = list.map(f)` but now `f` returns a Promise. `result = await Promise.all(list.map(f))` is less pleasant
by sqquima 4mo ago
I do find it annoying. Let's say in JS I have `result = list.map(f)` but now `f` returns a Promise.
`result = await Promise.all(list.map(f))` is less pleasant to read. And before writing it, I have to think if I want the `f` function to execute concurrently across all entries of the list, or one at a time: `for (const elem of list) { await f2(elem) }`.
Or maybe I should use a library like `p-map` and carefully set the concurrency level. Or maybe I should create a bulk version of `f` that takes an array and is more efficient than calling `f` N times.
And don't get me started when there's `list.forEach(f)` and `f` becomes async, so now it executes concurrently for all elements, and the engineer who made the change didn't realize it.
And then there's Async Generators ...
- lmm 4mo ago> I have to think if I want the `f` function to execute concurrently across all entries of the list, or one at a time: `for (const elem of list) { await f2(elem) }`. I'd consider that a positive rather than a negative. That's an important question to think about (usually) and I want the type system to help remind me.
- johnfn 4mo agoBut these are all legitimate choices you have to make, each with their own tradeoffs. Fire-and-forget, all in parallel, and batch are all different - you might end up selecting any based on the characteristics of the work you have to do.