I wanted to write an iterator that lazily traverses a graph in breadth first search order, where the graph is defined implicitly by a function giving for each vertex an iterable over the adjacent vertices. This is what I wrote:
struct ImplicitGraph
adj::Function
end
struct TraversalBFS{T}
graph::ImplicitGraph
start::T
end
G = ImplicitGraph(v -> (v - 1, v + 1))
t = TraversalBFS(G, 0)
function Base.iterate(t::TraversalBFS{T}, state=((t.start,), Set{T}())) where {T}
queue, visited = state
p = Iterators.dropwhile(w -> w ā visited, queue) |> Iterators.peel
p === nothing && return nothing
v, to_visit = p
push!(visited, v)
return v, (Iterators.flatten((to_visit, t.graph.adj(v))), visited)
end
for v in t
print(v)
end
In this example we try to traverse the āgraph of integersā starting at 0.
The problem is that this code runs at a ridiculous speed: it seems like the code is constantly being compiled.
Even if the above shown algorithm may not be the best way to achieve what I wanted, it is a perfectly reasonable algorithm. As a comparison, I wrote an analogous version using Python:
import itertools
t = { 'adj': lambda v: (v-1, v+1), 'start': 0 }
initial_state = ((t['start'],), set())
def iterate(t, state):
queue, visited = state
to_visit = itertools.dropwhile(lambda w: w in visited, queue)
v = next(to_visit, None)
if v is None:
return None
visited.add(v)
return v, (itertools.chain.from_iterable((to_visit, t['adj'](v))), visited)
v, state = iterate(t, initial_state)
print(v)
while True:
v, state = iterate(t, state)
print(v)
As you can see, this code runs fast.
The problem with the Julia code is that the data structure of the state of the iterator becomes ever more complex: with every iteration the type-tree grows and grows and Julia overspecializes on these data-structures.
Given that, how is one supposed to write such kind of lazy algorithms in Julia?
(This question is a follow up of the issue I submitted on GitHub: Iterative construction of lazy Iterators leads to excessive compilation time Ā· Issue #52295 Ā· JuliaLang/julia Ā· GitHub)