Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement an iterator in Julia?

Tags:

julia

I am trying to implement an iterator in Julia, but get an exception when the for-loop tries to call start already.

Here is what I get (I ran include(...), then using RDF):

julia> methods(start)
# 1 method for generic function "start":
start(graph::Graph) at /Users/jbaran/src/RDF.jl/src/RDF.jl:214

julia> for x in g
       println(x)
       end
ERROR: `start` has no method matching start(::Graph)
 in anonymous at no file

The function definition in the RDF module looks like this at the moment:

function start(graph::Graph)
    return GraphIterator(collect(keys(graph.statements)), nothing, nothing, nothing, [], [])
end

Any idea what I am doing wrong?

like image 380
Joachim Avatar asked Jun 06 '26 09:06

Joachim


2 Answers

In Julia 1.+, you should implement:

  1. Base.iterate(::YourType) for the starting iteration,
  2. Base.iterate(::YourType, state) for following iterations while getting the state from the previous steps.

Both methods should return (result, state) tuple, except for the last iteration that should return nothing.

In practice, this means that iterating on x::YourType with

for i in x
    # some code
end

is a shorthand for writing

it = iterate(x)
while it !== nothing
    i, state = it
    # some code
    it = iterate(x, state)
end

See the manual for details.

like image 105
BoZenKhaa Avatar answered Jun 07 '26 22:06

BoZenKhaa


Don't forget to specify Base. - you are adding methods to an existing function.

module MyMod
  type Blah
    data
  end
  export Blah
  Base.start(b::Blah) = 1
  Base.done(b::Blah,state) = length(b.data) == state-1
  Base.next(b::Blah,state) = b.data[state], state+1
end
using MyMod
x = Blah([1,2,3])
for i in x
  println(i)
end

This works as of Julia 0.3.

like image 31
IainDunning Avatar answered Jun 07 '26 22:06

IainDunning