Re: Accessing branches in PersistentTreeMap / sorted-map / CLJ-1008

2015-02-20 Thread Michał Marczyk
PS. Well, I suppose you'd want to make sure that you're not getting a key
that lies past the right endpoint of the map when using the nearest-based
approach.


On 20 February 2015 at 16:39, Michał Marczyk michal.marc...@gmail.com
wrote:

 Do you mean you'd like to compress

   {0 :a 1 :a 2 :a 3 :a 4 :b 5 :b 6 :c 7 :c 8 :c 9 :c}

 to something like

   {[0 1 2] :a [4 5] :b [6 7 8 9] :c}

 while maintaining the ability to ask for the value at 0, 1, …, 9?

 If so, you could represent the above as

   {0 :a 2 :a 4 :b 5 :b 6 :c 9 :c}

 (notice no explicit entries for 1, 7, 8) and query for the value at 7,
 say, using

   (val (avl/nearest the-map = 7))
   ;= :c

 (avl/nearest can be implemented for built-in sorted maps using subseq and
 first, in fact the test suite for data.avl has an implementation like that
 that it compares avl/nearest against).

 If you need more operations – say, data.avl-style slice-{at,key} and
 subrange – those could be supported with some care (mostly around the
 possibility that a slice, say, removes an endpoint of an interval – you may
 need to add the slice boundary as a replacement in that case).

 Cheers,
 Michał


 On 20 February 2015 at 16:15, David James davidcja...@gmail.com wrote:

 Thanks for your comments. I see now that I should clarify: all I really
 need is public access to the left and right Java methods in PTM. (So,
 perhaps CLJ-1008 is asking for more than I really need.)

 It seems to me that since Clojure's RB-Tree implementation (i.e.
 sorted-map = PTM), it might as well expose a Java API for root node (which
 it does) and branches (which is does not, currently). Is there any downside
 to exposing the 'right' and 'left' Java methods as public?

 In the near term, I'll be using data.avl. I'm glad it exists! My use case
 involves a non-overlapping interval map to store time series data that
 doesn't change very often.

 --
 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
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.




-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Accessing branches in PersistentTreeMap / sorted-map / CLJ-1008

2015-02-20 Thread David James
Thanks for your comments. I see now that I should clarify: all I really 
need is public access to the left and right Java methods in PTM. (So, 
perhaps CLJ-1008 is asking for more than I really need.)

It seems to me that since Clojure's RB-Tree implementation (i.e. sorted-map 
= PTM), it might as well expose a Java API for root node (which it does) 
and branches (which is does not, currently). Is there any downside to 
exposing the 'right' and 'left' Java methods as public?

In the near term, I'll be using data.avl. I'm glad it exists! My use case 
involves a non-overlapping interval map to store time series data that 
doesn't change very often.

-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Accessing branches in PersistentTreeMap / sorted-map / CLJ-1008

2015-02-20 Thread Michał Marczyk
Do you mean you'd like to compress

  {0 :a 1 :a 2 :a 3 :a 4 :b 5 :b 6 :c 7 :c 8 :c 9 :c}

to something like

  {[0 1 2] :a [4 5] :b [6 7 8 9] :c}

while maintaining the ability to ask for the value at 0, 1, …, 9?

If so, you could represent the above as

  {0 :a 2 :a 4 :b 5 :b 6 :c 9 :c}

(notice no explicit entries for 1, 7, 8) and query for the value at 7, say,
using

  (val (avl/nearest the-map = 7))
  ;= :c

(avl/nearest can be implemented for built-in sorted maps using subseq and
first, in fact the test suite for data.avl has an implementation like that
that it compares avl/nearest against).

If you need more operations – say, data.avl-style slice-{at,key} and
subrange – those could be supported with some care (mostly around the
possibility that a slice, say, removes an endpoint of an interval – you may
need to add the slice boundary as a replacement in that case).

Cheers,
Michał


On 20 February 2015 at 16:15, David James davidcja...@gmail.com wrote:

 Thanks for your comments. I see now that I should clarify: all I really
 need is public access to the left and right Java methods in PTM. (So,
 perhaps CLJ-1008 is asking for more than I really need.)

 It seems to me that since Clojure's RB-Tree implementation (i.e.
 sorted-map = PTM), it might as well expose a Java API for root node (which
 it does) and branches (which is does not, currently). Is there any downside
 to exposing the 'right' and 'left' Java methods as public?

 In the near term, I'll be using data.avl. I'm glad it exists! My use case
 involves a non-overlapping interval map to store time series data that
 doesn't change very often.

 --
 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
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Accessing branches in PersistentTreeMap / sorted-map / CLJ-1008

