# Array reductions (sum, mean, etc.) and abstract functions

**URL:** <https://discourse.julialang.org/t/array-reductions-sum-mean-etc-and-abstract-functions/4921>\
**Category:** Internals & Design\
**Tags:** indexing, array\
**Created:** [July 18, 2017, 10:56am UTC](https://discourse.julialang.org/t/array-reductions-sum-mean-etc-and-abstract-functions/4921 "2017-07-18T10:56:56Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![shorty66](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shorty66/32/3254_2.png) [@shorty66](https://discourse.julialang.org/u/shorty66)\
**Post date:** [July 18, 2017, 10:56am UTC](https://discourse.julialang.org/t/array-reductions-sum-mean-etc-and-abstract-functions/4921/1 "2017-07-18T10:56:56Z")

</div>

I was trying to implement what @mbauman [suggested](https://github.com/JuliaLang/julia/issues/16606#issuecomment-304924412) with respect to array reductions (sum, mean, etc.). Here is my idea at an implementation:

```julia
Base.getindex(A::Array, args::Union{T, Colon}...) where T<:Function = T(A, tuple(find((args .== T))...))

julia> A[sum,:] == sum(A, 1)
julia> A[:,mean] == mean(A, 2)

```

This has two problems:

1. Any Function could be used, not just reductions. It would be nice to be able to ‘subtype’ functions and dispatch on abstract functions like `Reduction`. I have not found any reference to abstract functions - what are your thoughts about that?

2. Calling the function using `T()` does not work, as the type of the function is e.g. `Base.#sum` and not `Base.sum`. How can i call a function only having access to its type?

---

<div class="post-metadata">

**Author:** ![jmert](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmert/32/3161_2.png) [@jmert](https://discourse.julialang.org/u/jmert)\
**Post date:** [July 18, 2017, 2:42pm UTC](https://discourse.julialang.org/t/array-reductions-sum-mean-etc-and-abstract-functions/4921/2 "2017-07-18T14:42:51Z")

</div>

Instead of trying to call `T`, you need to call `args[n]` for the appropriate argument number. A naive implementation is:

```julia
julia> Base.getindex(A::AbstractArray, args::Union{T,Colon}...) where {T<:Function} = (f=first(find(typeof.(args).==T)); args[f](A, f) )

julia> A = eye(5);

julia> A[:,sum]
5×1 Array{Float64,2}:
 1.0
 1.0
 1.0
 1.0
 1.0

```

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [July 18, 2017, 4:12pm UTC](https://discourse.julialang.org/t/array-reductions-sum-mean-etc-and-abstract-functions/4921/3 "2017-07-18T16:12:35Z")

</div>

I think it’s kind of nice that it doesn’t only work on reductions, consider, e.g., `A[diff, :] == diff(A, 1) `, similar for cumsum, cumprod etc. Thus works with @jmert implementation above.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [July 18, 2017, 4:25pm UTC](https://discourse.julialang.org/t/array-reductions-sum-mean-etc-and-abstract-functions/4921/4 "2017-07-18T16:25:05Z")

</div>

Maybe SimpleTraits.jl could be used to specify which functions are suitable to use for this kind of operation. The defined getindex method would then dispatch on that trait. All functions that operate along a dimension of an Array and produce sensible output could be added to the trait.

---

<div class="post-metadata">

**Author:** ![shorty66](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shorty66/32/3254_2.png) [@shorty66](https://discourse.julialang.org/u/shorty66)\
**Post date:** [July 18, 2017, 7:43pm UTC](https://discourse.julialang.org/t/array-reductions-sum-mean-etc-and-abstract-functions/4921/5 "2017-07-18T19:43:23Z")

</div>

Thanks for your answer. I knew that this way would work, but i think it feels a little cumbersome. The question remains: Is there a way to directly call a Function from its type?  
Why does the type contain a `#`?

---

<div class="post-metadata">

**Author:** ![jmert](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmert/32/3161_2.png) [@jmert](https://discourse.julialang.org/u/jmert)\
**Post date:** [July 18, 2017, 9:11pm UTC](https://discourse.julialang.org/t/array-reductions-sum-mean-etc-and-abstract-functions/4921/6 "2017-07-18T21:11:02Z")

</div>

> [@shorty66](#):
>
> Why does the type contain a `#`?

Because the type is not actually a constructable type, so the symbol also has the comment character to avoid letting it be typable?? (I don’t actually know, but that sounds like a not-unreasonable guess.)

> [@shorty66](#):
>
> but i think it feels a little cumbersome

Just because I was curious, I managed to get rid of the broadcasting, but it probably looks more cumbersome (though `@code_warntype` suggest it’s actually more efficient).

```julia
Base.getindex(A::AbstractArray, args::Union{T,Colon}...) where {T<:Function} = getindex(A, args)

function Base.getindex(A::AbstractArray, args::Tuple{Vararg{Union{T,Colon}}}) where T<:Function
  fn, dim = _getindex_isolatefn(A, args)
  fn(A, dim)
end

@inline function _getindex_isolatefn(A, args)
  fn, post = _ge_postfn(args...)
  n = length(args) - length(post)
  return (fn, n)
end

@inline _ge_postfn(arg::Colon, tail...) = _ge_postfn(tail...)
@inline _ge_postfn(arg::Function, tail...) = (arg, tail)

```
