Yesh I'm reading through Iterators.jl now to try and get my head around it.
On Sunday, July 27, 2014 7:58:09 PM UTC+1, Tim Holy wrote:
>
> Did you check out the examples I suggested? :)
>
> On Sunday, July 27, 2014 11:56:16 AM Ben Ward wrote:
> > I had not considered this - so state variable is a complex type which
> would
> > have say the Queue/Stack and current value, and the start, next and done
> > methods update it?
> >
> > On Sunday, July 27, 2014 7:48:56 PM UTC+1, Tim Holy wrote:
> > > Why can't you keep track of everything in the state variable, and make
> > > your
> > > iterator-types trivial?
> > >
> > > --Tim
> > >
> > > On Sunday, July 27, 2014 11:07:36 AM Ben Ward wrote:
> > > > My traverser types are not exactly wrappers quite a simple as they
> > >
> > > contain
> > >
> > > > FIFO and FILO structures that keep track of things - I struggle to
> > >
> > > imagine
> > >
> > > > how else to have them. Do the three iterate methods necessarily need
> to
> > > > have the second argument "state"? My types know they are done -
> > > > hasReachedEnd() - because there are no more nodes to visit in their
> > >
> > > Ahead
> > >
> > > > Queue/Stack. So would a done() that only requires the type be
> sufficient
> > > > with no state input variable as in done(tier, state)?
> > > >
> > > > Best,
> > > > Ben.
> > > >
> > > > On Sunday, July 27, 2014 4:49:24 PM UTC+1, Tim Holy wrote:
> > > > > You can obtain different types of iteration simply by wrapping
> "obj"
> > >
> > > in
> > >
> > > > > different thin-wrappers. For example, you can define
> > > > >
> > > > > immutable SomeOtherWayOfTraversing{T}
> > > > >
> > > > > obj::T
> > > > >
> > > > > end
> > > > >
> > > > > which is used as
> > > > >
> > > > > for x in SomeOtherWayOfTraversing(obj)
> > > > >
> > > > > # blah
> > > > >
> > > > > end
> > > > >
> > > > > and then write the specific start, next, done methods like this:
> > > > >
> > > > > start{T}(iter::SomeOtherWayOfTraversing{T})
> > > > >
> > > > > You can get totally different behavior this way from what would
> happen
> > > > > when you
> > > > > just say "for x in obj...".
> > > > >
> > > > >
> > > > > You might want to browse through more packages to see more
> examples.
> > > > > Here's
> > >
> > > > > one:
> > >
> https://github.com/timholy/Grid.jl/blob/600cbcf645a73525fb6d563d5a148b9d8b
> > >
> > > > > 2668aa/src/counter.jl but many other packages (DataFrames, Gtk,
> HDF5,
> > >
> > > etc)
> > >
> > > > > define iterators.
> > > > >
> > > > > --Tim
> > > > >
> > > > > On Sunday, July 27, 2014 06:41:43 AM Ben Ward wrote:
> > > > > > I'm not nessecerily trying it iterate over the children of a
> node.
> > > > >
> > > > > Rather I
> > > > >
> > > > > > have defined a series of types that facilitate traversing a tree
> in
> > > > >
> > > > > various
> > > > >
> > > > > > ways for my Phylogenetics.jl package, for example by depth
> first:
> > > > > >
> > > > > > type TraverserCore
> > > > > >
> > > > > > Start::PhyNode
> > > > > > Behind::Stack
> > > > > > History::Array{PhyNode, 1}
> > > > > > Current::PhyNode
> > > > > >
> > > > > > end
> > > > > >
> > > > > >
> > > > > > type DepthFirstTraverser <: TreeTraverser
> > > > > >
> > > > > > Ahead::Stack
> > > > > > Core::TraverserCore
> > > > > > function DepthFirstTraverser(tree::Phylogeny)
> > > > > >
> > > > > > x = new(Stack(PhyNode), TraverserCore(tree.Root,
> Stack(PhyNode),
> > > > >
> > > > > PhyNode
> > > > >
> > > > > > [], tree.Root))
> > > > > >
> > > > > > for i in x.Core.Current.Children
> > > > > >
> > > > > > push!(x.Ahead, i)
> > > > > >
> > > > > > end
> > > > > > return x
> > > > > >
> > > > > > end
> > > > > >
> > > > > > end
> > > > > >
> > > > > >
> > > > > > It has methods like:
> > > > > >
> > > > > >
> > > > > > function next!(x::DepthFirstTraverser)
> > > > > >
> > > > > > push!(x.Core.Behind, x.Core.Current)
> > > > > > x.Core.Current = pop!(x.Ahead)
> > > > > > for i in x.Core.Current.Children
> > > > > >
> > > > > > push!(x.Ahead, i)
> > > > > >
> > > > > > end
> > > > > >
> > > > > > end
> > > > > >
> > > > > >
> > > > > > function getCurrent(x::TreeTraverser)
> > > > > >
> > > > > > return x.Core.Current
> > > > > >
> > > > > > end
> > > > > >
> > > > > >
> > > > > > function hasReachedEnd(x::TreeTraverser)
> > > > > >
> > > > > > length(x.Ahead) > 0 ? false : true
> > > > > >
> > > > > > end
> > > > > >
> > > > > >
> > > > > > Which seem similar to start, next, and done. I'd use them in a
> loop
> > >
> > > like
> > >
> > > > > so
> > > > >
> > > > > > again from Phylogenetics.jl:
> > > > > >
> > > > > > while true
> > > > > >
> > > > > > show(getCurrent(traverser))
> > > > > > if hasReachedEnd(traverser)
> > > > > >
> > > > > > break
> > > > > >
> > > > > > end
> > > > > > next!(traverser)
> > > > > >
> > > > > > end
> > > > > >
> > > > > > But I'd like to make it behave more like an iterator - so be
> able to
> > > > >
> > > > > define
> > > > >
> > > > > > the iterator methods for it so I can do something like
> > > > > >
> > > > > > for i = DepthFirstTraverser(myTree)
> > > > > > # BLARGH
> > > > > > end
> > > > > >
> > > > > > And it will be translated accordingly. I think this is doable by
> > > > >
> > > > > defining
> > > > >
> > > > > > the three methods, making use of the types the method already
> has.
> > > > > >
> > > > > > The idea is to have a load of types that allow the user to code
> > > > >
> > > > > iteration
> > > > >
> > > > > > over the tree in any possible way, easily, providing there is a
> > > > > > TreeTraverser type for it.
> > > > > >
> > > > > > Best,
> > > > > > Ben.
> > > > > >
> > > > > > On Sunday, July 27, 2014 2:14:38 PM UTC+1, Tim Holy wrote:
> > > > > > > for x in obj
> > > > > > >
> > > > > > > # blah
> > > > > > >
> > > > > > > end
> > > > > > >
> > > > > > > will iterate if you've defined start, next, and done functions
> for
> > > > >
> > > > > which
> > > > >
> > > > > > > the
> > > > > > > first argument has typeof(obj). In your case you'd presumably
> use
> > >
> > > a
> > >
> > > > > node
> > > > >
> > > > > > > as
> > > > > > > obj, and the traversal would be recursively over all children
> of
> > >
> > > that
> > >
> > > > > > > node.
> > > > > > >
> > > > > > > If you want a specific tree example, check out
> > > > >
> > > > > ProfileView.jl/src/tree.jl.
> > > > >
> > > > > > > Best,
> > > > > > > --Tim
> > > > > > >
> > > > > > > On Sunday, July 27, 2014 05:13:39 AM Ben Ward wrote:
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > I've been writing a type for recursive tree structures, and
> > >
> > > several
> > >
> > > > > > > types
> > > > > > >
> > > > > > > > that traverse that tree in various manners like breadth
> first or
> > > > >
> > > > > depth
> > > > >
> > > > > > > > first. They have their own methods for getting the current
> tree
> > > > >
> > > > > node,
> > > > >
> > > > > > > > moving to the next node, whether an end has been reached and
> so
> > >
> > > on.
> > >
> > > > > The
> > > > >
> > > > > > > > contain fields for the nodes several steps ahead, those past
> > >
> > > etc. I
> > >
> > > > > > > > wondered if I might make it so as these types might easier
> be
> > >
> > > used
> > >
> > > > > in
> > > > >
> > > > > > > loops
> > > > > > >
> > > > > > > > by giving them the iterator protocol methods? I've not seen
> how
> > >
> > > to
> > >
> > > > > > > define
> > > > > > >
> > > > > > > > custom operators, is it as simple as defining start next and
> > >
> > > done?
> > >
> > > > > How
> > > > >
> > > > > > > is
> > > > > > >
> > > > > > > > the current value gotten? I guess its returned by next().
> > > > > > > >
> > > > > > > > Thanks,
> > > > > > > > Ben.
>
>