# How to define many variables in few lines?

**URL:** <https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788>\
**Category:** General Usage\
**Created:** [August 4, 2021, 6:38am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788 "2021-08-04T06:38:48Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 4, 2021, 6:38am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/1 "2021-08-04T06:38:49Z")

</div>

I am very grateful that learned from many guys here that, there is a trick to ‘lock’ the type of a variable by doing a const + Ref trick.  
Now, if I have many variables, say 100 variables, how to define them in as few lines as possible?  
I mean, do I have to do things like,

```
const a1 = Ref{Float64}(1.0)
const a2 = Ref{Float64}(1.0)
...
const a100 = Ref{Float64}(1.0)

```

1. But that requires 100 lines, is there a way to write them in as few lines as possible?  
I mean, I would like all the Float64 in a block, all the Int64 in a block, all the strings in a block, etc. But anyway, hopefully there is no need to write 100 lines. Because that will make the code somewhat looks like Fortran.

2. Besides, is there a way, in the above Ref trick, I can leave the value of each const variables as undefined instead of manually give them a value like 1.0?

Thanks in advance!

---

<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:** [August 4, 2021, 6:49am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/2 "2021-08-04T06:49:49Z")

</div>

This does not seem like a good idea. Whenever you are generating a bunch of `a1`, `a2`, etc. variables, it’s a sure sign that you should be using a vector instead.

Why do you need this?

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 4, 2021, 6:59am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/3 "2021-08-04T06:59:25Z")

</div>

Thank you!

a1,a2 are just names, they do not need to be ordered and named like vector.  
Like it can be any variable. Like in a Fortran code, at the top of a module, I can define things like

```
integer(kind=i8), private, save :: imode,iter,itermax &
                                  ,msample,mgauss,mgauss_tot,mgauss_max,mgauss_min,nsub,mi,mitot,dim_p,kmix 
real(kind=r8), private, save :: tsum,mu1,sig1,mu2,sig2,muV,SigV,w1,w2,sig,sig_inv,sigsq2_inv,D &
							   ,normpdf_factor_pYq_i,log_normpdf_factor_pYq_i,sigma_factor

```

If in Julia I need to define them as const … = Ref{…}(…), I need many many lines. But in Fortran it is only two blocks.

---

<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:** [August 4, 2021, 7:02am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/4 "2021-08-04T07:02:45Z")

</div>

Maybe something like this:

```julia
(a,b,c,d,e) = (Ref{Float64}(1.0) for _ in 1:5)

```

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 4, 2021, 7:09am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/5 "2021-08-04T07:09:51Z")

</div>

Great thank you!  
Do I have to give them a value like (1.0)?  
Is it possible to do things like (undef) so that I do not need to give them an initial value?

In

```
(a,b,c,d,e) = (Ref{Float64}(1.0) for _ in 1:5)

```

it seems I still need to manually count the number of variables. Is there a way to automatically loop over all variables instead of explicitly do 1:5?

Sorry if the questions are stupid.

---

<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:** [August 4, 2021, 7:12am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/6 "2021-08-04T07:12:36Z")

</div>

Doesn’t look like it. I don’t normally use `Ref`, except around broadcasting. Maybe you can use `NaN`, at least for floats.

It seems like you want to declare them as `const`, though, and then you shouldn’t go around changing their values.

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [August 4, 2021, 7:20am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/7 "2021-08-04T07:20:40Z")

</div>

