Matt Briggs
Matt Briggs

Reputation: 42178

STM and alter in clojure

I am working through the Programming Clojure book. While explaining alter and the STM, they say that if, during an alter, Clojure detects a change to the ref from outside the transaction, it will re-run the transaction with the new value. If that is the case, I would imagine the update function you pass in needs to be pure, but that isn't indicated in the docs (and it is in other similar situations).

So is my assumption correct? If not, how does the STM re-apply the function? If it is correct, is it the case that you can't rely on the docs to tell you when you can have side effects, and when you can't?

Upvotes: 4

Views: 312

Answers (3)

Riccardo
Riccardo

Reputation: 11

The point in Clojure is that there is no side effect when you deal with Transactions, because they acre consistent, and the function will re-run (I prefer retry) when it finds a conflict during the update of the Shared Value, otherwise it will commit succesfuly the change. If it has to retry, it will read the updated value, so there is no side effect, the problem you could find is a Livelock, but it is kind of controlled by a limit number in retries from Clojure.

Upvotes: 1

Arthur Ulfeldt
Arthur Ulfeldt

Reputation: 91554

Just as a side note:

If you need to perform side-effects like logging in your STM transation you can send messages to agents to do the non-idempotent parts. Messages sent to agents are dispatched only when the transaction finishes and are guaranteed to only be sent once.

Upvotes: 4

amalloy
amalloy

Reputation: 91867

It doesn't strictly have to be pure, it just has to be idempotent. In practice this is basically the same thing.

Further, it only has to be idempotent when seen outside of the STM: if the only side effect you produce is writing to some other ref or (I think) sending to an agent, that operation will be held until your transaction has succeeded.

It's also not really the case that it has to be any of these things: just that, if your update function isn't pure, the results may not be what you expect.

Edit: dosync's docs tell you that any expressions in the body may be executed more than once. You can't run an alter without running a dosync, so it looks like all the docs you need are there. What would you like changed?

Upvotes: 8

Related Questions