Which map access is more idiomatic

12 views
Skip to first unread message

Howard Lewis Ship

unread,
Jun 18, 2009, 7:30:49 PM6/18/09
to clo...@googlegroups.com
I have code that gets passed a map (actually a struct-map), should I

(my-map :my-key)
or
(:my-key my-map)

I'm beginning to gravitate towards the latter, as it is more tolerant of the map being nil.

--
Howard M. Lewis Ship

Creator of Apache Tapestry
Director of Open Source Technology at Formos

J. McConnell

unread,
Jun 18, 2009, 8:13:34 PM6/18/09
to clo...@googlegroups.com
On Thu, Jun 18, 2009 at 7:30 PM, Howard Lewis Ship <hls...@gmail.com> wrote:
>
> I have code that gets passed a map (actually a struct-map), should I
>
> (my-map :my-key)
> or
> (:my-key my-map)
>
> I'm beginning to gravitate towards the latter, as it is more tolerant of the map being nil.

I tend to prefer the latter as well, whenever possible.

- J.

kkw

unread,
Jun 18, 2009, 8:37:31 PM6/18/09
to Clojure
(my-map :my-key) has felt more natural to me, and I suspect it's
because it feels more OO to me (for better or worse). I hadn't
considered nil-map tolerance/robustness before, so I'd be quite happy
to change my mind on new work I write with maps.

Kev

Sean Devlin

unread,
Jun 18, 2009, 9:30:50 PM6/18/09
to Clojure
I like the map-key pattern, especially inside a function.

(fn [my-var]
({"A" 1 :b "one"} my-var))

In this example, the my-var works properly when passed a string.

(fn [my-var]
(my-var {"A" 1 :b "one"}))

The second example breaks when passed a string.

Mark Volkmann

unread,
Jun 18, 2009, 9:51:47 PM6/18/09
to clo...@googlegroups.com
On Thu, Jun 18, 2009 at 6:30 PM, Howard Lewis Ship <hls...@gmail.com> wrote:
I have code that gets passed a map (actually a struct-map), should I

(my-map :my-key)
or
(:my-key my-map)

I'm beginning to gravitate towards the latter, as it is more tolerant of the map being nil.

I prefer the (map key) order. One reason is that it is consistent with a cool use of sets that Stuart Halloway taught me. Here's an example:

(def vowel? (set "aeiou"))

(defn pig-latin [word]
  (let [first-letter (first word)]
    (if (vowel? first-letter)
      (str word "ay")
      (str (subs word 1) first-letter "ay"))))

(println (pig-latin "red"))
(println (pig-latin "orange"))

Note how vowel? isn't really a function. It's a set which is why def is used to define vowel? instead of defn. When it is used, it seems more readable to write (vowel? letter) than (letter vowel?).

--
R. Mark Volkmann
Object Computing, Inc.

CuppoJava

unread,
Jun 18, 2009, 10:02:08 PM6/18/09
to Clojure
I always use (map key), because it's the most likely to fail if "map"
is not what I think it is. This helps avoid some particularly hard to
find bugs.
-Patrick

Christophe Grand

unread,
Jun 19, 2009, 3:46:23 AM6/19/09
to clo...@googlegroups.com
Hi,

On Fri, Jun 19, 2009 at 1:30 AM, Howard Lewis Ship <hls...@gmail.com> wrote:
I have code that gets passed a map (actually a struct-map), should I

(my-map :my-key)
or
(:my-key my-map)

I'm beginning to gravitate towards the latter, as it is more tolerant of the map being nil.


I would further your reasoning on tolerance: it depends on whether the key, the map or both are variable.
(key map) is safe as long as you know that key is a symbol or a keyword.
(map key) is safe as long as you know that map will not be nil.
(get map key) never fails ((get (Object.) (Object.)) returns nil)

Christophe

--
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.blogspot.com/ (en)

Chouser

unread,
Jun 19, 2009, 11:13:35 AM6/19/09
to clo...@googlegroups.com
On Fri, Jun 19, 2009 at 3:46 AM, Christophe Grand<chris...@cgrand.net> wrote:
>
> I would further your reasoning on tolerance: it depends on whether the key,
> the map or both are variable.
> (key map) is safe as long as you know that key is a symbol or a keyword.
> (map key) is safe as long as you know that map will not be nil.
> (get map key) never fails ((get (Object.) (Object.)) returns nil)

I use nil tolerance as my main guide. Also, whether or not I want to allow
'map' to actually be a non-map function. If that's all a wash, then I go for
esthetics: if key is a literal keyword I'll usually put it first, if key is not
a keyword and map is more complex that a simple local or var I'll usually use
'get'.

An example of that last point, I think:

(@(:state-map my-obj) field-id-num)

is more confusing than:

(get @(:state-map my-obj) field-id-num)

--Chouser

Rich Hickey

unread,
Jun 19, 2009, 4:20:36 PM6/19/09
to Clojure


On Jun 19, 11:13 am, Chouser <chou...@gmail.com> wrote:
I like (:key map) when I'm treating the map like I would an object
with keywords as fields, and (map key) when I'm treating a map like a
collection. Not a hard rule.

Rich
Reply all
Reply to author
Forward
0 new messages