Description
The reduce
function should, according to its docstring, "reduce the given collection with the given binary operator." I believe this is also what most programmers would expect a reduce
function to do.
However, this is not always what it does. Some input types, e.g. Int32
are converted before the operator is applied. This can lead to unexpected results.
julia> my_op(a::Int32,b::Int32) = max(a,b)
my_op (generic function with 1 method)
julia> reduce(my_op, ones(Int32,42))
ERROR: MethodError: no method matching my_op(::Int64, ::Int64)
in mapreduce_impl(::Base.#identity, ::#my_op, ::Array{Int32,1}, ::Int64, ::Int64, ::Int64) at ./reduce.jl:101
in _mapreduce(::Base.#identity, ::#my_op, ::Base.LinearFast, ::Array{Int32,1}) at ./reduce.jl:168
in mapreduce(::Function, ::Function, ::Array{Int32,1}) at ./reduce.jl:175
in reduce(::Function, ::Array{Int32,1}) at ./reduce.jl:179
The exact same problem occurs with mapreduce(identity, my_op, ones(Int32,42))
.
I realize that using an accumulator that is wider than the input could be beneficial in some special circumstances, such as if the sum
function didn't exist and one wanted to create it using reduce(+, ...)
without risking integer overflow. But in those cases one could supply a v0
argument of the desired return type (or there could be an optional accumulator_type
argument).