# Why there is no in-place \`map!\` on arrays?

**URL:** <https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956>\
**Category:** Internals & Design\
**Tags:** map\
**Created:** [September 29, 2022, 1:34am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956 "2022-09-29T01:34:55Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [September 29, 2022, 1:34am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/1 "2022-09-29T01:34:55Z")

</div>

I am wondering why we could not have a in-place `map!` so that the `destination` and the `source` are the same:

```julia
julia> a = [1, 2, 3];

julia> map!(-, a)
3-element Vector{Int64}:
 -1
 -2
 -3

```

I am using this pattern a lot and really hope we can have one. I suppose I am [not the only one](https://discourse.julialang.org/t/in-place-map/47464). What might block this design?

---

<div class="post-metadata">

**Author:** ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)\
**Post date:** [September 29, 2022, 1:45am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/2 "2022-09-29T01:45:05Z")

</div>

You can technically just do `map!(-,a,a)` which does work. But might have issues with aliasing.

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [September 29, 2022, 1:47am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/3 "2022-09-29T01:47:02Z")

</div>

> But might have issues with aliasing.

Could you please elaborate a little on what “issues with aliasing” means? I sometimes have a long variable name `aVeryLongVariableName` and it is ugly to write:

```julia
map!(f, aVeryLongVariableName, aVeryLongVariableName)

```

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [September 29, 2022, 1:49am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/4 "2022-09-29T01:49:53Z")

</div>

I believe that you might be free to define `map!(op, a) = map!(op, a, a)`?

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [September 29, 2022, 1:50am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/5 "2022-09-29T01:50:08Z")

</div>

I think type stability is the issue—what if you have an array of floats but `f` returns a string?

For `-` you can use `a[:] *= -1`.

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [September 29, 2022, 1:51am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/6 "2022-09-29T01:51:40Z")

</div>

That is what I am doing now. But if I want to use it a lot, it seems overkilling to write a package just about `map!`. And I am not sure if it is type piracy.

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [September 29, 2022, 1:52am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/7 "2022-09-29T01:52:37Z")

</div>

> For `-` you can use `a[:] *= -1` .

This is just an example, I usually have more complicated functions to map on an array.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [September 29, 2022, 1:55am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/8 "2022-09-29T01:55:19Z")

</div>

Possibly. Call it `map1!` then?

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [September 29, 2022, 1:56am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/9 "2022-09-29T01:56:48Z")

</div>

[Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp) suggested [`mapinto!`](https://discourse.julialang.org/t/in-place-map/47464/4). I think it is better.

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [September 29, 2022, 2:02am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/10 "2022-09-29T02:02:56Z")

</div>

> I think type stability is the issue—what if you have an array of floats but `f` returns a string?

I think `map!` already checks that?

```julia
julia> a = [1, 2, 3];

julia> map!(sin, a, a)
ERROR: InexactError: Int64(0.8414709848078965)
Stacktrace:
 [1] Int64
   @ ./float.jl:788 [inlined]
 [2] convert
   @ ./number.jl:7 [inlined]
 [3] setindex!
   @ ./array.jl:966 [inlined]
 [4] map!(f::typeof(sin), dest::Vector{Int64}, A::Vector{Int64})
   @ Base ./abstractarray.jl:2927
 [5] top-level scope
   @ REPL[2]:1

julia> map!(string, a, a)
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Int64
Closest candidates are:
  convert(::Type{T}, ::Ptr) where T<:Integer at pointer.jl:23
  convert(::Type{T}, ::T) where T<:Number at number.jl:6
  convert(::Type{T}, ::Number) where T<:Number at number.jl:7
  ...
Stacktrace:
 [1] setindex!(A::Vector{Int64}, x::String, i1::Int64)
   @ Base ./array.jl:966
 [2] map!(f::typeof(string), dest::Vector{Int64}, A::Vector{Int64})
   @ Base ./abstractarray.jl:2927
 [3] top-level scope
   @ REPL[3]:1

```

So I just do `mapinto!(f, arg) = map!(f, arg, arg)`.

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [September 29, 2022, 2:49am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/11 "2022-09-29T02:49:22Z")

</div>

> [@singularitti](#):
>
> Could you please elaborate a little on what “issues with aliasing” means?

I think this is referring to [`broadcast!(f, x, x)` slower, prevents SIMD? · Issue #43153 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/43153), but according to [`map!` does not check for aliasing · Issue #46352 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/46352) that shouldn’t be an issue for `map!`.

> [@singularitti](#):
>
> I sometimes have a long variable name `aVeryLongVariableName` and it is ugly to write

```julia
let tmp = aVeryLongVariableName
   map!(f, tmp, tmp)
end

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [September 29, 2022, 3:06am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/12 "2022-09-29T03:06:32Z")

</div>

> [@singularitti](#):
>
> Could you please elaborate a little on what “issues with aliasing” means?

```julia
julia> a = collect(1:10)

julia> map(-, view(a, 7:-1:3))
5-element Vector{Int64}:
 -7
 -6
 -5
 -4
 -3

julia> map!(-, view(a, 1:5), view(a, 7:-1:3));

julia> a
10-element Vector{Int64}:
 -7
 -6
 -5
 -4
  5
  6
  7
  8
  9
 10

```

something like this; the overlapping cause incorrect result but we don’t have alias checking so `map!()` didn’t error

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [September 29, 2022, 4:57am UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/13 "2022-09-29T04:57:25Z")

</div>

> [@maxkapur](#):
>
> For `-` you can use `a[:] *= -1`.

This creates _two_ unnecessary temporary arrays, and traverses `a` three times instead of once. Instead use `a .*= -1`.

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [September 29, 2022, 7:57pm UTC](https://discourse.julialang.org/t/why-there-is-no-in-place-map-on-arrays/87956/14 "2022-09-29T19:57:20Z")

</div>

See [Proposal to use map!(f,A) for in place modification of collections · Issue #31677 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/31677).
