That works, but I don't think it's satisfactory. first and second aren't the intended functions to access a map entry's keys and vals— but most importantly, it's been documented that second is very, very slow compared to val (http://w01fe.com/blog/2009/01/more-on-clojure- map-accessor-speeds/). second, in fact, is so slow, I would never use it if there's a chance that it would be called on map entries, even if it would be cleaner and more abstract; I'd have to write my code around the fact that val doesn't work on vector pairs. I think that key and val on vector pairs is a great way to make dealing with maps and their entries more elegant, especially since vector pairs work as map entries in every other case. Is there a good reason why Clojure 1.1 shouldn't allow val on vector pairs?
On Nov 11, 11:54 am, ataggart <[email protected]> wrote: > Just use first and second for both cases. > > On Nov 11, 9:52 am, samppi <[email protected]> wrote: > > > > > Clojure 1.1.0-alpha-SNAPSHOT > > user=> (conj (first {1 2}) 3) > > [1 2 3] > > user=> (conj {1 2} [2 5]) > > {2 5, 1 2} > > user=> (key (first {1 2})) > > 1 > > user=> (key [1 2]) > > java.lang.ClassCastException: clojure.lang.PersistentVector cannot be > > cast to java.util.Map$Entry (NO_SOURCE_FILE:0) > > > In all respects but one, two-sized vectors act like map entries, and > > map entries act like two-sized vectors. This single exception is the > > exception that the key and val forms throw when called on two-sized > > vectors. > > > Almost one year ago, when I was completely new at Clojure, I asked > > about creating map entries (http://groups.google.com/group/clojure/ > > browse_thread/thread/15572b6c7269096e/ab113323410dc39e). Rich Hickey > > made it clear, though, that while he wants key and val to be used on > > map entries, he does not want map entries to be created directly by > > the user, and that map entries could be removed at any time. > > > I presumed in the past year that he wanted us to use vectors whenever > > we wanted to create map entries, since he designed Clojure so that map > > entries are equivalent to vector pairs and vice versa. But in one > > aspect, this does not work. Let me give an example—processing pairs: > > > user=> (defn a [pairs] > > (map #(vector (key %) (inc (val %))) pairs)) > > #'user/a > > user=> (defn b [pairs] > > (map #(vector (key %) (* (val %) 2)) pairs)) > > #'user/b > > user=> (a {:a 3, :b 2}) > > ([:a 4] [:b 3]) > > user=> (b {:a 3, :b 2}) > > ([:a 6] [:b 4]) > > user=> ((comp a b) {:a 3, :b 2}) > > java.lang.ClassCastException: clojure.lang.PersistentVector cannot be > > cast to java.util.Map$Entry > > > If we are not to create map entries directly, but use vector pairs > > instead, then I would like vector pairs to act more like map entries: > > the key and val functions should work on vectors too. This would be > > elegant and complete the equivalence between map entries and vector > > pairs. If this should not be, then what would be the rationale? > > Otherwise, the user should be able to just create map entries instead, > > since Clojure 1.0 definitely has map entries now. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/clojure?hl=en
