JuliaCollections / IterTools.jl

Common functional iterator patterns
Other
152 stars 28 forks source link

`eltype` of partition not inferred, mention in documentation #76

Closed goretkin closed 4 years ago

goretkin commented 4 years ago

I had assumed constant propagation would make these two functions f and g generate identical code.

function f(a)
    s = 0
    for (a,b) in IterTools.partition(a, 2, 1)
        s += sum(abs.(b .- a))
    end
    return s
end

function g(a)
    s = 0
    for (a,b) in IterTools.Partition{typeof(a), 2}(a, 1)
        s += sum(abs.(b .- a))
    end
    return s
end

However

julia> @code_warntype f([1,2,3])
Variables
  #self#::Core.Compiler.Const(f, false)
  a@_2::Array{Int64,1}
  s::Int64
  @_4::Union{Nothing, Tuple{Tuple{Vararg{Int64,N} where N},Tuple{Int64,Array{Int64,1}}}}
  b::Int64
  @_6::Int64
  a@_7::Int64

Body::Int64
1 ─       (s = 0)
│   %2  = IterTools.partition::Core.Compiler.Const(IterTools.partition, false)
│   %3  = (%2)(a@_2, 2, 1)::IterTools.Partition{Array{Int64,1},_A} where _A
│         (@_4 = Base.iterate(%3))
│   %5  = (@_4 === nothing)::Bool
│   %6  = Base.not_int(%5)::Bool
└──       goto #4 if not %6
2 ┄ %8  = @_4::Tuple{Tuple{Vararg{Int64,N} where N},Tuple{Int64,Array{Int64,1}}}::Tuple{Tuple{Vararg{Int64,N} where N},Tuple{Int64,Array{Int64,1}}}
│   %9  = Core.getfield(%8, 1)::Tuple{Vararg{Int64,N} where N}

[...]

where as @code_warntype g([1,2,3]) shows no red.

I tried this on Julia 1.3 and 1.4. It seems like something which Julia could fix, but until then I'm wondering if it's beneficial to include a note in the documentation for partition.

goretkin commented 4 years ago

This is a straight-up duplicate of https://github.com/JuliaCollections/IterTools.jl/issues/39