julia icon indicating copy to clipboard operation
julia copied to clipboard

implement `mapreduce(f, op)` without any collection input for disambiguity

Open putianyi889 opened this issue 1 year ago • 2 comments

Although unintended (I guess), currently mapreduce(f, op) can work, returning f(). However this can easily cause ambiguity if mapreduce tries to support custom types.

For example,

julia> mapreduce(eps, +)
2.220446049250313e-16

julia> using QuasiArrays

julia> mapreduce(eps,+)
ERROR: MethodError: mapreduce(::typeof(eps), ::typeof(+)) is ambiguous.

Candidates:
  mapreduce(f, op, A::AbstractQuasiArray...; kw...)
    @ QuasiArrays C:\Users\pty\.julia\dev\QuasiArrays\src\quasireducedim.jl:142
  mapreduce(f, op, A::Union{Base.AbstractBroadcasted, AbstractArray}...; kw...)
    @ Base reducedim.jl:359

Possible fix, define
  mapreduce(::Any, ::Any)

Stacktrace:
 [1] top-level scope
   @ REPL[12]:1

putianyi889 avatar Feb 16 '24 11:02 putianyi889

The issue is that QuasiArrays is committing piracy. Vararg inputs must always consider the possibility of 0 arguments and the piracy potential it creates. I think the more durable solution is to make a PR to QuasiArrays, removing the piracy by redefining the offending signature as

function mapreduce(f, op, A::AbstractQuasiArray, B::AbstractQuasiArray...; kw...)

Also, #52631 recently removed map's 0-collection (i.e., map(f)) signature. I expect that mapreduce should follow this same lead, although perhaps there is some reason it's different and shouldn't?

mikmoore avatar Feb 16 '24 15:02 mikmoore

Also, #52631 recently removed map's 0-collection (i.e., map(f)) signature.

That's interesting to know and it will make f(A::something, B::something...) a standard way to do things. However, I still prefer to have a f() in Base. All it does is to define f as accepting at least one argument, allowing everyone else to use the shorter f(A::something...) without a problem.

putianyi889 avatar Feb 16 '24 16:02 putianyi889