1

I've been learning Clojure for a few weeks now. I know the basics of the data structures and some functions. (I'm reading the Clojure Programming book).

I'm stuck with the following. I'm writing a function which will lower case the keys of the supplied map.

(defn lower-case-map [m]
  (def lm {})
  (doseq [k (keys m)]
    (assoc lm (str/lower-case k) (m k))))

This does what I want, but how do I return the map? Is the def correct?

I know this works

(defn lower-case-map [m]
  (assoc {} :a 1))

But the doseq above seems to be creating a problem.

1
  • You should never use def inside of a function on Clojure. def should only be used on the top level. Use let to define local variables instead. Commented Jul 21, 2015 at 8:10

1 Answer 1

5

Within a function body you should define your local variables with let, yet this code looks alot like you try to bend it into an imperative mindset (def tempvar = new Map; foreach k,v in m do tempvar[k.toLower] = v; return tempvar). Also note, that the docs of doseq explicitly state, that it returns nil.

The functional approach would be a map or reduce over the input returning the result directly. E.g. a simple approach to map (iterating the sequence of elements, destructure the key/value tuple, emit a modified tuple, turn them back into a map):

user=> (into {} (map (fn [[k v]] [(.toLowerCase k) v]) {"A" 1 "B" 2}))
{"a" 1, "b" 2}

For your use-case (modify all keys in a map) is already a nice core function: reduce-kv:

user=> (doc reduce-kv)
-------------------------
clojure.core/reduce-kv
([f init coll])
  Reduces an associative collection. f should be a function of 3
  arguments. Returns the result of applying f to init, the first key
  and the first value in coll, then applying f to that result and the
  2nd key and value, etc. If coll contains no entries, returns init
  and f is not called. Note that reduce-kv is supported on vectors,
  where the keys will be the ordinals.

user=> (reduce-kv (fn [m k v] (assoc m (.toLowerCase k) v)) {} {"A" 1 "B" 2})
{"a" 1, "b" 2}
Sign up to request clarification or add additional context in comments.

1 Comment

Sure, years of imperative style programming has me hooked. Trying hard to get into functional programming.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.