There is a protocol-based zipper lib at
https://github.com/akhudek/fast-zip

In my experience it can be made even faster if perf is a huge concern.

If this lib gets upgraded, another big item is built-in support for
the full range of clojure datastructures. Currently zippers are more
limited than walk, which already has known issues in that regard.




On Thu, Jan 2, 2014 at 12:09 PM, Timothy Baldridge <tbaldri...@gmail.com> wrote:
> clojure.zip needs to be rewritten IMO. It's written in more of a scheme
> style using vectors. Since then protocols have come out and there's no
> reason why this can't make use of those. And yes, at the same time new
> functions could probably be added.
>
> I've threatened to re-write this lib several times, and always gotten pulled
> away into other projects. Code it up though and I'd love to see it pushed
> through.
>
> The first thing that would need to happen would be for the library to get
> much better testing, right now there aren't any tests around this lib at
> all.
>
> Anyway, that's my 2 cents.
>
> Timothy
>
>
> On Thu, Jan 2, 2014 at 5:07 AM, Alex Dowad <alexinbeij...@gmail.com> wrote:
>>
>> Hi, everybody,
>>
>> I'm just throwing this out to see if the Clojure core team agrees, and if
>> they would like me to code something up and send a PR.
>>
>> clojure.zip works great if you want to walk a tree and add nodes here and
>> there -- append-child, insert-child, insert-left, and insert-right cover all
>> the important use cases. If you want to walk a tree and filter nodes out,
>> remove has you covered. I've discovered, though, that trying to *move* nodes
>> is very cumbersome, far more than it needs to be.
>>
>> The crux of the problem is here (to quote the API docs):
>>
>> remove
>>
>> function
>>
>> Usage: (remove loc)
>>
>> Removes the node at loc, returning the loc that would have preceded
>> it in a depth-first walk.
>>
>>
>> The problem is that remove "returns the loc that would have preceded" the
>> removed node "in a depth-first walk". If I want to push a node down below
>> its left/right sibling, or pull it up to become a sibling of its parent, or
>> make it swap places with its left/right sibling, etc. etc., going to "the
>> loc that would have preceded it in a depth-first walk" is useless. Once the
>> node is removed, it's very hard to find my way back to the loc where I want
>> to insert it.
>>
>>
>> I'm not saying that the API for remove is faulty -- it's perfect if your
>> goal is just to filter nodes out. But functions are needed which can remove
>> a node *and* return the loc above/to the left/to the right.
>>
>>
>> When I ran into this problem, I cracked open the source for clojure.zip,
>> looked at the source for "remove", and coded this variant up:
>>
>>
>> (defn remove-and-up [loc]
>>   (let [[node {l :l, ppath :ppath, pnodes :pnodes, rs :r, :as path}] loc]
>>     (if (nil? path)
>>       (throw (new Exception "Remove at top"))
>>       (if (pos? (count l))
>>         (up (with-meta [(peek l)
>>                     (assoc path :l (pop l) :changed? true)]
>>                    (meta loc)))
>>         (with-meta [(make-node loc (peek pnodes) rs)
>>                     (and ppath (assoc ppath :changed? true))]
>>                    (meta loc))))))
>>
>>
>> That removes a node, and returns the loc of its parent. My problem is now
>> solved. But to a newbie programmer, that problem would have probably been
>> insurmountable.
>>
>>
>> What do you think? Is adding a function or two to clojure.zip warranted?
>>
>>
>> Thanks, AD
>>
>> --
>> --
>> 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/groups/opt_out.
>
>
>
>
> --
> “One of the main causes of the fall of the Roman Empire was that–lacking
> zero–they had no way to indicate successful termination of their C
> programs.”
> (Robert Firth)
>
> --
> --
> 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/groups/opt_out.

-- 
-- 
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/groups/opt_out.

Reply via email to