How to use an atom to update a map's state?

Viewed 671

I want to create a function that holds the frequencies of strings I deem as spam. I'm trying to use an atomic map that can be updated as I give the map a new string.

Desired Behavior

user> (train-word spam "FREE")
{"FREE": 1}
user> (train-word spam "FREE")
{"FREE" : 2}
user> (train-word spam "MONEY")
{"FREE" : 2 "MONEY" : 1}

So far I have tried

(def spam (atom {}))
(defn train-word [m word]
  (swap! update-in m [word]
                 (fn [old] (inc (or old 0)))))

but that produces an error:

clojure.lang.Atom cannot be cast to clojure.lang.Associative  clojure.lang.RT.assoc (RT.java:702)

I'm new to Clojure so I did a quick prototype in Python

from collections import defaultdict
spam = defaultdict(int)
def train_word(word, spam):
        spam[word] += 1

What is the idiomatic way to manage state using an atom to update current values as well as add new ones? Thanks!

1 Answers
Related