Sum(i for i in Vector{Int}()) raises error instead of returning 0?


sum(i for i in Vector{Int}())

raises an error:

ERROR: MethodError: no method matching zero(::Type{Any})
Closest candidates are:
zero(::Type{Base.LibGit2.Oid}) at libgit2/oid.jl:88
zero(::Type{Base.Pkg.Resolve.VersionWeights.VWPreBuildItem}) at pkg/resolve/versionweight.jl:80
zero(::Type{Base.Pkg.Resolve.VersionWeights.VWPreBuild}) at pkg/resolve/versionweight.jl:120

in mr_empty(::Base.#identity, ::Base.#+, ::Type{T}) at ./reduce.jl:130
in mapfoldl(::Base.#identity, ::Function, ::Base.Generator{Array{Int64,1},##11#12}) at ./reduce.jl:60
in sum(::Base.Generator{Array{Int64,1},##11#12}) at ./reduce.jl:229

Why can’t sum infer that the type is Int, and return an integer 0?
(The mathematical definition of an empty sum is 0)


See also the related issue and


Is there / shouldn’t there be a way to specify the eltype of a generator? What’s the equivalent of sum(Int[i for i in Vector{Int}()])


Something like

sum(f(x)::Int for x in Vector())

should tell the compiler that the generator’s eltype is an Int. Currently it raises the same error (julia v0.5.0).


I defined a “safe sum” that guarantees a return type and returns the correct 0 for empty iterators:

function sumf(::Type{T}, itr)::T where T
    isempty(itr) ? zero(T) : sum(x::T for x in itr)::T

Perhaps this should be added as a method to Base.sum?


Note that while it may be useful, adding it to sum would conflict with the existing sum(::Union{Function, Type}, ::Any) method.


You can always call reduce instead.