> [@CRquantum](#):
>
> Do I have to give them a value like (1.0)?

No, `Ref{Float64}()` creates an undefined reference but then the compiler has to add a check on each access to it.

> [@CRquantum](#):
>
> it seems I still need to manually count the number of variables. Is there a way to automatically loop over all variables instead of explicitly do 1:5?

You may set a ridiculously large number as the upper limit, Julia will only take as many as there are elements on the left-hand side.

That said, mutable globals is a code smell overall. For immutable globals, a named tuple would be a cleaner syntax:

```julia
const GLOBALS = (a = 2, greeting = "Hello", ...)

```

Reiterating a question from @DNF, _are you sure you absolutely need the mutable globals?_

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [August 4, 2021, 7:50am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/8 "2021-08-04T07:50:32Z")

</div>

You can use metaprogramming:

```julia
for i = 1:100
    var_name = Symbol("a", i)
    @eval $var_name = Ref{Float64}(1.0)
end

```

But I agree with the other posters that this is probably not a good idea.

Edit:  
`x = Ref{Float64}()` initializes x with an undefined (i.e. arbitrary, not reproducable) value. But this is dangerous.  
An alternative would be to explicitly use missing: `x = Ref{Union{Float64, Missing}}(missing)`

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 4, 2021, 8:24am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/9 "2021-08-04T08:24:33Z")

</div>

Not really sure if I need mutable global actually.  
I am a Fortran guy and I am new to Julia.  
I am just translating my Fortran code to Julia.

In my Fortran code, I have modules, in the modules I have some variables and arrays defined at the top, which looks like the global stuff in Julia. Like below,

```
module step
use constants
use mixture
use formats
implicit none 
real(kind=r8), private, allocatable, save :: Yji(:,:),t(:)
integer(kind=i8), private, save :: imode,iter,itermax &
                                  ,msample,mgauss,mgauss_tot,mgauss_max,mgauss_min,nsub,mi,mitot,dim_p,kmix 
real(kind=r8), private, save :: tsum,mu1,sig1,mu2,sig2,muV,SigV,w1,w2,sig,sig_inv,sigsq2_inv,D &
							   ,normpdf_factor_pYq_i,log_normpdf_factor_pYq_i,sigma_factor
real(kind=r8), private, allocatable, save :: LL_iter(:),muk_iter(:,:),sigk_iter(:,:) &
											,muV_iter(:,:),sigV_iter(:,:),wk_iter(:,:),sigma_iter(:) &
											,mukerror_iter(:,:),sigkerror_iter(:,:) &
											,muVerror_iter(:,:),sigVerror_iter(:,:),sigmaerror_iter(:) &
											,ar_gik(:),ar_gik_k(:,:) &
											,thetas(:,:,:),thetaspr(:,:,:) &
											,norm(:),norm_sig(:),normerr(:),log_norm(:) &
											,pYq_ikm(:,:,:),hi_diag(:,:,:,:),yimhi(:,:,:,:) &
											,pYq_km(:,:),log_pYq_km(:,:),h_diag(:,:,:),ymh(:,:,:) &
											,pYq_ikm_o(:,:,:)

real(kind=r8), private, allocatable, save ::wnow(:),log_wnow(:),nik(:,:),nik_sig(:,:),wknik(:,:),wknik_sig(:,:),tauik(:,:) 
integer(kind=i8), private, allocatable, save :: isub_Metroplis_gik_all(:,:),mgauss_ik(:,:)
...
contains

subroutine initialization(...)
blablabla
end 

subroutine A(...)
...
end
subroutine B(...)
...
end
subroutine C(...)
...
end
...
... 
end module step

```

All those r8 and i8 variables and allocable arrays are stored in the module, and their values can change. So that in my Fortran code, I do not need to put every of them in the arguments of any function.

But it seems in Julia, as many guys pointed out, people don’t do such things.  
My Fortran code cannot be translated into Julia in a ‘raw’ way. So I need to think about it. It seems the translation will need to make some change. Otherwise my Julia version code will be way much slower than the Fortran code, and that lost the meaning of my translation.

It is a Monte Carlo Expectation Maximization code with various Metropolis samplings and iterations. Just wanted to see how fast is Julia compared with Fortran.

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 4, 2021, 8:29am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/10 "2021-08-04T08:29:45Z")

</div>

Thank you so much!  
Right, with undef initial values can be dangerous.  
It just that, I heard that doing undef perhaps could also have some advantages, such as can detect some bug/error at early stage. If I initialize everthing all using ‘normal’ values, it perhaps will ‘hide’ some bugs.

---

<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:** [August 4, 2021, 11:52am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/11 "2021-08-04T11:52:08Z")

</div>

You don’t need to define the variables like that! Julia does not require variable declaration.

If you do something like this in Fortran:

```fortran
function f(x,y)
  double precision :: f, x, y, a, b, c
  a = 5.
  b = 3.
  c = 2.
  f = a*x + b*y + c
end

```

That in Julia is just

```julia
function f(x,y)
  a = 5.
  b = 3.
  c = 2.
  f = a*x + b*y + c
end

```

By the way, you should not absolutely try to use scalar variables as mutable variables. I mean, doing something like `a1 = Ref{Float64}(1.0)` is not recommended at all. I understand that you are trying to mimic Fortran behavior, in which one thinks that everything is a mutable variable. That way of thinking must go. Specifically, [read this](https://m3g.github.io/JuliaNotes.jl/stable/immutable/).

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 17, 2021, 12:16am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/12 "2021-08-17T00:16:40Z")

</div>

Thank you very much.  
But sometime it seems I do need to, don’t I? For example,

```
function step11(it::Int64)
    Muk = Array{Float64,1}(undef,kmix[])
    Sigk = Array{Float64,1}(undef,kmix[])
    error_sigk = Array{Float64,1}(undef,kmix[])
    ar_gik_k_more = Array{Float64,1}(undef,kmix[])

    for k in 1:kmix[]
        Muk(k),error_muk(k),Sigk(k),error_sigk(k),ar_gik_k_more(k) = Metroplis_gik_k_more_o_log(k,msample[])
    end
return nothing
end

```

I need to define

```
    Muk = Array{Float64,1}(undef,kmix[])
    Sigk = Array{Float64,1}(undef,kmix[])
    error_sigk = Array{Float64,1}(undef,kmix[])
    ar_gik_k_more = Array{Float64,1}(undef,kmix[])

```

One by one, because they need to be defined.  
Because I want the function Metroplis\_gik\_k\_more\_o\_log to give values to each elements of the above arrays.  
In these cases, it seems defining these arrays in few lines will be helpful.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [August 17, 2021, 12:27am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/13 "2021-08-17T00:27:53Z")

