Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

idiomatic lazy atoms in clojure

I am playing a bit with atoms in clojure. I have an atom pointing at a lazy-seq. In another bit of code I want to update the value of the atom to the result of doing next on the sequence, but given that both swap! and reset! return the updated value execution never ends. I figured out that I could always wrap the call to swap!, reset! in a do statement and then return nil, but I am wondering how idiomatic this is or whether there is an alternative solution to do it.

Doesn't terminate:

(def x (atom (range)))
(swap! x next)

Terminates

(def x (atom (range)))
(do (swap! x next) nil)
(first @x) ;1
(do (swap! x next) nil)
(first @x) ;2
like image 549
emanjavacas Avatar asked Jan 08 '23 12:01

emanjavacas


1 Answers

The problem here isn't so much with Clojure, but with the repl you are using. The call to swap! is working just fine, it's that the repl is attempting to print out the result and it can't since the sequence never ends. You can set the number of items printed by Clojure's built-in repl via (set! *print-length* 10). But this won't always work if you have other REPL middleware that performs different print logic.

On the topic of "what is the idiomatic way of doing this", I'd give you two options:

  1. Wrap your call to swap! in a function that returns something different.
  2. Or, in the use case above, put an integer in the atom then use (swap! x inc) to get the next integer.
like image 54
Timothy Baldridge Avatar answered Jan 19 '23 12:01

Timothy Baldridge