2015-02-20 Thread David James
Yes, exactly, you read my mind.

(I'd also like to do this a sorted-map / PersistentTreeMap (nudge, nudge) 
-- all that is missing would be public 'left' and 'right' accessors. I 
don't necessarily need rank functionality.)

On Friday, February 20, 2015 at 10:39:26 AM UTC-5, Michał Marczyk wrote:

 Do you mean you'd like to compress

   {0 :a 1 :a 2 :a 3 :a 4 :b 5 :b 6 :c 7 :c 8 :c 9 :c}

 to something like

   {[0 1 2] :a [4 5] :b [6 7 8 9] :c}

 while maintaining the ability to ask for the value at 0, 1, …, 9?

 If so, you could represent the above as

   {0 :a 2 :a 4 :b 5 :b 6 :c 9 :c}

 (notice no explicit entries for 1, 7, 8) and query for the value at 7, 
 say, using

   (val (avl/nearest the-map = 7))
   ;= :c

 (avl/nearest can be implemented for built-in sorted maps using subseq and 
 first, in fact the test suite for data.avl has an implementation like that 
 that it compares avl/nearest against).

 If you need more operations – say, data.avl-style slice-{at,key} and 
 subrange – those could be supported with some care (mostly around the 
 possibility that a slice, say, removes an endpoint of an interval – you may 
 need to add the slice boundary as a replacement in that case).

 Cheers,
 Michał


 On 20 February 2015 at 16:15, David James david...@gmail.com 
 javascript: wrote:

 Thanks for your comments. I see now that I should clarify: all I really 
 need is public access to the left and right Java methods in PTM. (So, 
 perhaps CLJ-1008 is asking for more than I really need.)

 It seems to me that since Clojure's RB-Tree implementation (i.e. 
 sorted-map = PTM), it might as well expose a Java API for root node (which 
 it does) and branches (which is does not, currently). Is there any downside 
 to exposing the 'right' and 'left' Java methods as public?

 In the near term, I'll be using data.avl. I'm glad it exists! My use case 
 involves a non-overlapping interval map to store time series data that 
 doesn't change very often.



-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Accessing branches in PersistentTreeMap / sorted-map / CLJ-1008

2015-02-20 Thread Michał Marczyk
You don't need left and right, you can literally use a sorted map / PTM
that looks like {0 :a 3 :a …} as your representation and build a wrapper to
query it appropriately using functions like avl/nearest, but implemented
using first/(r)(sub)seq.

Here's a prototype:

https://github.com/michalmarczyk/ticktickticktock

(require '[ticktickticktock.core :as ])

(/-map 0 :a 1 :a 2 :a 3 :a 4 :b 5 :b 6 :c 7 :c 8 :c 9 :c)
;= {0 :a, 3 :a, 4 :b, 5 :b, 6 :c, 9 :c}
;; the above is a wrapper around a sorted map

Some interactions:

user= (get (/-map 0 :a 1 :a 2 :a 3 :a 4 :b 5 :b 6 :c 7 :c 8 :c 9
:c) -1)
nil
user= (get (/-map 0 :a 1 :a 2 :a 3 :a 4 :b 5 :b 6 :c 7 :c 8 :c 9
:c) 0)
:a
user= (get (/-map 0 :a 1 :a 2 :a 3 :a 4 :b 5 :b 6 :c 7 :c 8 :c 9
:c) 1)
:a
user= (get (/-map 0 :a 1 :a 2 :a 3 :a 4 :b 5 :b 6 :c 7 :c 8 :c 9
:c) 8)
:c

NB. this really is a prototype – it supports only the what's strictly
necessary for the above demo to work – but it should be fairly
straightforward to extend it to support other desirable features. (For
example assoc elsewhere than beyond the rightmost key etc. dissoc of single
values doesn't really make sense here, but I suppose inserting a gap
would.) Also, I don't think it handles lookups in between intervals very
well… That's fixable as well. I guess the first thing to fix would be the
lack of a clear target API design. :-)