</div>

> [@CRquantum](#):
>
> a1,a2 are just names, they do not need to be ordered and named like vector.

This might be a case for namedtuples `(a=10, b=20, c=30)`.

---

<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:** [August 17, 2021, 1:17am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/14 "2021-08-17T01:17:05Z")

</div>

There is one thread that discussed some alterntives to that. One is this:

```julia
julia> a, b, c = ntuple(i -> Vector{Float64}(undef,0), 3)
(Float64[], Float64[], Float64[])

julia> a
Float64[]

julia> b
Float64[]

julia> c
Float64[]

```

> [@CRquantum](#):
>
> `Muk = Array{Float64,1}(undef,kmix[])`

By the way: `Vector{Float64}` is an alias for `Array{Float64,1}`. And I’m not sure what you are aiming there, but a vector of `kmix[]` does not sound right. What do you want to create there?

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 17, 2021, 2:50am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/15 "2021-08-17T02:50:50Z")

</div>

Thanks.  
kmix is defined as

```
 const kmix = Ref{Int64}()

```

So I need use kmix[] to get the value.

Do you think in the function step11, it is better to specify a known-size array Vector{Float64}(undef,kmix[]), or simply an unknown-size array Vector{Float64}(undef,0) ?  
I feel specify the size Vector{Float64}(undef,kmix[]) is better than just do Vector{Float64}(undef,0). Because the computer then knows how much memory to be allocated to the Vector{Float64}(undef,kmix[]).  
I feel Vector{Float64}(undef,0) is not enough, the explicit size is needed.

---

<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:** [August 17, 2021, 5:48am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/16 "2021-08-17T05:48:49Z")

</div>

> [@CRquantum](#):
>
> `const kmix = Ref{Int64}()`

`const` is for defining actual constants. If you don’t know the value of `kmix` and will in fact change it at runtime it’s better to leave it as an ordinary variable, and avoid globals that aren’t true constants.

> [@CRquantum](#):
>
> ```julia
> function step11(it::Int64)
> Muk = Array{Float64,1}(undef,kmix[])
> ...
> 
> ```

Can’t you make this into

```julia
function step11(it, kmix)
    Muk = Array{Float64,1}(undef, kmix)
    ...

```

?

BTW this function is confusing. It has one input, which it does not use, and apparently accesses two global variables instead of giving them as input arguments.

Then it creates several arrays, but returns `nothing`, so those arrays will disappear. It seems to rely heavily on ‘spooky action at a distance’, which, imho, should be avoided. Is this considered idiomatic in Fortran?

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [August 17, 2021, 6:30am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/17 "2021-08-17T06:30:07Z")

</div>

Everything that @DNF said plus that `Muk(k),error_muk(k),Sigk(k),error_sigk(k),ar_gik_k_more(k)` isn’t Julia either. We access arrays with square brackets.

Perhaps you shouldn’t copy-paste translate your Fortran code but instead think of its overall structure and dependencies and then think about how one would model this structure in Julia. Afterwards you can fill this “construct” with your real code, i.e. variable names, operations, etc.

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 17, 2021, 6:33am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/18 "2021-08-17T06:33:18Z")

</div>

Thanks.  
Of course I can make

```
step11(it, kmix)

```

But that is not the point.  
I use Ref, and [] symbol in kimx[] simply to remind me that it is a global variable and its type is locked.

The step11 function is just a small piece for illustration, all the arrays created will be used of course.

For me, modern Fortran’s grammar seem to be more easy to make sure type stability and easy to write fast code.

In Julia it seems more easy to make such a mistake (Please correct me if I am wrong)

```
function f(a::Int64)
  a=5.1 
  println(a) 
end

```

Here a should be Int64, but can be accidently changed to Float64 without warning.

---

<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:** [August 17, 2021, 6:39am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/19 "2021-08-17T06:39:46Z")

</div>

> [@CRquantum](#):
>
> But that is not the point.  
> I use Ref, and symbol in kimx simply to remind me that it is a global variable and its type is locked.

But the point is that you shouldn’t use global mutable variables.

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [August 17, 2021, 6:39am UTC](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788/20 "2021-08-17T06:39:51Z")

</div>

> [@CRquantum](#):
>
> But that is not the point.  
> I use Ref, and symbol in kimx simply to remind me that it is a global variable and its type is locked.

First of all, it very much _is_ the point. Using global variables in that way is highly unidiomatic and will likely get you into troubles in some way (unless, maybe, if you know exactly what you’re doing). Generally speaking, unless you’re “forced to”, don’t use mutable global variables.

> [@CRquantum](#):
>
> For me, modern Fortran’s grammar seem to be more easy to make sure type stability and easy to write fast code.

Well, at the risk of sounding a bit harsh (sorry in advance), why don’t you write Fortran then? Why do you want to use Julia in the first place if you like Fortrans grammar, speed etc.? Learning a new languange means learning a new language. And not just taking everything you know from a different language and one-to-one translating it.

[Next page](https://discourse.julialang.org/t/how-to-define-many-variables-in-few-lines/65788.md?page=2)
