Re: need help understanding two issues
Thank you very much Rob and Michal, both issues are clear now. Michael, I agree that the documentation for clojure.set/project could improve. At least now there is your email to be sent around to those like me who don't get it from the very succinct default doc string. Albert -- http://albert.rierol.net -- 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
need help understanding two issues
Hi all, I have run into the following two issues over the last few days. I would appreciate insight/help/advice: 1. How come APersistentMap$KeySet doesn't implement IPersistentSet? (clojure.set/intersection (keys {2 two 4 four}) #{2 3}) java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentSet So one must: (clojure.set/intersection (set (keys {2 two 4 four})) #{2 3}) ... which is redundant. Is there a better way? 2. I can't get clojure.set/project to work. All of the following throw an exception: (clojure.set/project (keys {2 two 4 four}) #{2 3}) (clojure.set/project (set (keys {2 two 4 four})) #{2 3}) Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.Map ... and this one returns a result that I don't understand: (clojure.set/project {2 two 4 four} #{2 3}) #{{}} So perhaps I have misread what xrel is supposed to be, in the docs for clojure.set/project: clojure.set/project ([xrel ks]) Returns a rel of the elements of xrel with only the keys in ks I understand that one should use select-keys to get the submap for a given set of keys. But how come the map's key set is not set that plays well with the rest of clojure sets? Help very appreciated. Albert -- http://albert.rierol.net -- 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
Re: need help understanding two issues
I'll take a whack at it. 1. How come APersistentMap$KeySet doesn't implement IPersistentSet? Because keys and vals are designed to return (lazy) sequences. More important, these two functions return those two sequences in the same order. The laziness avoids having to incur the overhead of creating the set structure, though if you want that you can just call (set (keys map)) as in your example. 2. I can't get clojure.set/project to work. All of the following throw an exception: (clojure.set/project (keys {2 two 4 four}) #{2 3}) (clojure.set/project (set (keys {2 two 4 four})) #{2 3}) Yeah, I found the doc confusing as well. Here's an example: user (ns user (:use clojure.set)) nil user (project [{1 2, 2 4, 3 6}, {1 3, 2 6}] [1]) #{{1 3} {1 2}} So project seems to take a collection of maps, and projects, or restricts them all on to the values specified in the second argument. Cheers Rob -- 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
Re: need help understanding two issues
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