Cheers,
Michał


On 20 February 2015 at 20:09, David James davidcja...@gmail.com wrote:

 Yes, exactly, you read my mind.

 (I'd also like to do this a sorted-map / PersistentTreeMap (nudge, nudge)
 -- all that is missing would be public 'left' and 'right' accessors. I
 don't necessarily need rank functionality.)

 On Friday, February 20, 2015 at 10:39:26 AM UTC-5, Michał Marczyk wrote:

 Do you mean you'd like to compress

   {0 :a 1 :a 2 :a 3 :a 4 :b 5 :b 6 :c 7 :c 8 :c 9 :c}

 to something like

   {[0 1 2] :a [4 5] :b [6 7 8 9] :c}

 while maintaining the ability to ask for the value at 0, 1, …, 9?

 If so, you could represent the above as

   {0 :a 2 :a 4 :b 5 :b 6 :c 9 :c}

 (notice no explicit entries for 1, 7, 8) and query for the value at 7,
 say, using

   (val (avl/nearest the-map = 7))
   ;= :c

 (avl/nearest can be implemented for built-in sorted maps using subseq and
 first, in fact the test suite for data.avl has an implementation like that
 that it compares avl/nearest against).

 If you need more operations – say, data.avl-style slice-{at,key} and
 subrange – those could be supported with some care (mostly around the
 possibility that a slice, say, removes an endpoint of an interval – you may
 need to add the slice boundary as a replacement in that case).

 Cheers,
 Michał


 On 20 February 2015 at 16:15, David James david...@gmail.com wrote:

 Thanks for your comments. I see now that I should clarify: all I really
 need is public access to the left and right Java methods in PTM. (So,
 perhaps CLJ-1008 is asking for more than I really need.)

 It seems to me that since Clojure's RB-Tree implementation (i.e.
 sorted-map = PTM), it might as well expose a Java API for root node (which
 it does) and branches (which is does not, currently). Is there any downside
 to exposing the 'right' and 'left' Java methods as public?

 In the near term, I'll be using data.avl. I'm glad it exists! My use
 case involves a non-overlapping interval map to store time series data that
 doesn't change very often.

  --
 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
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Accessing branches in PersistentTreeMap / sorted-map / CLJ-1008

