Rex Kerr
1 min readMar 11, 2023

--

Many of the rules of thumb agree with mine, but I have a few differences.

1. Prefer chains of map/flatMap/collect/whatever over for-comprehensions because they are more flexible and explicit about what is happening when. Also, it's much easier to integrate "generators of different types" because you can just switch type mid-chain if that's what you need.

2. Use one-line syntax for very simple for comprehensions, because it makes it easier to embed them in other places (closures, arguments, etc.) and only doing so when embedding is inconsistent. Also, always use braces instead of parens for consistency. However, this rarely comes up because of rule 1: one would almost always use map instead. (Destructuring can be an exception.)

3. Put as much work into the `yield` as possible. This is ordinary-code-land where everything works the way you expect. If you put code into the for-comprehension part, you might not anticipate when certain code will actually be run. In the `yield`, it's abundantly obvious.

Also: don't name things when you don't need to name them; it's extra clutter if you're only ever going to refer to it once. Exception: when you're matching function argument to a particular argument in some method, favor x => foo(a, x, z) over foo(a, _, z). Not an exception because you need to name it: even if you use it only once, if it's at all complicated, name it, but with a meaningful name. It's documentation for what the complicated thing is.

Anyway, it's a good intro to for-comprehensions!

--

--

Rex Kerr
Rex Kerr

Written by Rex Kerr

One who rejoices when everything is made as simple as possible, but no simpler. Sayer of things that may be wrong, but not so bad that they're not even wrong.

No responses yet