# Parameters.jl usage: group variables to reduce number of inputs to function

**URL:** https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782
**Category:** New to Julia
**Tags:** argument, functions
**Created:** [October 21, 2020, 10:28pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782 "2020-10-21T22:28:14Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![dalarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dalarev/32/9881_2.png) [@dalarev](https://discourse.julialang.org/u/dalarev)
#### Post date: [October 21, 2020, 10:28pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/1 "2020-10-21T22:28:14Z")

</div>

I am looking at Parameters.jl to reduce the number of inputs to some functions.

How do I add an already-defined parameter to a parameter struct?

For context, one of my functions requires many constants as input: N1, N2, …, which are themselves computed by another function. So I can’t just say

```julia
@with_kw struct Para
    N1::Int64
end

```

and give it a value because N1 is already defined.

…and I guess while I’m at it, how would I define an array inside the Para struct? One of the arrays I would try to define is of type `StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}`. (Can that string be truncated and/or is there a better way to do that?) Similar situation as above, that array is already defined, so I would not give it a value inside the struct.

Thanks so much!

---

<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: [October 21, 2020, 11:28pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/2 "2020-10-21T23:28:42Z")

</div>

Unclear what you mean when you say that you can’t do exactly what you have written. Structs pretty much just pack things together when they are created. Parameters.jl just adds some convenience functionality for working with structs.

So your code example defines a struct `Para` which you can create an instance of by doing `Para(N1=N1value)` where `N1value` is whatever value you are trying to give to `N1` in the parameter struct. You can get `N1value` any way you like, no worries that it is a computed constant.

---

<div class="post-metadata">

### Author: ![briochemc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/briochemc/32/4209_2.png) [@briochemc](https://discourse.julialang.org/u/briochemc)
#### Post date: [October 22, 2020, 1:04am UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/3 "2020-10-22T01:04:42Z")

</div>

> [@tbeason](#):
>
> So your code example defines a struct `Para` which you can create an instance of by doing `Para(N1=N1value)` where `N1value` is whatever value you are trying to give to `N1` in the parameter struct. You can get `N1value` any way you like, no worries that it is a computed constant.

You can even call it `N1` (instead of `N1value`), that’s not a problem:

```julia
julia> using Parameters

julia> @with_kw struct Para
           N1::Int64
       end
Para

julia> N1 = 42
42

julia> Para(N1=N1)
Para
  N1: Int64 42

```

---

<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: [October 22, 2020, 2:50am UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/4 "2020-10-22T02:50:25Z")

</div>

> [@briochemc](#):
>
> You can even call it `N1` (instead of `N1value` ), that’s not a problem:

Of course, but it _does_ become a bit tricky to describe it to someone who is new to the process 😉

---

<div class="post-metadata">

### Author: ![dalarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dalarev/32/9881_2.png) [@dalarev](https://discourse.julialang.org/u/dalarev)
#### Post date: [October 22, 2020, 2:18pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/5 "2020-10-22T14:18:33Z")

</div>

Thanks for the replies.

I’m confused by the order of your code. I imagine the use case as:

```julia
N1 = func1(inputs) # N1 now has some value from another function

@with_kw struct Para # structure I want to create to group many constants/arrays
     N1::Int # N1 is already defined, so I simply want to add it to struct
end

function func2(Para) # function I want to feed some of Para constants/arrays
@unpack N1
# do math using N1
end

```

I interpret your code as 1) assigning N1 a value, 2) create a struct containing N1, (3) specify value of N1 using `Para(N1=N1)`. This seems redundant, but I’m sure I’m missing something in connecting Parameters usage to my use case.

---

<div class="post-metadata">

### Author: ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)
#### Post date: [October 22, 2020, 2:43pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/6 "2020-10-22T14:43:36Z")

</div>

You’ve missed the creation of the actual variable

```julia
# N1 = func1(inputs) # I remove this line because N1 as variable and as a field of the Para struct is confusing

@with_kw struct Para # structure I want to create to group many constants/arrays
     N1::Int # N1 is already defined, so I simply want to add it to struct
end

p = Para(func1(inputs))

function func2(p) # function I want to feed some of Para constants/arrays
@unpack N1 = p
# do math using N1
end

```

By the way, it is not necessary to create intermediate structure, you can use `NamedTuple`

```julia
p = (N1 = func1(inputs))

```

Or even better

```julia
N1 = func1(inputs)
p = (; N1) # This is equivalent to the creation of NamedTuple (N1 = N1)

```

---

<div class="post-metadata">

### Author: ![dalarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dalarev/32/9881_2.png) [@dalarev](https://discourse.julialang.org/u/dalarev)
#### Post date: [October 22, 2020, 5:09pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/7 "2020-10-22T17:09:59Z")

</div>

I can’t get `p = (N1 = func1(inputs))` to work when func1 has multiple outputs.

It’d be nice and concise if I could do:

```julia
p = (N1a,N1b,N1c,... = func1(inputs1))
p = (N2a,N2b,N2c,... = func1(inputs2))

```

and group all of those outputs in `p` so that I can later pick & choose those that I want in other functions.

---

<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: [October 22, 2020, 5:20pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/8 "2020-10-22T17:20:50Z")

</div>

If you structure the return of `func1` appropriately you get this for free:

```julia
function func1(inputs)
# do stuff
return (N1=this,N2=that)
end

```

then

```julia
p1 = func1(inputs1)
p2 = func1(inputs2)

```

Done.

This is exactly what I do.

---

<div class="post-metadata">

### Author: ![dalarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dalarev/32/9881_2.png) [@dalarev](https://discourse.julialang.org/u/dalarev)
#### Post date: [October 22, 2020, 5:35pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/9 "2020-10-22T17:35:58Z")

</div>

That’s true, but now p1 and p2 are separate tuples, right?

If a separate function required parameters from both, they’d have to be fed in separately.

What I’m really doing is computing grid parameters (step size, number of points, etc.) So I have a function `func` that looks like `gp1,gp2,gp3 = func(inputs)`, where “gp” are my resulting grid parameters.

I need to compute grid parameters for multiple grids, say a low-res and a high-res one:

```julia
gp1lo,gp2lo,gp3lo = func(inputslo)
gp1hi,gp2hi,gp3hi = func(inputshi)

```

Some combination of these will be needed as input to another function. So ideally I could group all `gp` variables (constants and arrays) into a structure `GP`, where `GP` can be the only input to my new function and I can `@unpack` whatever I need inside it.

---

<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: [October 22, 2020, 6:18pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/10 "2020-10-22T18:18:49Z")

</div>

Don’t you want simply an array?

```julia
julia> f(n) = rand(n), 10, 100;

julia> p = f(5);

julia> p[1]
5-element Array{Float64,1}:
 0.382830386230846
 0.19886498332704194
 0.7040674905637088
 0.5274814696569752
 0.6055869206344655

julia> p[2]
10

julia> p[3]
100

```

Then pass `p` as a parameter to the other function.

---

<div class="post-metadata">

### Author: ![dalarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dalarev/32/9881_2.png) [@dalarev](https://discourse.julialang.org/u/dalarev)
#### Post date: [October 22, 2020, 6:45pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/11 "2020-10-22T18:45:21Z")

</div>

That could work, but if I wanted to use the 2nd element of that array, for example, I’d have to call `p[1][2]`, instead of being able to point to a more memorable variable.

---

<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: [October 22, 2020, 6:55pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/12 "2020-10-22T18:55:26Z")

</div>

Something like this?

```julia
julia> f(n) = rand(n), 10, 100;

julia> struct Params
          N1
          N2
          N3
       end

julia> p = Params(f(5)...) # the 3 dots here is the "splat operator", that does the magic
Params([0.567716392452982, 0.9718828072619585, 0.2503661667618038, 0.9976792632899436, 0.42025703584303065], 10, 100)

julia> p.N1
5-element Array{Float64,1}:
 0.567716392452982
 0.9718828072619585
 0.2503661667618038
 0.9976792632899436
 0.42025703584303065

julia> p.N2
10

```

---

<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: [October 22, 2020, 7:07pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/13 "2020-10-22T19:07:54Z")

</div>

Instead of

```julia
gp1lo,gp2lo,gp3lo = func(inputslo)
gp1hi,gp2hi,gp3hi = func(inputshi)

```

try

```julia
helperfunc(x,y) = (gplo=func(x),gphi=func(y))
gparams = helperfunc(inputslo,inputshi)

```

then you can get stuff by for example `gparams.gplo.N1`

---

<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: [October 22, 2020, 7:08pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/14 "2020-10-22T19:08:12Z")

</div>

> [@dalarev](#):
>
> For context, one of my functions requires many constants as input: N1, N2, …, which are themselves computed by another function. So I can’t just say

Maybe use an array or tuple of values instead of separate struct fields?

---

<div class="post-metadata">

### Author: ![dalarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dalarev/32/9881_2.png) [@dalarev](https://discourse.julialang.org/u/dalarev)
#### Post date: [October 22, 2020, 7:23pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/15 "2020-10-22T19:23:00Z")

</div>

Yup, using an array or tuple of values seems like the way to go.

I guess this was a habit carried over from MATLAB, where one could group many already-defined variables into a “structure”: `STRUCT.a = a, STRUCT.b = b`. I’ll read up on where/when structures are actually the optimal choice.

Many thanks, everybody!

---

<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: [October 22, 2020, 7:30pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/16 "2020-10-22T19:30:45Z")

</div>

You can still use `@unpack` with named tuples too I think, which gets you most of what you might want from Parameters.jl

[https://github.com/mauro3/UnPack.jl](https://github.com/mauro3/UnPack.jl)

---

<div class="post-metadata">

### Author: ![dalarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dalarev/32/9881_2.png) [@dalarev](https://discourse.julialang.org/u/dalarev)
#### Post date: [November 2, 2020, 6:27pm UTC](https://discourse.julialang.org/t/parameters-jl-usage-group-variables-to-reduce-number-of-inputs-to-function/48782/17 "2020-11-02T18:27:01Z")

</div>

I ended up going with `NamedTuples`:

```julia
gplo = NamedTuple{(:gp1lo,:gp2lo,:gp3lo)}(func(inputslo))
gphi = NamedTuple{(:gp1hi,:gp2hi,:gp3hi)}(func(inputshi))
GP = merge(gplo,gphi)

```

making it straightforward to call any variable `GP.gp1lo`. Tried to find a way to define GP in one line but decided it wasn’t worth the time at the moment.

I don’t know if this solution optimizes performance, but it is easy to understand for me (took me a while to get a grip on this) and it’s nice to not need external packages.

Thanks again for the help.
