Re: need help understanding two issues

2010-06-20 Thread Albert Cardona
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

2010-06-19 Thread Albert Cardona
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

2010-06-19 Thread Rob Lachlan
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

2010-06-19 Thread Michał Marczyk
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