yazz.com
yazz.com

Reputation: 58826

Can I create mutable state inside Clojure records?

I am considering using Clojure records to map to changing entities in my program. Are they mutable? Or do you need to use extra refs within the records? I am a little confused about this

Upvotes: 9

Views: 3224

Answers (2)

mikera
mikera

Reputation: 106401

It's well worth watching Rich Hickey's fantastic video on identity and state.

Records are designed to be immutable and store the state of something as a value.

To model the state of a changing entity, I'd recommend using a ref that refers to an immutable value that represents the current state. You can use records for the immutable state, but often it's simpler just to use a simple map.

A simple example, where the mutable state is a scoreboard for a game:

; set up map of current scores for each player
(def scores 
  (ref 
    {:mary 0 
     :joe  0   }))

; create a function that increments scores as a side effect
(defn add-score [player amount]
  (dosync
    (alter scores update-in [player] + amount)))

; add some scores
(add-score :mary (rand-int 10))
(add-score :joe (rand-int 10))

; read the scores
@scores
=> {:mary 6, :joe 1}

Upvotes: 12

Arthur Ulfeldt
Arthur Ulfeldt

Reputation: 91617

I have found that I much more commonly put records in refs than refs in records. mikira's advice to use a simple map sounds very good.

Start with a map and switch to something less flexable when you have to.

Upvotes: 5

Related Questions