From ac9937db2229be16c6f689b0282a563d5b45b539 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Sat, 9 Sep 2023 15:10:08 +0200 Subject: [PATCH] Call user function only once in `mean` Use an internal type to initiate promotion instead of using the type returned by user-provided function applied to the first element. This avoid calling the function twice, which can be confusing. --- src/Statistics.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Statistics.jl b/src/Statistics.jl index 560b227d..30c154ce 100644 --- a/src/Statistics.jl +++ b/src/Statistics.jl @@ -178,7 +178,10 @@ if !isdefined(Base, :mean) """ mean(A::AbstractArray; dims=:) = _mean(identity, A, dims) + struct _InitType end + _mean_promote(x::T, y::S) where {T,S} = convert(promote_type(T, S), y) + _mean_promote(x::_InitType, y::Any) = y/1 # ::Dims is there to force specializing on Colon (as it is a Function) function _mean(f, A::AbstractArray, dims::Dims=:) where Dims @@ -188,8 +191,7 @@ if !isdefined(Base, :mean) else n = mapreduce(i -> size(A, i), *, unique(dims); init=1) end - x1 = f(first(A)) / 1 - result = sum(x -> _mean_promote(x1, f(x)), A, dims=dims) + result = sum(x -> _mean_promote(_InitType(), f(x)), A, dims=dims) if dims === (:) return result / n else