Re: My quest to modify a leaf node in an arbitrarily deep map (question posed)

2008-12-10 Thread Randall R Schulz

On Wednesday 10 December 2008 10:40, Daniel Eklund wrote:
 Hi all,

 ...

 One thing I immediately ran up against were certain situations where
 I have a map and want to modify a value several levels deep into
 the hierarchy.  Imagine the following structure:

 (def nested-structure { :level 0,
:nested1 { :level 1,
  :nested2 { :level 2,
:final-data initial data}}})

Look into clojure.zip (.../src/clj/clojure/zip.clj in the Clojure 
source).


 ...

 1) Am I missing something from the API that could have done what my
 function path-rebind? (I would have assumed that this would be a
 common need and that programmers would not need to roll their own
 each time)

Yes. The Zipper.


 2) Am I missing out on a clever reduce usage that could have made
 this more in-line?  i.e. how's my code?

 It was after I made wrote this function and contemplated how I could
 make it abstract (i.e. with vectors, lists, etc) that I noticed the
 existence of the zip library...  Maybe question 1) above is
 answered by the zip library.  Is/Will the zip library be the
 recommended means by which to navigate/modify data structures of
 arbitrary depth, branching, and concrete 'type' ?

There you have it. I would say yes.


 daniel


Randall Schulz

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



Re: My quest to modify a leaf node in an arbitrarily deep map (question posed)

2008-12-10 Thread Chouser

On Wed, Dec 10, 2008 at 1:40 PM, Daniel Eklund [EMAIL PROTECTED] wrote:

 user (path-rebind nested-structure [:nested1 :nested2 :final-data]
 new data)
 {:nested1 {:nested2 {:final-data new data, :level 2}, :level
 1}, :level 0}

Congratulations, you've implemented 'assoc-in'  :-)

user= (assoc-in nested-structure [:nested1 :nested2 :final-data] new data)
{:nested1 {:nested2 {:level 2, :final-data new data}, :level 1}, :level 0}

There are also 'get-in' and 'update-in'.

Your code looks fine -- nearly identical to 'assoc-in' in fact.  It
does the destructuring right in the function arguments, but everything
else is merely stylistic differences.

--Chouser

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



Re: My quest to modify a leaf node in an arbitrarily deep map (question posed)

2008-12-10 Thread Daniel Eklund

  One thing I immediately ran up against were certain situations where
  I have a map and want to modify a value several levels deep into
  the hierarchy.  Imagine the following structure:

  (def nested-structure { :level 0,
                          :nested1 { :level 1,
                                    :nested2 { :level 2,
                                              :final-data initial data}}})

 Look into clojure.zip (.../src/clj/clojure/zip.clj in the Clojure
 source).


Excellent... thanks for the pointer.  I will take a stab at using this
for maps (I see stuff for vector-zip, but not yet maps).

As an off-hand comment made without careful reading, I can imagine
there being great utility in a special reader-syntax for paths.  XSLT
embeds xpath, and groovy embeds gpath.  I am unsure at this point the
exact capabilities of the zipper, so I don't know whether it's meant
to go to a single location in a tree (it seems this way) or whether it
refers to a sequence of all tree nodes that satisfy the predicates of
the path (as xpath and gpath do).  For the latter scenario, though, a
reader syntax for a path could be very useful.

thanks again !

daniel
--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



Re: My quest to modify a leaf node in an arbitrarily deep map (question posed)

2008-12-10 Thread Daniel Eklund

  user (path-rebind nested-structure [:nested1 :nested2 :final-data]
  new data)
  {:nested1 {:nested2 {:final-data new data, :level 2}, :level
  1}, :level 0}

 Congratulations, you've implemented 'assoc-in'  :-)

 user= (assoc-in nested-structure [:nested1 :nested2 :final-data] new data)
 {:nested1 {:nested2 {:level 2, :final-data new data}, :level 1}, :level 0}

 There are also 'get-in' and 'update-in'.

 Your code looks fine -- nearly identical to 'assoc-in' in fact.  It
 does the destructuring right in the function arguments, but everything
 else is merely stylistic differences.

 --Chouser

ahh even better...   I knew someone must have done this before and
it kills me now to look at the API and see it right underneath the
(assoc) description.   I have no idea how I missed it.

thanks,
daniel
--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



Re: My quest to modify a leaf node in an arbitrarily deep map (question posed)

2008-12-10 Thread Chouser

On Wed, Dec 10, 2008 at 2:13 PM, Daniel Eklund [EMAIL PROTECTED] wrote:


 As an off-hand comment made without careful reading, I can imagine
 there being great utility in a special reader-syntax for paths.  XSLT
 embeds xpath, and groovy embeds gpath.  I am unsure at this point the
 exact capabilities of the zipper, so I don't know whether it's meant
 to go to a single location in a tree (it seems this way)

That's right.  Every navigation operation on a zip tree gives you a
single tree with a new current location.

 or whether it
 refers to a sequence of all tree nodes that satisfy the predicates of
 the path (as xpath and gpath do).  For the latter scenario, though, a
 reader syntax for a path could be very useful.

For this, you may be interested in clojure.contrib.zip-filter.  It
takes a single zip tree and then applies a series of filters, each of
which may increase or reduce the number of nodes that match (so far),
and/or map each node to some new object.

It has a specialization for XML zip-trees that allows expressions like:

(xml- atom1 :entry :author :name text)

...where atom1 is an xml-zip tree of an atom feed.  The above
expression would return a seq of author name strings.

It doesn't require reader macros or even regular macros.  The 'xml-'
function just takes a number of functions that it applies in order.
The keywords are a special case for XML and act as if you wrote:

(xml- atom1 (tag= :entry) (tag= :author) (tag= :name) text)

A primary benefit of not having a special syntax is that it's easy to
drop in custom filtering and mapping functions.  For example, get the
titles of atom entries with odd-numbered ids:

(xml- atom1 :entry [:id text #(odd? (Integer. %))] :title text)

--Chouser

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---