## Consider run!

January 16, 2016

Sometimes you need to perform a side effect for each element in a sequence. For the sake of argument, let's say we want to `prn` each of the items in `[0 1 2 3 4]`.

The existing core function `doseq` can be used to accomplish this:

``````(doseq [x [0 1 2 3 4]]
(prn x))
``````

Since `doseq` is modeled after `for`, lots of sophisticated things can be done using its mini-language, with `:let`, `:while`, and `:when`.

But, for applying `prn` to each of the elements, you may be tempted to reach for this simpler looking `map` form:

``````(map prn [0 1 2 3 4])
``````

While this has appeal, it is laced with subtle issues surrounding evaluation and lazy sequences.

When you have something like this, you don't need to resort to `dorun` to force evaluation. Instead, simply replace `map` with `run!`, directly indicating your intent:

``````(run! prn [0 1 2 3 4])
``````

As its docstring indicates, `run!` is based on `reduce`, which is eager, thus side-stepping any issues with lazy sequences. Also with `run!`, no temporary sequence is produced and discarded as would be with `(dorun (map ...))`.

And, since it is based on `reduce`, this gives you a way to terminate processing early—you can use `reduced`:

``````(run! (fn [n]
(if (< n 3)
(prn n)
(reduced nil)))
(range))
``````

This will apply `prn` to only the first 3 elements of the infinite sequence returned by `(range)` and terminate:

``````0
1
2
``````

Note that, while the intent of `run!` is that it be used solely for side effects (and thus is without a meaningful return value), it can return non-`nil` in its initially-released form in Clojure and ClojureScript.

The `run!` function was introduced with the work done to add transducers to Clojure 1.7, also first appearing in ClojureScript 0.0-2301.

Tags: Clojure ClojureScript