People are saying avoid using map
to perform side effects over sequence and it makes sense.
But in the real world, I find myself needing to both retain the result and have the map
evaluated eagerly, i.e, when inserting to db and returning the record.
Is (doall (map ..))
my only choice here? Is there a more idiomatic way to do this?
No. (doall (map ..))
is not your only choice: mapv
is not lazy, so it effectively does (doall (map ..))
, but in one operation.
It is not great to use either map
or mapv
with a map function that produces side effects. Instead try to use doseq
, which clearly indicates that side effects will be taking place. As you point out, and this goes to the crux of your question, the problem with doseq
is that return results are not gathered together for you in a sequence as they are with map
or mapv
.
If you don't want a lazy sequence then try not to produce it in the first place, rather than producing it and then forcing it to be realised as you are currently doing. Thus we should rule out the use of map
.
Most cases where you do not need laziness are covered by using mapv
when your map function is not side-effecting, or doseq
when it is, but doesn't return a result.
If your map function both produces a result, and is side effecting, and you want those results to be gathered together, then your best bet would be to use mapv
over a map function that is named as clearly producing a side effect by having a name ending in !
. While this is not a great use of mapv
, at least the !
clearly highlights what is going on.
I would use (doall (map ..))
as you stated since it is clear what the intention is in your code. mapv
works as well, although the intention is a little more ambiguous.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With