# Bug in \`reverse!\`?

**URL:** <https://discourse.julialang.org/t/bug-in-reverse/35857>\
**Category:** General Usage\
**Created:** [March 11, 2020, 11:31pm UTC](https://discourse.julialang.org/t/bug-in-reverse/35857 "2020-03-11T23:31:03Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)\
**Post date:** [March 11, 2020, 11:31pm UTC](https://discourse.julialang.org/t/bug-in-reverse/35857/1 "2020-03-11T23:31:03Z")

</div>

we have

```julia
julia> reverse(1:1:2)
2:-1:1

```

but

```julia
julia> a=1:1:2
1:1:2

julia> reverse!(a)
ERROR: setindex! not defined for StepRange{Int64,Int64}
Stacktrace:
 [1] error(::String, ::Type) at ./error.jl:42
 [2] error_if_canonical_setindex(::IndexLinear, ::StepRange{Int64,Int64}, ::Int64) at ./abstractarray.jl:1082
 [3] setindex! at ./abstractarray.jl:1073 [inlined]
 [4] reverse!(::StepRange{Int64,Int64}, ::Int64, ::Int64) at ./array.jl:1524
 [5] reverse!(::StepRange{Int64,Int64}) at ./array.jl:1515
 [6] top-level scope at REPL[49]:1

```

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [March 11, 2020, 11:33pm UTC](https://discourse.julialang.org/t/bug-in-reverse/35857/2 "2020-03-11T23:33:50Z")

</div>

Ranges are not mutable types, so there’s no in-place `reverse!` for them:

```julia
julia> typeof(1:1:2).mutable
false

```

If you’re trying to use the same code on both ranges and vectors, you might be interested in [BangBang.jl](https://github.com/tkf/BangBang.jl) instead, but it doesn’t yet have a `reverse!!` method. (Maybe someone want’s to write a PR?)

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [March 11, 2020, 11:55pm UTC](https://discourse.julialang.org/t/bug-in-reverse/35857/3 "2020-03-11T23:55:30Z")

</div>

See also the lazy [`Iterators.reverse`](https://docs.julialang.org/en/v1/base/iterators/#Base.Iterators.reverse) function.

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [March 12, 2020, 12:00am UTC](https://discourse.julialang.org/t/bug-in-reverse/35857/4 "2020-03-12T00:00:07Z")

</div>

This is a case where you probably don’t need to worry about in-place operations anyway. Ranges are so light (they are like what? 3 numbers?) that it shouldn’t really make a performance difference anyway

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [March 12, 2020, 12:02am UTC](https://discourse.julialang.org/t/bug-in-reverse/35857/5 "2020-03-12T00:02:14Z")

</div>

> [@tbeason](#):
>
> This is a case where you probably don’t need to worry about in-place operations anyway. Ranges are so light (they are like what? 3 numbers?)

Note that constructing a range is not always for free or elided, even when constant propagation would normally apply. `range` is _much_ more of a hefty operation than you might think:

```julia
julia> foo() = range(1, 10, length=30)
foo (generic function with 1 method)

julia> @btime foo()
  116.499 ns (0 allocations: 0 bytes)
1.0:0.3103448275862069:10.0

julia> bar() = 1:0.01:10
bar (generic function with 1 method)

julia> @btime bar()
  166.943 ns (0 allocations: 0 bytes)
1.0:0.01:10.0

```

Not that this is relevant to the case at hand.

---

<div class="post-metadata">

**Author:** ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)\
**Post date:** [March 12, 2020, 12:02am UTC](https://discourse.julialang.org/t/bug-in-reverse/35857/6 "2020-03-12T00:02:21Z")

</div>

Thank you all. The fact is that I was using the same code for ranges and vectors. Slight uglification to need to special-case ranges.

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [March 12, 2020, 12:04am UTC](https://discourse.julialang.org/t/bug-in-reverse/35857/7 "2020-03-12T00:04:18Z")

</div>

Yea I assumed that was the case. It is a bit annoying when you run into situations like that.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [March 12, 2020, 12:05am UTC](https://discourse.julialang.org/t/bug-in-reverse/35857/8 "2020-03-12T00:05:02Z")

</div>

> [@Jean\_Michel](#):
>
> Thank you all. The fact is that I was using the same code for ranges and vectors

In this case, I’d just define

```julia
reverse!!(r::AbstractRange) = reverse(r)
reverse!!(v::AbstractVector) = reverse!(v) 

```

and use that.

---

<div class="post-metadata">

**Author:** ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)\
**Post date:** [March 12, 2020, 12:06am UTC](https://discourse.julialang.org/t/bug-in-reverse/35857/9 "2020-03-12T00:06:46Z")

</div>

Your answer makes me wonder why `Base` does not define

```julia
reverse!(r::AbstractRange) = reverse(r)

```

Edit: of course because this does not work, and your solution is also useless:

one has to write

`r=reverse!!(r)`

with your definition…

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [March 12, 2020, 12:08am UTC](https://discourse.julialang.org/t/bug-in-reverse/35857/10 "2020-03-12T00:08:38Z")

</div>

> [@Jean\_Michel](#):
>
> Your answer makes me wonder why `Base` does not define
> 
> ```julia
> reverse!(r::AbstractRange) = reverse(r)
> 
> ```

Because people might expect long range effects from mutating functions. Consider this:

```julia
julia> function foo(xs)
           reverse!!(xs)
           for x in xs
               println(x)
           end
       end

julia> foo(1:5)
1
2
3
4
5

julia> foo(collect(1:10))
5
4
3
2
1

```

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [March 12, 2020, 12:10am UTC](https://discourse.julialang.org/t/bug-in-reverse/35857/11 "2020-03-12T00:10:12Z")

</div>

> [@Jean\_Michel](#):
>
> of course because this does not work, and your solution is also useless:

I’m not sure I’d call that useless, but to each their own.

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [March 12, 2020, 12:10am UTC](https://discourse.julialang.org/t/bug-in-reverse/35857/12 "2020-03-12T00:10:24Z")

</div>

You sort of proved my point by trying to disprove it, but I do applaud the correction. I’m not saying it is free to construct a range, but I doubt that this is something most people need to worry about eliminating from their code. Operations that are non-allocating and with timings on the nanosecond scale are generally not the first place to go looking for performance improvements.