2015-02-19 Thread David James
Andy, to take advantage of the Red-Black Tree, I'm looking for public API 
access to the branches. (I'm not looking for a work-around.)

More discussion on this at 
SO: 
http://stackoverflow.com/questions/1981859/finding-keys-closest-to-a-given-value-for-clojure-sorted-maps

Thanks to both Michał Marczyk and Andy for commenting on CLJ-1008 (
http://dev.clojure.org/jira/browse/CLJ-1008).

On Thursday, February 19, 2015 at 1:02:53 PM UTC-5, Andy Fingerhut wrote:

 I haven't checked carefully, but from at least a quick look it appears 
 that implementing the NavigableMap and NavigableSet interfaces could be 
 done by using the existing subseq and rsubseq functions in clojure.core?

 It doesn't give you access to subtree nodes directly, but perhaps it is 
 sufficient for your purposes?

 Andy

 On Wed, Feb 18, 2015 at 6:04 PM, David James david...@gmail.com 
 javascript: wrote:

 Summary: I'd like to find a public API to work with the underlying tree 
 of a sorted-map.

 For example:

 (def t (sorted-map 1 :a 2 :b 3 :c 4 :d 5 :e 6 :f)) 

 The underlying implementation of sorted-map uses a PersistentTreeMap, 
 which can be accessed with `tree`:

 (.tree t) ;= [2 :b]

 I have not found a way to access the left and right branches, since 
 calling `left` fails:

 (.left (.tree t))

 IllegalArgumentException Can't call public method of non-public class: 
 public clojure.lang.PersistentTreeMap$Node 
 clojure.lang.PersistentTreeMap$BlackBranch.left()  
 clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:88)

 Perhaps it would be reasonable to make such calls possible, at least from 
 the Java API (without reflection)?

 CLJ-1008 (http://dev.clojure.org/jira/browse/CLJ-1008) offers one 
 possible way to support a public API. It was created in 2012. Perhaps it 
 could use another look. Thoughts? 

  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com 
 javascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com javascript:
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojure+u...@googlegroups.com javascript:.
 For more options, visit https://groups.google.com/d/optout.




-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Accessing branches in PersistentTreeMap / sorted-map / CLJ-1008

2015-02-19 Thread Andy Fingerhut
David:

I see why you would want that.

If you want this soon, I would recommend using data.avl as suggested by Michał,
or copy the parts of the sorted-set/map implementation from Clojure and
implement it yourself.

If you don't want it soon, you could try persuading a few dozen people to
vote on CLJ-1008, and hope the Clojure developers also want this change.
No guarantees there.

Andy

On Thu, Feb 19, 2015 at 12:18 PM, David James davidcja...@gmail.com wrote:

 Andy, to take advantage of the Red-Black Tree, I'm looking for public API
 access to the branches. (I'm not looking for a work-around.)

 More discussion on this at SO:
 http://stackoverflow.com/questions/1981859/finding-keys-closest-to-a-given-value-for-clojure-sorted-maps

 Thanks to both Michał Marczyk and Andy for commenting on CLJ-1008 (
 http://dev.clojure.org/jira/browse/CLJ-1008).

 On Thursday, February 19, 2015 at 1:02:53 PM UTC-5, Andy Fingerhut wrote:

 I haven't checked carefully, but from at least a quick look it appears
 that implementing the NavigableMap and NavigableSet interfaces could be
 done by using the existing subseq and rsubseq functions in clojure.core?

 It doesn't give you access to subtree nodes directly, but perhaps it is
 sufficient for your purposes?

 Andy

 On Wed, Feb 18, 2015 at 6:04 PM, David James david...@gmail.com wrote:

 Summary: I'd like to find a public API to work with the underlying tree
 of a sorted-map.

 For example:

 (def t (sorted-map 1 :a 2 :b 3 :c 4 :d 5 :e 6 :f))

 The underlying implementation of sorted-map uses a PersistentTreeMap,
 which can be accessed with `tree`:

 (.tree t) ;= [2 :b]

 I have not found a way to access the left and right branches, since
 calling `left` fails:

 (.left (.tree t))

 IllegalArgumentException Can't call public method of non-public class:
 public clojure.lang.PersistentTreeMap$Node clojure.lang.
 PersistentTreeMap$BlackBranch.left()  
 clojure.lang.Reflector.invokeMatchingMethod
 (Reflector.java:88)

 Perhaps it would be reasonable to make such calls possible, at least
 from the Java API (without reflection)?

 CLJ-1008 (http://dev.clojure.org/jira/browse/CLJ-1008) offers one
 possible way to support a public API. It was created in 2012. Perhaps it
 could use another look. Thoughts?

  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@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+u...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send
 an email to clojure+u...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


  --
 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
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Accessing branches in PersistentTreeMap / sorted-map / CLJ-1008

2015-02-19 Thread David James
Yes, we're on the same page here. I'm very glad Michał has done great work 
in this Clojure data structure space.

Of course, I wouldn't mind if dozens of people agreed, but I'm more 
interested in the pros/cons before I try to mobilize support. So, to those 
reading this, I'd be interested to hear if:

(a) you agree with CLJ-1008 (or some friendly amendment to it)
(b) you disagree with CLJ-1008 for some principled or philosophical reason 
(not just because you think other things are more pressing or you wouldn't 
personally use a a RB-Tree API right away)
(c) you think more exploration is needed

Some observations and context:

* I find it curious that `tree` is public but `left` and `right` are not. 
Perhaps this was just historical accident?

* Exposing the API for PersistentTreeMaps opens up a lot of useful 
possibilities for derivative data structures. (This is what led me to this 
question.) See, for example, interval trees, in particular ones with 
non-overlapping intervals: http://en.wikipedia.org/wiki/Interval_tree, 
which could be naively implemented with a PersistentTreeMap if it had 
public API access.

On Thursday, February 19, 2015 at 3:37:46 PM UTC-5, Andy Fingerhut wrote:

 David:

 I see why you would want that.

 If you want this soon, I would recommend using data.avl as suggested by 
 Michał, 
 or copy the parts of the sorted-set/map implementation from Clojure and 
 implement it yourself.

 If you don't want it soon, you could try persuading a few dozen people to 
 vote on CLJ-1008, and hope the Clojure developers also want this change.  
 No guarantees there.

 Andy

 On Thu, Feb 19, 2015 at 12:18 PM, David James david...@gmail.com 
 javascript: wrote:

 Andy, to take advantage of the Red-Black Tree, I'm looking for public API 
 access to the branches. (I'm not looking for a work-around.)

 More discussion on this at SO: 
 http://stackoverflow.com/questions/1981859/finding-keys-closest-to-a-given-value-for-clojure-sorted-maps

 Thanks to both Michał Marczyk and Andy for commenting on CLJ-1008 (
 http://dev.clojure.org/jira/browse/CLJ-1008).

 On Thursday, February 19, 2015 at 1:02:53 PM UTC-5, Andy Fingerhut wrote:

 I haven't checked carefully, but from at least a quick look it appears 
 that implementing the NavigableMap and NavigableSet interfaces could be 
 done by using the existing subseq and rsubseq functions in clojure.core?

 It doesn't give you access to subtree nodes directly, but perhaps it is 
 sufficient for your purposes?

 Andy

 On Wed, Feb 18, 2015 at 6:04 PM, David James david...@gmail.com wrote:

 Summary: I'd like to find a public API to work with the underlying tree 
 of a sorted-map.

 For example:

 (def t (sorted-map 1 :a 2 :b 3 :c 4 :d 5 :e 6 :f)) 

 The underlying implementation of sorted-map uses a PersistentTreeMap, 
 which can be accessed with `tree`:

 (.tree t) ;= [2 :b]

 I have not found a way to access the left and right branches, since 
 calling `left` fails:

 (.left (.tree t))

 IllegalArgumentException Can't call public method of non-public class: 
 public clojure.lang.PersistentTreeMap$Node clojure.lang.
 PersistentTreeMap$BlackBranch.left()  
 clojure.lang.Reflector.invokeMatchingMethod 
 (Reflector.java:88)

 Perhaps it would be reasonable to make such calls possible, at least 
 from the Java API (without reflection)?

 CLJ-1008 (http://dev.clojure.org/jira/browse/CLJ-1008) offers one 
 possible way to support a public API. It was created in 2012. Perhaps it 
 could use another look. Thoughts? 

  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@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+u...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google 
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send 
 an email to clojure+u...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com 
 javascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com javascript:
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojure+u...@googlegroups.com javascript:.
 For more options, visit https://groups.google.com/d/optout.




-- 
You received this message because you are 

Re: Accessing branches in PersistentTreeMap / sorted-map / CLJ-1008

2015-02-19 Thread Michał Marczyk
Hi David,

data.avl trees and maps offer navigable map / set functionality out of the
box (with a Clojure API – as mentioned in my comment on CLJ-1008,
implementing the reverse methods would be straightforward in itself, but
problematic due to interactions with other functionality I'd like to have
the option to implement; I might eventually come up with a clean way of
making it all work together, but for now I'd like to keep my options open):

  (avl/subrange (avl/sorted-set 0 1 2 3 4 5) = 2  5)
  ;= #{2 3 4}

Adding them to PTM would be quite a bit trickier, because PTM doesn't store
rank metadata in nodes, and so after extracting a subrange from a PTM
instance we have no good answer to c.c/count, unless of course we're
willing to walk the entire subrange (but at this point it's simpler to just
combine (r)subseq with into to produce a new map; in fact there is a
function like this in data.avl's test suite for use as a sanity check on
the fast implementation – as you'd expect, it's *very* slow, whereas
data.avl/subrange is fast – O(log n) – and gives you first-class results
with O(1) count).

As I said in CLJ-1008, I'm not convinced we should change that – as of
right now, we have in Clojure a lean sorted map (c.l.PTM with basic sorted
map / set functionality) and a more feature-rich sorted map (data.avl –
extra features, fatter nodes). Making c.l.PTM nodes fatter would remove the
lean  basic option, so we should only do it if there's a compelling
reason. Given data.avl's performance – totally on a par with c.l.PTM
(sometimes faster, largely due to AVL trees being shallower, sometimes
slower where they do a measurable amount of extra work) – I'm not sure
there really is a compelling reason. Do you feel otherwise?

(I can see other feature packages being useful for various use cases…
I've been thinking about how best to support them without reimplementing
too much of the basic stuff.)

Going back to the original question, data.avl trees and maps make no
attempt to hide the internal structure of their nodes (although you'll have
to access the fields through clojure.data.avl.IAVLNode method calls and not
direct field access; the fields need to be mutable for data.avl to support
transients, and deftype-introduced mutable fields are always private):

  ;; reflection removable with appropriate hints
  (.. (avl/sorted-set 0 0 1 1 2 2 3 3 4 4) (getTree) (getLeft))
  ;= #AVLNode clojure.data.avl.AVLNode@25c3b70f

As for interval trees, that's one data structure that I've been meaning to
add to data.avl for a long time, and I'm fairly close to releasing a first
cut. Currently I'm aiming at sets of intervals with some overlap queries
(find intervals overlapping this one, find intervals which include this
point). I'm not planning to support all data.avl features for interval
sets in the initial alpha – the purpose of that will be to hash out a good
API for the new stuff – but I'll be happy to add in whatever makes sense in
a future release. (In particular, map-like interval trees in which you
could associate values with the stored intervals are a possibility.)

In any case, whatever your use case is, I'd be very interested to learn
more about it and see if data.avl could provide a useful solution.

Cheers,
Michał


On 19 February 2015 at 23:12, David James davidcja...@gmail.com wrote:

 Yes, we're on the same page here. I'm very glad Michał has done great work
 in this Clojure data structure space.

 Of course, I wouldn't mind if dozens of people agreed, but I'm more
 interested in the pros/cons before I try to mobilize support. So, to those
 reading this, I'd be interested to hear if:

 (a) you agree with CLJ-1008 (or some friendly amendment to it)
 (b) you disagree with CLJ-1008 for some principled or philosophical reason
 (not just because you think other things are more pressing or you wouldn't
 personally use a a RB-Tree API right away)
 (c) you think more exploration is needed

 Some observations and context:

 * I find it curious that `tree` is public but `left` and `right` are not.
 Perhaps this was just historical accident?

 * Exposing the API for PersistentTreeMaps opens up a lot of useful
 possibilities for derivative data structures. (This is what led me to this
 question.) See, for example, interval trees, in particular ones with
 non-overlapping intervals: http://en.wikipedia.org/wiki/Interval_tree,
 which could be naively implemented with a PersistentTreeMap if it had
 public API access.

 On Thursday, February 19, 2015 at 3:37:46 PM UTC-5, Andy Fingerhut wrote:

 David:

 I see why you would want that.

 If you want this soon, I would recommend using data.avl as suggested by 
 Michał,
 or copy the parts of the sorted-set/map implementation from Clojure and
 implement it yourself.

 If you don't want it soon, you could try persuading a few dozen people to
 vote on CLJ-1008, and hope the Clojure developers also want this change.
 No guarantees there.

 Andy

 On Thu, Feb 19, 2015 at 12:18 PM, David 

Re: Accessing branches in PersistentTreeMap / sorted-map / CLJ-1008

2015-02-19 Thread Andy Fingerhut
I haven't checked carefully, but from at least a quick look it appears that
implementing the NavigableMap and NavigableSet interfaces could be done by
using the existing subseq and rsubseq functions in clojure.core?

It doesn't give you access to subtree nodes directly, but perhaps it is
sufficient for your purposes?

Andy

On Wed, Feb 18, 2015 at 6:04 PM, David James davidcja...@gmail.com wrote:

 Summary: I'd like to find a public API to work with the underlying tree of
 a sorted-map.

 For example:

 (def t (sorted-map 1 :a 2 :b 3 :c 4 :d 5 :e 6 :f))

 The underlying implementation of sorted-map uses a PersistentTreeMap,
 which can be accessed with `tree`:

 (.tree t) ;= [2 :b]

 I have not found a way to access the left and right branches, since
 calling `left` fails:

 (.left (.tree t))

 IllegalArgumentException Can't call public method of non-public class:
 public clojure.lang.PersistentTreeMap$Node
 clojure.lang.PersistentTreeMap$BlackBranch.left()
 clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:88)

 Perhaps it would be reasonable to make such calls possible, at least from
 the Java API (without reflection)?

 CLJ-1008 (http://dev.clojure.org/jira/browse/CLJ-1008) offers one
 possible way to support a public API. It was created in 2012. Perhaps it
 could use another look. Thoughts?

  --
 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
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.