On 19 June 2010 18:59, Albert Cardona <sapri...@gmail.com> wrote: > 1. How come APersistentMap$KeySet doesn't implement IPersistentSet?
Beyond what Rob has already written above, keys works with APersistentMap$KeySeq (note the "q" at the end), not APersistentMap$KeySet. To get at the latter, use (.keySet {:a 1 :b 2}); you'll get back a java.util.Set of two entries, :a and :b. This is mainly an interop feature, I believe (meant to make it easier for non-Clojure code on the JVM to read Clojure data structures directly). clojure.set/intersection knows how to handle java.util.Set instances, though in this case, using (comp set keys) -- that is, normally, (set (keys ...)) -- is the more usual and overall more sensible way to go. > 2. I can't get clojure.set/project to work. clojure.set/project is meant to implement the projection operator of [Relational algebra](http://en.wikipedia.org/wiki/Relational_algebra). The representation of relations assumed here is a "collection of tuples", which makes sense: the mathematical definition of a relation -- the one used in relational algebra -- is "a set of tuples". The tuples are here represented as maps. Of course in a mathematical relation all tuples have the same "format"; in Clojure, if some of the maps happen to be missing some of the keys present in some of the other maps, the overall semantics are very much (if not exactly) as if they had those keys bound to nil (as the usual Clojure semantics for maps would imply). Now the projection operator takes a relation and throws out some of its attributes (or some of the columns if you visualise it as a table; or if you think of a set of tuples, it removes some axes from all the tuples). The result is still a relation, i.e. a set, meaning in particular that there are no duplicates: (clojure.set/project #{{:foo 1 :bar 2} {:foo 1 :bar 3}} [:foo]) returns #{{:foo 1}}, because once we throw out the :bars, the two tuples from the input relation become indistinguishable on the basis of the remaining :foo attribute and "blend together" into just one tuple in the output relation. An example where the projection is larger: (clojure.set/project #{{:foo 1 :bar 2} {:foo 2 :quux 3}} [:foo]) ; => #{{:foo 1} {:foo 2}} So, that's how it's supposed to work. Your final example should perhaps fail more gracefully -- the first argument to clojure.set/project cannot be a map (which is by definition a collection of map entries and not of maps, as required here). As things stand, it gives a weird result due to clojure.set/project using select-keys, which in turn uses clojure.lang.RT/find, which happens to return nils when it's called with an argument which makes no sense (in addition to returning nil when the argument does make sense -- i.e. is a map -- but the given key is not found). Sincerely, Michał -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en