# The verbosity of dropdims…dims…dims (was: range improvement for 1.1)

**URL:** <https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428>\
**Category:** Internals & Design\
**Created:** [December 7, 2018, 12:10pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428 "2018-12-07T12:10:38Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)\
**Post date:** [December 7, 2018, 12:10pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/1 "2018-12-07T12:10:38Z")

</div>

> [@the \`range\` improvement for 1.1](https://discourse.julialang.org/t/the-range-improvement-for-1-1/18378/11):
>
> dropdims(sum(a,dims=1),dims=1)

It would be nice if this could be something like `sum(a, dims=1, drop=true)` for all functions which take dims.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 7, 2018, 12:19pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/2 "2018-12-07T12:19:35Z")

</div>

My understanding is that this would not be type stable.

---

<div class="post-metadata">

**Author:** ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)\
**Post date:** [December 7, 2018, 12:45pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/3 "2018-12-07T12:45:59Z")

</div>

I get that a generic `squeeze` function can’t be, but why would this be worse than `dropdims` itself?

Edit: Ah I see now, sorry. A keyword `drop=(2,3)` vs `drop=nothing` etc could let the type system know, but the value `drop=true` can’t. Unless all this new fancy constant propagation business can save us…

---

<div class="post-metadata">

**Author:** ![antoine-levitt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/antoine-levitt/32/4008_2.png) [@antoine-levitt](https://discourse.julialang.org/u/antoine-levitt)\
**Post date:** [December 7, 2018, 12:52pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/4 "2018-12-07T12:52:31Z")

</div>

> Perhaps you missed [https://github.com/JuliaLang/julia/pull/28708](https://github.com/JuliaLang/julia/pull/28708)

I know, and I said before it is indeed better, but still not as nice as `linspace` was. `LinRange` is a good substitution though.

> It would be nice if this could be something like `sum(a, dims=1, drop=true)` for all functions which take dims.

That would not be typestable if understood as “drop all singleton dimensions”, but if dropping only the dimensions specified by dims, with constant propagation I think that would be fine?

mbauman suggested `sum(a, squeeze=1)` (which would now perhaps be spelled `sum(a,dropdims=1)`) in [array reductions (sum, mean, etc.) and dropping dimensions · Issue #16606 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/16606) , which is a nice idea (although perhaps not very intuitive at first). StefanKarpinski suggested `dropdims(sum, a, dims=1)` which is nice and composeable, but it does lose something in translation (the main action is that I want to sum that array, not that I want to drop some dimensions, and therefore `sum` should be the first thing appearing in the expression).

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 7, 2018, 1:00pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/5 "2018-12-07T13:00:19Z")

</div>

FWIW I would go with something like

```julia
sum(A, Drop(2, 3))
sum(A, Squeeze(2, 3))

```

where `Drop` and `Squeeze` wrap a tuple with a convenience splat syntax.

---

<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:** [December 7, 2018, 1:43pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/6 "2018-12-07T13:43:30Z")

</div>

```julia
function sumdrop(a; dims, drop=false)
    s = sum(a,dims=dims)
    if drop
        return dropdims(s, dims=dims)
    end
    return s
end

function testsum(a)
    sumdrop(a,dims=2, drop=true)
end

@code_warntype testsum(randn(2,2))

Body::Union{Array{Float64,1}, Array{Float64,2}}
11 1 ── %1 = Main.sumdrop::Core.Compiler.Const(sumdrop, false) │
   │ %2 = (Base.sle_int)(1, 1)::Bool │╻╷╷╷╷ #sumdrop
   └─── goto #3 if not %2 ││┃│││ isempty
   2 ── %4 = (Base.sle_int)(1, 0)::Bool │││┃│││ iterate
   └─── goto #4 ││││┃│ iterate
   3 ── nothing │
   4 ┄─ %7 = φ (#2 => %4, #3 => false)::Bool │││││┃ iterate
   └─── goto #6 if not %7 ││││││
   5 ── invoke Base.getindex(()::Tuple{}, 1::Int64) ││││││
   └─── $(Expr(:unreachable)) ││││││
   6 ── goto #8 ││││││
   7 ── $(Expr(:unreachable)) ││││││
   8 ┄─ goto #9 │││││
   9 ── goto #10 │││╻ iterate
   10 ─ goto #11 │││
   11 ─ %16 = invoke Main.:(#sumdrop#21)(2::Int64, true::Bool, %1::Function, _2::Array{Float64,2})::Union{Array{Float64,1}, Array{Float64,2}}
   └─── goto #12 ││
   12 ─ return %16 

```

constant propagation does not seem to solve the issue in this case

---

<div class="post-metadata">

**Author:** ![antoine-levitt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/antoine-levitt/32/4008_2.png) [@antoine-levitt](https://discourse.julialang.org/u/antoine-levitt)\
**Post date:** [December 7, 2018, 1:55pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/7 "2018-12-07T13:55:18Z")

</div>

Indeed, the compiler is not clever enough to do that, too bad. Moving the arguments as positional and using `@inline` does make it infer though.

---

<div class="post-metadata">

**Author:** ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)\
**Post date:** [December 7, 2018, 2:06pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/8 "2018-12-07T14:06:00Z")

</div>

Thanks for all these. This seems pretty clean, from June I see [array reductions (sum, mean, etc.) and dropping dimensions · Issue #16606 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/16606#issuecomment-398086850)

> [@the \`range\` improvement for 1.1](https://discourse.julialang.org/t/the-range-improvement-for-1-1/18378/15):
>
> `sum(a,dropdims=1)`

This one could be a package:

> [@the \`range\` improvement for 1.1](https://discourse.julialang.org/t/the-range-improvement-for-1-1/18378/16):
>
> sum(A, Drop(2, 3))

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 7, 2018, 2:11pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/9 "2018-12-07T14:11:51Z")

</div>

> [@the \`range\` improvement for 1.1](https://discourse.julialang.org/t/the-range-improvement-for-1-1/18378/19):
>
> This one could be a package:

I agree, but I don’t have for this ATM, anyone interested should feel free to go for it.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [December 7, 2018, 5:10pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/10 "2018-12-07T17:10:25Z")

</div>

Given that `dims` is now in the function name, I could get behind a positional argument: `dropdims(A, 2)` and even `dropdims(sum, A, 2)`.

This is one of those cases where we added the `dims` keyword when it was still called `squeeze`… and then realized that `dropdims` was a better name in the first place. I’m not sure we would have ended up here had the name changed first.

---

<div class="post-metadata">

**Author:** ![yha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yha/32/3502_2.png) [@yha](https://discourse.julialang.org/u/yha)\
**Post date:** [December 7, 2018, 5:52pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/11 "2018-12-07T17:52:04Z")

</div>

I really like [this](https://github.com/JuliaLang/julia/issues/16606#issuecomment-304924412) suggestion for the syntax `a[:,sum]`.  
If `a[:,sum]` drops the dimension, then it seems to fall naturally out of the APL-style indexing rules that `a[:,[sum]]` should keep the dimension (and `a[:,[sum,median]]` should yield an m×2 matrix with a column of sums and a column of medians, though this is probably very tricky to implement efficiently for arbitrary reductions).

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [December 7, 2018, 6:04pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/12 "2018-12-07T18:04:40Z")

</div>

Yeah, it’s a cute idea but the implementation is a challenge. It’s also not clear to me that we’d want to add this kind of meaning to indexing — it’d be very different than everything else we currently support.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [December 7, 2018, 6:08pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/13 "2018-12-07T18:08:19Z")

</div>

Reading back through that thread I found [array reductions (sum, mean, etc.) and dropping dimensions · Issue #16606 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/16606#issuecomment-398086850).

I had forgotten about that idea and I still like it — except maybe the keyword shouldn’t be `squeeze`, it should be `dropdims`.

---

<div class="post-metadata">

**Author:** ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)\
**Post date:** [December 7, 2018, 6:08pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/14 "2018-12-07T18:08:55Z")

</div>

Thanks to whoever split this off, and apologies for derailing the previous thread.

The examples passing `sum` as a function seem strange to me, compared to `sum(log, A)` and `reduce(+, A, dims=2)` where the given function acts on elements, or pairs, not the array. Perhaps `A[:,+]` would be a more consistent version.

Right now `sum(A, dropdims=1)` seems very appealing, and clear – visually a small modification of `sum(A, dims=1)`.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [December 7, 2018, 6:09pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/15 "2018-12-07T18:09:52Z")

</div>

I still think the higher order function approach, i.e. `squeeze(sum, A, dims=2)` is most appealing.

---

<div class="post-metadata">

**Author:** ![roflmaostc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roflmaostc/32/30123_2.png) [@roflmaostc](https://discourse.julialang.org/u/roflmaostc)\
**Post date:** [May 20, 2022, 2:38pm UTC](https://discourse.julialang.org/t/the-verbosity-of-dropdims-dims-dims-was-range-improvement-for-1-1/18428/16 "2022-05-20T14:38:27Z")

</div>

Sorry for warming that up but in the past days I came across this.

Was there any kind of progress or style suggestion regarding that issue?
