Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What function to use when you want both side effect and retain value in Clojure?

Tags:

clojure

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?

like image 933
LoveProgramming Avatar asked Jul 26 '17 23:07

LoveProgramming


Video Answer


2 Answers

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.

like image 149
Chris Murphy Avatar answered Oct 28 '22 14:10

Chris Murphy


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.

like image 45
Slae Avatar answered Oct 28 '22 14:10

Slae