# Automate allocation

**URL:** https://discourse.julialang.org/t/automate-allocation/56161
**Category:** New to Julia
**Tags:** question
**Created:** [February 27, 2021, 10:00pm UTC](https://discourse.julialang.org/t/automate-allocation/56161 "2021-02-27T22:00:55Z")
**Posts on this page:** 15
**Page:** 1

<div class="post-metadata">

### Author: ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)
#### Post date: [February 27, 2021, 10:00pm UTC](https://discourse.julialang.org/t/automate-allocation/56161/1 "2021-02-27T22:00:55Z")

</div>

Is it possible to automate this:

```julia
#I currently have:
y_TX, m_TX, ŷ_TX, ATT_TX, ATT_co, se_i_TX, se_t_TX = [], [], [], [], [], [], [] 
# I want something like:
y_TX, m_TX, ŷ_TX, ATT_TX, ATT_co, se_i_TX, se_t_TX = []

```

---

<div class="post-metadata">

### Author: ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)
#### Post date: [February 27, 2021, 10:11pm UTC](https://discourse.julialang.org/t/automate-allocation/56161/2 "2021-02-27T22:11:07Z")

</div>

You can do:

```julia
y_TX, m_TX, ŷ_TX, ATT_TX, ATT_co, se_i_TX, se_t_TX = ntuple(_ -> [], 7)

```

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [February 27, 2021, 10:11pm UTC](https://discourse.julialang.org/t/automate-allocation/56161/3 "2021-02-27T22:11:13Z")

</div>

You can do something like

```julia
a, b, c = ([] for _ in 1:3)

```

Be careful, because that way the arrays are of type Any, thus inefficient.

---

<div class="post-metadata">

### Author: ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)
#### Post date: [February 27, 2021, 10:16pm UTC](https://discourse.julialang.org/t/automate-allocation/56161/4 "2021-02-27T22:16:20Z")

</div>

Thanks but I keep adding new variables as I write, is it possible to do something like

```julia
a, b, c = ([] for _ in 1:end)

```

---

<div class="post-metadata">

### Author: ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)
#### Post date: [February 27, 2021, 10:26pm UTC](https://discourse.julialang.org/t/automate-allocation/56161/5 "2021-02-27T22:26:04Z")

</div>

You could just pick a really big upper bound, only the elements of the iterator you actually use will be created:

```julia
a, b, c = ([] for _ in 1:1000)
a, b, c, d = ([] for _ in 1:1000)
a, b, c, d, e = ([] for _ in 1:1000)
# etc...

```

---

<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: [February 27, 2021, 11:22pm UTC](https://discourse.julialang.org/t/automate-allocation/56161/6 "2021-02-27T23:22:48Z")

</div>

Could use `Iterators.repeated` here:

```julia
julia> using .Iterators: repeated

julia> a, b, c = repeated([]);

julia> a
Any[]

julia> b
Any[]

julia> c
Any[]

```

---

<div class="post-metadata">

### Author: ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)
#### Post date: [February 27, 2021, 11:30pm UTC](https://discourse.julialang.org/t/automate-allocation/56161/7 "2021-02-27T23:30:05Z")

</div>

That just repeats the same object though, using the comprehension makes independent `[]`'s.

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [February 27, 2021, 11:30pm UTC](https://discourse.julialang.org/t/automate-allocation/56161/8 "2021-02-27T23:30:44Z")

</div>

```julia
julia> using .Iterators: repeated

julia> a, b, c = repeated([]);

julia> push!(a, 2)
1-element Array{Any,1}:
 2

julia> b
1-element Array{Any,1}:
 2

```

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [February 27, 2021, 11:40pm UTC](https://discourse.julialang.org/t/automate-allocation/56161/9 "2021-02-27T23:40:11Z")

</div>

If you do not mind a new struct type:

```julia
struct OnRepeat{F}
    f :: F
end

function Base.iterate(o :: OnRepeat{F}, s :: Nothing = nothing) where {F}
    return o.f(), nothing
end

a, b, c = OnRepeat(() -> [])

```

And now you can use `OnRepeat` with any function taking no arguments and returning the new object you want.

---

<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: [February 27, 2021, 11:46pm UTC](https://discourse.julialang.org/t/automate-allocation/56161/10 "2021-02-27T23:46:48Z")

</div>

good catch!

---

<div class="post-metadata">

### Author: ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)
#### Post date: [February 28, 2021, 12:19am UTC](https://discourse.julialang.org/t/automate-allocation/56161/11 "2021-02-28T00:19:28Z")

</div>

I’ve sometimes defined a macro to help with this exact scenario,

```julia
macro repeated(x)
    :(($(esc(x))) for _ in Iterators.repeated(nothing))
end

```

then you can do

```julia
a, b, c = @repeated([])

```

I think I even proposed adding this to Base.Iterators but there were some valid concerns which I forget the details of now though.

---

<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: [February 28, 2021, 12:33am UTC](https://discourse.julialang.org/t/automate-allocation/56161/12 "2021-02-28T00:33:56Z")

</div>

could also just do

```julia
copy_repeated(x) = (copy(x) for x in Iterators.repeated(x))

```

then

```julia
julia> a, b, c = copy_repeated([])
Base.Generator{Base.Iterators.Repeated{Vector{Any}}, typeof(copy)}(copy, Base.Iterators.Repeated{Vector{Any}}(Any[]))

julia> push!(a, 1)
1-element Vector{Any}:
 1

julia> b
Any[]

```

(or `Iterators.map(copy, repeated(x))` if you’re on 1.6+

---

<div class="post-metadata">

### Author: ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)
#### Post date: [June 9, 2021, 6:02pm UTC](https://discourse.julialang.org/t/automate-allocation/56161/13 "2021-06-09T18:02:44Z")

</div>

There are some issues w/ some of the methods proposed above.

**Method 1** :

> [@lmiq](#):
>
> `a, b, c = ([] for _ in 1:3)`

```julia
julia> zs = zeros(3)
3-element Vector{Float64}:
 0.0
 0.0
 0.0

julia> a, b, c = (zs for _ in 1:100)
Base.Generator{UnitRange{Int64}, var"#33#34"}(var"#33#34"(), 1:100)

julia> a, b, c, zs
([0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])

julia> b = ones(3)
3-element Vector{Float64}:
 1.0
 1.0
 1.0

julia> a, b, c, zs # only b is changed
([0.0, 0.0, 0.0], [1.0, 1.0, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])

julia> a[1:2] = ones(2) 
2-element Vector{Float64}:
 1.0
 1.0

julia> a, b, c, zs # a, c, zs are changed, but not b. Why?
([1.0, 1.0, 0.0], [1.0, 1.0, 1.0], [1.0, 1.0, 0.0], [1.0, 1.0, 0.0])

```

When I change `b` to a new vector, only b is changed, while `a, c, zs` are unchanged.  
When I change _some elements_ of `a` to a new vector, then `a, c, zs` are all changed in the same way, while `b` is unchanged.

**Method 2** :

> [@Mason](#):
>
> `copy_repeated(x) = (copy(x) for x in Iterators.repeated(x))`

```julia
julia> copy_repeated(x) = (copy(x) for x in Iterators.repeated(x))
copy_repeated (generic function with 1 method)

julia> zs = zeros(3)
3-element Vector{Float64}:
 0.0
 0.0
 0.0

julia> a, b, c = copy_repeated(zs)
Base.Generator{Base.Iterators.Repeated{Vector{Float64}}, typeof(copy)}(copy, Base.Iterators.Repeated{Vector{Float64}}([0.0, 0.0, 0.0]))

julia> a, b, c, zs
([0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])

julia> b = ones(3)
3-element Vector{Float64}:
 1.0
 1.0
 1.0

julia> a, b, c, zs # only b is changed
([0.0, 0.0, 0.0], [1.0, 1.0, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])

julia> a[1:2] = ones(2) 
2-element Vector{Float64}:
 1.0
 1.0

julia> a, b, c, zs # only a is changed
([1.0, 1.0, 0.0], [1.0, 1.0, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])

```

@Mason’s method gives me what I expected.

Q: is the behavior of the 1st method `a, b, c = (zs for _ in 1:100)` as intended?

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [June 9, 2021, 6:13pm UTC](https://discourse.julialang.org/t/automate-allocation/56161/14 "2021-06-09T18:13:34Z")

</div>

> [@Albert\_Zevelev](#):
>
> ```julia
> julia> b = ones(3)
> 3-element Vector{Float64}:
> 1.0
> 1.0
> 1.0
> 
> ```

Here you assigned `b` to be a new vector of ones. If you wanted to mutate the vector that was there, you must use ` b .= 1`, or `b[1] = 1`, etc.:

```julia
julia> zs = zeros(3);

julia> a, b, c = (zs for _ in 1:3)
Base.Generator{UnitRange{Int64}, var"#1#2"}(var"#1#2"(), 1:3)

julia> a
3-element Vector{Float64}:
 0.0
 0.0
 0.0

julia> a[1] = 1
1

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

```

Ah, I see you already noted that. Yes, that is the expected behavior. If you don’t want the vectors to be the same, you need to copy them:

```julia
julia> a, b, c = (copy(zs) for _ in 1:3)
Base.Generator{UnitRange{Int64}, var"#3#4"}(var"#3#4"(), 1:3)

julia> a
3-element Vector{Float64}:
 1.0
 0.0
 0.0

julia> a[1] = 2
2

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

```

---

<div class="post-metadata">

### Author: ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)
#### Post date: [June 9, 2021, 6:18pm UTC](https://discourse.julialang.org/t/automate-allocation/56161/15 "2021-06-09T18:18:55Z")

</div>

Yes.  
We talked about [assignment vs copy here](https://discourse.julialang.org/t/is-it-worth-introducing-copy-into-learnxiny/55965).

I brought this up in case future users come to this thread, so the diff betw the following is clear:

```julia
a, b, c = (zs for _ in 1:3)
a, b, c = (copy(zs) for _ in 1:3)

a, b, c = (copy(zs) for i in Iterators.repeated(zs))

```
