# Swap array contents?

**URL:** <https://discourse.julialang.org/t/swap-array-contents/7774>\
**Category:** General Usage\
**Created:** [December 14, 2017, 9:19pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774 "2017-12-14T21:19:40Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [December 14, 2017, 9:19pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/1 "2017-12-14T21:19:40Z")

</div>

I wanted to ask whether julia arrays support something like C++ vector swap.

That is, swap!(A,B) should swap the contents of both arrays A,B, and throw if they don’t have the same type (essentially swap sizes and data-pointers of the arrays).

I think that this can only be done either by horribly abusing pointers, or by some ccall into the runtime (I did not find it in array.c nor array.jl, but maybe I’m blind?).

Does such functionality exist in some corner of the runtime?

Is there a fundamental reason why this cannot be made to work? If I have pointer-arrays of different age, then I need to possibly root the young one; if shared, then maybe just give up and throw?

(while I am not opposed to horribly abusing pointers, this specific case probably wants to be written in C and either linked against the runtime or included in array.c)

(adding another layer of indirection by wrapping array does not cut the cake, nor does copying the contents)

---

<div class="post-metadata">

**Author:** ![favba](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/favba/32/2735_2.png) [@favba](https://discourse.julialang.org/u/favba)\
**Post date:** [December 14, 2017, 9:58pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/2 "2017-12-14T21:58:00Z")

</div>

Maybe I’m being really naive, but is this what you want?

```julia
julia> macro swap!(a::Symbol,b::Symbol)
       blk = quote
         if typeof($(esc(a))) != typeof($(esc(b)))
           throw(ArgumentError("Arrays of different type"))
         else
             c = $(esc(a))
             $(esc(a)) = $(esc(b))
             $(esc(b)) = c
           end
         end
         return blk 
       end
@swap! (macro with 1 method)

julia> a = zeros(10);

julia> b = ones(10);

julia> @swap!(a,b);

julia> a
10-element Array{Float64,1}:
 1.0
 1.0
 1.0
 1.0
 1.0
 1.0
 1.0
 1.0
 1.0
 1.0

julia> b
10-element Array{Float64,1}:
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0

julia> c = zeros(Int,10);

julia> @swap!(a,c)
ERROR: ArgumentError: Arrays of different type

```

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [December 14, 2017, 10:08pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/3 "2017-12-14T22:08:58Z")

</div>

@favba your method just swaps the _names_ `a` and `b`, while I think that @foobar_lv2 is trying to swap their contents. The difference is noticeable if you have other bindings to the two arrays:

```julia
julia> a = zeros(2);

julia> b = ones(2);

julia> c = (a, b)
([0.0, 0.0], [1.0, 1.0])

julia> @swap!(a, b);

julia> c # unchanged, because all the `@swap!` macro did was change the bindings "a" and "b"
([0.0, 0.0], [1.0, 1.0])
```

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [December 14, 2017, 10:31pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/4 "2017-12-14T22:31:28Z")

</div>

(to follow up, I don’t actually know how to do what’s being requested, except by actually copying the data around).

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [December 14, 2017, 10:42pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/5 "2017-12-14T22:42:35Z")

</div>

~~Something that makes me slightly nervous is that I know of no way at all of mutating the sizes or relocating the data of an array with more than one dimension.~~

I could not see this assumption used anywhere, but I must confess that I don’t understand the other relevant parts of the code (gc, inference, codegen) where this could be hidden.

reshape / jl\_reshape\_array changes sizes. If it works without bugs now, then no one should assume that multi-dim arrays have fixed sizes.

Meh, no idea. I should read more code.

---

<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:** [December 14, 2017, 11:18pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/6 "2017-12-14T23:18:33Z")

</div>

Just to make this absolutely clear—you mean neither of these two options?

```julia
# option 1, swap name
a, b = b, a 

```

```julia
# option 2, copy over contents
function swap!(a, b)
    # check eltype and size ...
    for i in eachindex(a, b)
        @inbounds a[i], b[i] = b[i], a[i]
    end
end

```

---

<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:** [December 14, 2017, 11:21pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/7 "2017-12-14T23:21:50Z")

</div>

BTW, is it conceivably possible to make this work?

```julia
a, b .= b, a

```

It’s an error now.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 14, 2017, 11:41pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/8 "2017-12-14T23:41:49Z")

</div>

> [@foobar\_lv2](#):
>
> I wanted to ask whether julia arrays support something like C++ vector swap.

Yes. It’s just `a, b = b, a`.

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [December 14, 2017, 11:47pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/9 "2017-12-14T23:47:46Z")

</div>

Nope; I have references to my arrays scattered all over the place, and iterating over the entries… works, but I imagine being a poor CPU who has to move all this data instead of just flipping a pointer, and going on strike?

Something that works, but is also quite wasteful (extra indirection on access) is

```julia
mutable struct arraywrap{T,N}
contents::Array{T,N}
end

function swap!(a,b)
c = b.contents
b.contents=a.contents
a.contents=c
end

```

@yuyichao That swaps the binding only, not the contents. Basically I want to swap pointers and sizes.

```julia
a = collect(1:2);
b = collect(3:4);
c = (a,b)
([1, 2], [3, 4])
a,b = b,a ;
c
([1, 2], [3, 4])

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 14, 2017, 11:57pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/10 "2017-12-14T23:57:28Z")

</div>

> [@foobar\_lv2](#):
>
> That swaps the binding only

And that’s exactly what’s corresponds to swap in c++. C++ and julia has completely different object models. In general, please have a good understanding of the difference between c++ and julia variables before asking these questions…

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [December 15, 2017, 12:25am UTC](https://discourse.julialang.org/t/swap-array-contents/7774/11 "2017-12-15T00:25:28Z")

</div>

In how far? Array is not an immutable container (with mutable contents), but rather a mutable container (push!/pop!/resize!, not reshape (I misread the code, sorry; reshape builds a new container for the old contents)).

And in C++, this is exactly what happens: If I swap contents of two vectors (using a.swap(b)), then this content-swap is reflected in all references to the vector that are stored someplace, e.g. below in the call stack. And I pay one indirection for this convenience (vector is like elem\_type \*\*, not elem\_type \*, just like in julia)

Sometimes you want changes to the container like resize!/push!/pop! to propagate through all existing references. Same for content-swaps.

Also, sorry for pissing you off somehow?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 15, 2017, 1:07am UTC](https://discourse.julialang.org/t/swap-array-contents/7774/12 "2017-12-15T01:07:48Z")

</div>

> [@foobar\_lv2](#):
>
> And in C++, this is exactly what happens: If I swap contents of two vectors (using a.swap(b)), then this content-swap is reflected in all references to the vector that are stored someplace, e.g. below in the call stack.

As I understand it, the closest equivalent of this in Julia is currently to declare a type like:

```julia
mutable struct WrapArray{T,N} <: AbstractArray{T,N}
    a::Array{T,N}
end

```

that wraps around an array `a`. You would then have to define `size`, `getindex`, etcetera methods on `WrapArray` (which simply pass through and call the same methods on the field `a`), so that it acts like an array.

Then you could define:

```julia
function swap!(x::WrapArray{T,N}, y::WrapArray{T,N}) where {T,N}
    x.a, y.a = y.a, x.a
    return x, y
end

```

Since this is a mutable type, the changes to the contents of `x` and `y` would be reflected in all references to those objects elsewhere. As you point out, above, though, this adds an extra indirection to array accesses.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 15, 2017, 1:13am UTC](https://discourse.julialang.org/t/swap-array-contents/7774/13 "2017-12-15T01:13:16Z")

</div>

In principle, I suppose it would be possible to define such a copy-free `swapstorage!` function for the built-in `Array` type, since under the hood this is just a [C `struct` that contains a pointer to the underlying data](https://github.com/JuliaLang/julia/blob/1f33cddf9d40fd754e1738429998afd35546b2fe/src/julia.h#L153-L172). I’m not sure if that would screw up any compiler or gc assumptions? Since `resize!` can already change the underlying data pointer, I don’t see why you couldn’t in principle have a `swapstorage!` function for two `Array{T,N}` objects too.

(You’d have to implement such a function in C, though, since it would need to munge internals of the built-in `Array` type, which is one of the few Julia types whose innards are implemented in C.)

---

<div class="post-metadata">

**Author:** ![simonbyrne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simonbyrne/32/19_2.png) [@simonbyrne](https://discourse.julialang.org/u/simonbyrne)\
**Post date:** [December 15, 2017, 1:39am UTC](https://discourse.julialang.org/t/swap-array-contents/7774/14 "2017-12-15T01:39:17Z")

</div>

> [@DNF](#):
>
> BTW, is it conceivably possible to make this work?
> 
> a, b .= b, a
> 
> It’s an error now.

You just need to define the appropriate method:

```julia
function Base.broadcast!(::typeof(identity), ta::Tuple{A1,A2}, tb::Tuple{B1,B2}) where {A1,A2,B1,B2}
    ta1, ta2 = ta
    tb1, tb2 = tb
    @assert indices(ta1) == indices(ta2) == indices(tb1) == indices(tb2)
    for i in eachindex(ta1)
        @inbounds ta1[i], ta2[i] = tb1[i], tb2[i]
    end
    ta
end

```

I’m not saying we should do this though, for one thing this is a different behaviour of broadcasting over tuples than we usually use (which is why it errors).

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [December 15, 2017, 12:18pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/15 "2017-12-15T12:18:58Z")

</div>

> [@stevengj](#):
>
> (You’d have to implement such a function in C, though, since it would need to munge internals of the built-in Array type, which is one of the few Julia types whose innards are implemented in C.)

Not necessarily (although that would be a lot safer). You can get a pointer to the array object, and fiddle with underlying C structure, using `unsafe_*` calls in Julia.

Edit: if either of the arrays store their data in-line though, I see it might not be possible unless the allocated sizes are the same.

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [December 15, 2017, 12:40pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/16 "2017-12-15T12:40:05Z")

</div>

Yes, I could do

```julia
function terrible_swap!(A::Array{T,N}, B::Array{T,N}) where {T,N}
    swapspace = zero(UInt64)
    aptr = reinterpret(Ptr{UInt64}, pointer_from_objref(A))
    bptr = reinterpret(Ptr{UInt64}, pointer_from_objref(B))
    for i = 1:8 
        swapspace = unsafe_load(aptr, i)
        unsafe_store!(aptr, unsafe_load(bptr, i) , i)
        unsafe_store!(bptr, swapspace, i)
    end
    nothing
end

A = collect(1:2);
B = collect(3:4);
c = (A,B)
@show c
terrible_swap!(A,B)
@show c

c = ([1, 2], [3, 4])
c = ([3, 4], [1, 2])

```

That has the chance of terribly crashing the garbage collector down the road, though (and probably fails if the array is very high-dimensional).

I think arrays never store their data inline?

```julia
A=collect(1:2)
 pointer(A)-pointer_from_objref(A)
0x0000000000000040

```

This would be really cool for very small arrays, though (save the allocation, save the cache-miss), but would probably need a lot of changes.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 15, 2017, 12:47pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/17 "2017-12-15T12:47:03Z")

</div>

> [@foobar\_lv2](#):
>
> pointer(A)-pointer\_from\_objref(A)  
> 0x0000000000000040

You’ve just seen the evidence that they do.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [December 15, 2017, 1:17pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/18 "2017-12-15T13:17:55Z")

</div>

For the ones stored inline, it would be possible (if the sizes were compatible), to swap all of the contents,  
as well as the flags, (but not the pointer!).  
I suppose if you had incompatible sizes, it still could be handled, but it looks like the best approach if this functionality is really useful (I have’t thought of a use case myself), is to make a PR with a C function in Julia,  
and a Julia wrapper to call it.

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [December 15, 2017, 1:57pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/19 "2017-12-15T13:57:01Z")

</div>

> You’ve just seen the evidence that they do.

I stand corrected. Thank you!

(I misunderstood _new\_array_ and thought this very nice placement was due to both being pool-allocs directly after each other; you are absolutely correct and I failed at reading comprehension)

Re inline: Sorry for using the wrong words. The thing I was thinking about is that an empty vector still has some bytes of capacity in the same cache-line as the struct, so Vector{T}() could start with capacity (64-sizeof(array))/elsize.  
Nice if I have a Vector of Vectors, initially all empty, that I push! into, e.g. for n-ary trees with vector of children, first few pushes would not need to allocate / fragment the heap, most vectors are empty (leaf nodes) or small.

@ScottPJones I’ll see. If I write a proper swap in C, then I am sure make a PR; I just need to think a little about possible subtleties: Is something shared? What do I do if the arrays are not inline (jl\_gc\_alloc) but malloced (jl\_gc\_managed\_malloc, jl\_gc\_track\_malloced\_array)? Are there other possible gotchas? What if one of the arrays is a wrap around externally allocated data? Do I really understand all the possible flags?

And then see whether it is worth the effort (alternatives are: copy the data if small or swap is used rarely, wrap the array, redesign until swap is not needed anymore).

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [December 15, 2017, 2:33pm UTC](https://discourse.julialang.org/t/swap-array-contents/7774/20 "2017-12-15T14:33:48Z")

</div>

> [@foobar\_lv2](#):
>
> Nice if I have a Vector of Vectors, initially all empty, that I push! into, e.g. for n-ary trees with vector of children, first few pushes would not need to allocate / fragment the heap, most vectors are empty (leaf nodes) or small.

One technique I’ve had to use, because Julia’s `Vector`s are very expensive memory wise, is to have a constant `empty_vector` (of whatever type I need), and then use that instead of Vector{T}() to initialize.  
Then, when I push, I check first if `v === empty_vector`, and if so, only at that point create a new vector with the element being added, i.e. `[element]`.

One nice thing about this technique is that it’s very easy to initialize a `Vector` of `Vector`s with `fill!`.

[Next page](https://discourse.julialang.org/t/swap-array-contents/7774.md?page=2)
