Monday, June 11, 2012

Clojure: name function

The 'name' function is a clojure function that returns the string for a keyword, symbol, or string.
name - function
Usage: (name x)
Returns the name String of a string, symbol or keyword.
At first glace this might not seem that interesting; however, it's good to know 'name' if you've ever been surprised by (str :foo) => ":foo". If you have a ruby background (as I do), you probably expected the result to be "foo", spent a bit of time looking, and found that (name :foo) was actually what you were looking for.

That's helpful, but not particularly exciting. Perhaps a more interesting application of name is the ability to normalize all keys as strings and destructure. For example, say you're designing a library that monitors threads and you want to be able to pass in warning and error thresholds. Usage of your functions may look like the following examples
(monitored-threads/create :warn-threshold 100 :error-threshold 200)
(monitored-threads/create "warn-threshold" 100 "error-threshold" 200)
Assuming a simple function that updates keys:
(defn update-keys [m f]
  (reduce (fn [r [k v]] (assoc r (f k) v)) {} m))
You can now write your create function as:
(defn create [& {:as m}]
  (let [{:strs [warn-threshold error-threshold]} (update-keys m name)]
    ; do work, son
    ))

2 comments:

  1. Not sure I agree with the idea of normalizing to strings, especially when keywords are the better fit for use as map keys.

    Note that the function name does not handle name-spacing of keywords. Compare ":foo" and "::foo" to "(name :foo)" and "(name ::foo)" .

    ReplyDelete
  2. Alex, I'm not advocating that you should use strings as keys. When possible, I always use keywords. However, if you need to support both strings & keywords I think this is a decent option. Obviously, you could also update-keys with 'keyword' and switch :strs to :keys. This post isn't about recommending anything, it's about showing what you *could* do.

    ReplyDelete

Note: Only a member of this blog may post a comment.