JuliaFolds / Transducers.jl

Efficient transducers for Julia
https://juliafolds.github.io/Transducers.jl/dev/
MIT License
432 stars 24 forks source link

`tcollect` and `Zip` fails for more than 1 thread #566

Open BCRARL opened 10 months ago

BCRARL commented 10 months ago

Four threads with collect runs correctly

julia> collect(Zip(Map(identity)), 1:4)
4-element Vector{Tuple{Int64}}:
 (1,)
 (2,)
 (3,)
 (4,)

Replacing collect with tcollect fails due to missing iterate definition even in the most trivial case.

julia> tcollect(Zip(Map(identity)), 1:4)
ERROR: MethodError: no method matching iterate(::Transducers.PrivateState{Transducers.Splitter{Transducers.Reduction{Map{typeof(first)}, Transducers.Reduction{Map{typeof(identity)}, Transducers.Joiner{Transducers.Reduction{Map{typeof(Transducers._zip_between)}, Transducers.Reduction{Map{typeof(last)}, Transducers.Reduction{Map{Type{BangBang.NoBang.SingletonVector}}, Transducers.BottomRF{Completing{typeof(append!!)}}}}}}}}}, Nothing, Transducers.PrivateState{Transducers.Joiner{Transducers.Reduction{Map{typeof(Transducers._zip_between)}, Transducers.Reduction{Map{typeof(last)}, Transducers.Reduction{Map{Type{BangBang.NoBang.SingletonVector}}, Transducers.BottomRF{Completing{typeof(append!!)}}}}}}, Tuple{Int64, Tuple{}}, Vector{Tuple{Int64}}}})

Closest candidates are:
  iterate(::Union{LinRange, StepRangeLen})
   @ Base range.jl:880
  iterate(::Union{LinRange, StepRangeLen}, ::Integer)
   @ Base range.jl:880
  iterate(::T) where T<:Union{Base.KeySet{<:Any, <:Dict}, Base.ValueIterator{<:Dict}}
   @ Base dict.jl:698
  ...
BCRARL commented 10 months ago

The culprit seems to be a call to next(::Max{typeof{first}}, ::PrivateState, input::PrivateState) as generated by Zip. input needs to be unwrapped for first to apply, although I'm not sure whether first(unwrap(rf, input)) is really as intended.