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