You need to either `import Base.start` or implement a function named `Base.start` instead of `start`. That change will make your `start` function extend the one from Base with new methods, rather than being a separate function that happens to be named `start`. (This is a super common confusion.)
-- Leah On Sun, Jul 27, 2014 at 2:40 PM, Ben Ward <axolotlfan9...@gmail.com> wrote: > I've given this a go but it does not quite work as expected: > > immutable DepthFirst > tree::Phylogeny > end > > function start(x::DepthFirst) > state = Stack(PhyNode) > push!(state, x.tree.Root) > return state > end > > function next(x::DepthFirst, state) > current::PhyNode = pop!(state) > for i in current.Children > push!(state, i) > end > return current, state > end > > function done(x::DepthFirst, state) > return length(state) == 0 ? true : false > end > > Then: > > *for i in DepthFirst(myTree)* > > *i* > > *end* > > results in: > > *ERROR: `start` has no method matching start(::DepthFirst)* > > > > > * in anonymous at no file* > > I'm not sure why this is - I have a method defined start() for the > utterable immutable DepthFirst trivial type. I'm clearly missing something > here. > > > 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. >> >>