Srini
Srini

Reputation: 883

Clojure: Update value of record field

I have defined record to store User details and Address Details.

(defrecord User [id name address])

(defrecord Address [id location street city state])

(def usr (User. 1 "Abc"
           (Address. 1 "Location 1" "Street" "NY" "US")))

I have updated "name" to "BCD" using the below code

(assoc usr :name "BCD")

Output:

#async_tea_party.core.User{:id 1, :name "BCD", :address #async_tea_party.core.Address{:id 1, :location "Location 1", :street "Street", :city "NY", :state "US"}}

(usr)

OutPut:

#async_tea_party.core.User{:id 1, :name "Abc", :address #async_tea_party.core.Address{:id 1, :location "Location 1", :street "Street", :city "NY", :state "US"}}

New value of name field has not updated and It still shows old value.

How can I update "name" field permanently in "User" record?

Upvotes: 3

Views: 1649

Answers (2)

Ward
Ward

Reputation: 2852

This is called immutability and is one of the main reasons for me to like clojure so much.

To understand the reasoning why this behaviour is so beneficial, reading values and state really helped me

Upvotes: 1

akond
akond

Reputation: 16035

(def usr (User...)) is kind of immutable. You cannot change it. When you do (assoc usr :name "BCD") you are not changing it. You create a new one. In order to do what you want you need an atom.

(def usr (atom (User. 1 "Abc"
           (Address. 1 "Location 1" "Street" "NY" "US"))))

(:name @usr) ;; "Abc"
(swap! usr assoc :name "BCD")
(:name @usr) ;; "BCD"

Upvotes: 2

Related Questions