# Best practice for storing, passing, and managing parameters in economic models

**URL:** https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705
**Category:** Finance and Economics
**Tags:** performance
**Created:** [July 15, 2021, 4:52pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705 "2021-07-15T16:52:37Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![PatrickMcFarlane](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickmcfarlane/32/50027_2.png) [@PatrickMcFarlane](https://discourse.julialang.org/u/PatrickMcFarlane)
#### Post date: [July 15, 2021, 4:52pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/1 "2021-07-15T16:52:37Z")

</div>

I am working on a discrete time HANK model in Julia.

The model has a very large number of parameters. Most of these are related to the theoretical structure of the model (e.g., production function parameters, utility function parameters, policy parameters, stochastic process parameters, etc.). Some are related to numerical methods (e.g., numbers of grid points, state space bounds, convergence tolerances, dampening parameters for fixed point iterations, etc.).

The code will make use of many functions, some will only require a small subset of the parameters (e.g., a function for the marginal utility of consumption), others will require all of them as they will call many of the other functions (e.g., a function for computing the steady-state of the model).

I will also write some calibration routines that will alter the parameters to achieve certain calibration targets for the model (e.g., matching some features of the empirical income or wealth distribution for example). These are likely to be iterative (e.g., solving the model, updating parameters, solve again, etc.)

What is the best practice for storing and passing these parameters to functions and why? I have often seen examples where modelers set up a structure to hold all the model parameters and then simply pass the structure to functions. But it seems like named tuples could also work.

The model is large and thus performance will be a top consideration.

Thank you in advance for any insights.

---

<div class="post-metadata">

### Author: ![PatrickMcFarlane](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickmcfarlane/32/50027_2.png) [@PatrickMcFarlane](https://discourse.julialang.org/u/PatrickMcFarlane)
#### Post date: [July 16, 2021, 2:21pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/2 "2021-07-16T14:21:29Z")

</div>

I have been doing more reading on this issue. For anyone else that has the same question, there is a highly relevant thread here:

[https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748)

As it turns out, thinking about this issue seems to have led to the development of features in [Parameters.jl](https://github.com/mauro3/Parameters.jl)

For convenience, using Parameters.jl seems to be the way to go, but I’m still not entirely clear on the advantages/disadvantages of structs versus named tuples. Particularly as it relates to calibrating the model where I will want to make numerous changes to the parameter values and possibly use a numerical root-finding algorithm to alter them.

---

<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: [July 16, 2021, 2:55pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/3 "2021-07-16T14:55:03Z")

</div>

> [@PatrickMcFarlane](#):
>
> For convenience, using Parameters.jl seems to be the way to go, but I’m still not entirely clear on the advantages/disadvantages of structs versus named tuples.

One of the advantages is the possibilities introduced for construction, particularly if you use the Parameters package. You can just set a bunch of parameters as default and only set the other ones each time:

```julia
julia> using Parameters

julia> @with_kw struct Options
         n::Int = 1
         x::Float64 = 1.0
       end
Options

julia> opt = Options(n=2)
Options
  n: Int64 2
  x: Float64 1.0

```

I don’t see how that could be done with named tuples readily. Also, note that all functions that you define in your code can be dispatched to the `Options` type specifically:

```julia
julia> function f(y,opt::Options) 
         @unpack n, x = opt # unpack is from Parameters.jl
         return (x*y)^n
       end
f (generic function with 1 method)

julia> f(1.0,Options(n=3,x=2.0))
8.0

```

With named tuples that would be more cumbersome, for sure, and the “user” could face many more sources of error by providing the functions with tuples with wrong argument names or types.

> [@PatrickMcFarlane](#):
>
> Particularly as it relates to calibrating the model where I will want to make numerous changes to the parameter values and possibly use a numerical root-finding algorithm to alter them.

In this case, you can use a mutable struct or, more likely, store arrays in the struct, and just calibrate the parameters that are defined in these arrays, that mutable anyway, even if the struct is not mutable (this would be the same for a named tuple containing an array):

```julia
julia> using Parameters

julia> @with_kw struct Options
         n::Int = 1
         x::Vector{Float64} = zeros(2)
       end
Options

julia> opt = Options()
Options
  n: Int64 1
  x: Array{Float64}((2,)) [0.0, 0.0]

julia> opt.x[1] = 1.0
1.0

julia> opt
Options
  n: Int64 1
  x: Array{Float64}((2,)) [1.0, 0.0]

```

---

<div class="post-metadata">

### Author: ![PatrickMcFarlane](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickmcfarlane/32/50027_2.png) [@PatrickMcFarlane](https://discourse.julialang.org/u/PatrickMcFarlane)
#### Post date: [July 16, 2021, 3:32pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/4 "2021-07-16T15:32:57Z")

</div>

> I don’t see how that could be done with named tuples readily.

I thought that @with\_kw and @unpack worked with named tuples as well. Using a bit of code from the Parameters.jl site and expanding on it:

```julia
julia> using Parameters

julia> MyNT = @with_kw (x = 1, y = "foo", z = :(bar))
##NamedTuple_kw#263 (generic function with 2 methods)

julia> tupl1 = MyNT(x=2)
(x = 2, y = "foo", z = :bar)

julia> @unpack x=tupl1
(x = 2, y = "foo", z = :bar)

julia> x
2

```

> In this case, you can use a mutable struct or, more likely, store arrays in the struct, and just calibrate the parameters that are defined in these arrays, that mutable anyway, even if the struct is not mutable (this would be the same for a named tuple containing an array):

I was reading [here](https://www.juliabloggers.com/should-i-use-mutable-or-immutable-containers-for-agent-based-models-in-julia/) that immutable types have significant performance advantages and that using Setfield.jl to modify them has performance advantages compared to using mutables. Not sure whether those advantages hold when you store arrays in an immutable struct and then alter those arrays. But that seems like more hoops to jump through than just using Setfield.jl, particularly since many of the elements in the parameters container would be of the form: alpha=0.5, beta=0.9, nk=50 , etc.

Right now I’m leaning a bit towards named tuples because of the fact that they are type inferred and I therefore would not need to explicitly set out the type of each parameter.

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [July 16, 2021, 3:59pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/5 "2021-07-16T15:59:49Z")

</div>

I don’t do anything as complicated as a HANK model, but 100% `@unpack` and `@set` are your best friends. I have like 3 medium-ish structs that are parametrically typed that I just pass to every function, whether I need it or not. Saves a lot of mental overhead.

Then I just use `@unpack` as needed. Sure it’s annoying to write `@unpack` everywhere, but it beats using `getproperty` a lot, passing each parameter as a separate argument, or globals, or namespace issues.

`@set` will be fast as long as the types are isbits, which they will be if they are just non-mutable `struct`s full of numbers. Using `@set` a lot definitely not going to be close to a bottleneck in your code.

I think you are on the right track.

---

<div class="post-metadata">

### Author: ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)
#### Post date: [July 16, 2021, 4:17pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/6 "2021-07-16T16:17:00Z")

</div>

If you are not intending to use these for dispatching (which you probably aren’t for this sort of use), then they are roughly equivalent. In both cases, use the tools to define defaults (e.g. the `@with_kw` for the named tuples) and use `@unpack` where applicable. With named tuples, it tends to be a little bit easier to to iterate on your design as you can add new things to it as you code and you don’t need to restart the repl as much to compile the new structs, but that is a 2nd order concern.

The most important thing for pararmeters if ensuring that the structures remain immutable and that you properly type any `struct`. Named tuples will figure out the concrete types for you. Here are a few hints, but the julia docs are more complete: [5. Introduction to Types and Generic Programming — Quantitative Economics with Julia](https://julia.quantecon.org/getting_started_julia/introduction_to_types.html#Creating-New-Types)

---

<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: [July 16, 2021, 4:19pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/7 "2021-07-16T16:19:32Z")

</div>

> [@PatrickMcFarlane](#):
>
> `MyNT = @with_kw (x = 1, y = "foo", z = :(bar))`

I was not aware of that syntax. But note that it does not limit you in defining anything as any of the parameters:

```julia
julia> MyNT = @with_kw (x = 1, y = "foo", z = :(bar))
##NamedTuple_kw#257 (generic function with 2 methods)

julia> tupl1 = MyNT(x=1)
(x = 1, y = "foo", z = :bar)

julia> tupl1 = MyNT(x="abc")
(x = "abc", y = "foo", z = :bar)

```

Thus, you cannot really dispatch on that `MyNT` type, which is not really a type.

> [@PatrickMcFarlane](#):
>
> Setfield.jl, particularly since many of the elements in the parameters container would be of the form: alpha=0.5, beta=0.9, nk=50

`Setfield.jl` copies the complete structure each time. Note, for instance:

```julia
julia> using Setfield

julia> struct A
         x
       end

julia> f(x::A) = @set! x.x = 5
f (generic function with 1 method)

julia> a = A(1)
A(1)

julia> f(a)
A(5)

julia> a
A(1)

```

Note that `a` was not mutated really. This can be convenient if your structure does not have many parameters, but for large enough structures it become better to really write mutable structures.

At the same time, immutable structures containing mutable fields is a very common thing. You guarantee with that the the _type_ o the field is constant, and that allows for many compiler optimizations, even if the content of the field changes.

---

<div class="post-metadata">

### Author: ![PatrickMcFarlane](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickmcfarlane/32/50027_2.png) [@PatrickMcFarlane](https://discourse.julialang.org/u/PatrickMcFarlane)
#### Post date: [July 16, 2021, 7:09pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/8 "2021-07-16T19:09:20Z")

</div>

> With named tuples, it tends to be a little bit easier to to iterate on your design as you can add new things to it as you code and you don’t need to restart the repl as much to compile the new structs

Are you referring to the `merge()` function?

---

<div class="post-metadata">

### Author: ![PatrickMcFarlane](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickmcfarlane/32/50027_2.png) [@PatrickMcFarlane](https://discourse.julialang.org/u/PatrickMcFarlane)
#### Post date: [July 16, 2021, 7:32pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/9 "2021-07-16T19:32:49Z")

</div>

> At the same time, immutable structures containing mutable fields is a very common thing. You guarantee with that the the _type_ o the field is constant, and that allows for many compiler optimizations, even if the content of the field changes.

I find the syntax with that approach is a bit tricky. For example, if I want to have a simple parameter, β=0.5, I need to remember to declare it’s type as an Array and use square brackets when entering the value even though it will always be a scalar:

```julia
#this doesn't work
julia> @with_kw struct MParams

                         α::Array{Float64} = 0.5
                         β::Array{Float64} = 0.9
                     end
MParams

julia> p = MParams()

ERROR: MethodError: Cannot `convert` an object of type
  Float64 to an object of type
  Array{Float64, N} where N

#This does
julia> @with_kw struct MParams

                         α::Array{Float64} = [0.5]
                         β::Array{Float64} = [0.9]
                     end
MParams

julia> p = MParams()
MParams
  α: Array{Float64}((1,)) [0.5]
  β: Array{Float64}((1,)) [0.9]

```

And then when I want to mutate it, I need to remember to use square brackets again:

```julia
#this doesn't work
julia> p.α = 0.6
ERROR: MethodError: Cannot `convert` an object of type
  Float64 to an object of type
  Array{Float64, N} where N

#this does
julia> p.α[1] = 0.6
0.6

```

I suppose if I use that technique enough, it would become habit and I wouldn’t make those errors anymore. At the same time, I’m the early adopter of Julia at my institution and I’d like to reduce the chances of errors for other potential users. Especially since they may at some point need to learn how to do simulations with my model without having to learn a lot about Julia itself.

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [July 16, 2021, 7:47pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/10 "2021-07-16T19:47:25Z")

</div>

There is some confusion in this post that could be alleviated by re-reading the [manual](https://docs.julialang.org/en/v1/manual/types/#Composite-Types) on Julia’s types.

1. 

```julia
struct MParams
    α::Array{Float64} = 0.5
    β::Array{Float64} = 0.9
end

```

is not the appropriate type declaration. I’m not sure what this is intended to be. A vector where every value of `.5`?

1. 

```julia
struct MParams
    α::Array{Float64} = 0.5
    β::Array{Float64} = 0.9
end

```

If you rad the manual, you will see that declaring types in this way will lead to type instabilities. You want to declare the types in the same line as `struct`. That way Julia can “see” the types of an object at compile time and create more optimized code.

Here is what I would recomment (without `@with_kw`) for simplicity

```julia
julia> struct MParams{T <:AbstractVector{<:Real}}
           α::T
           β::T
       end;

julia> function MParams()
           α = fill(.5, 10)
           β = fill(.9, 10)
           MParams(α, β)
       end;

julia> MParams()
MParams{Vector{Float64}}([0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5], [0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9])

```

EDIT: I re-read your question and I think I have better advice.

There is nothing wrong with a fully-types mutable struct. The following will be _faster_ than having mutable types in a non-mutable struct, as you are currently doing with your one element array trick above.

```julia
julia> mutable struct MParamsMutable{T<:Real}
           α::T
           β::T
       end;

julia> function MParamsMutable()
           MParamsMutable(.5, .9)
       end;

julia> m = MParamsMutable()
MParamsMutable{Float64}(0.5, 0.9)

julia> m.α = .2
0.2

julia> m
MParamsMutable{Float64}(0.2, 0.9)

```

Overall, the distinction between a mutable struct and using `@set` is really not about speed for small to medium structs.

1. If you have a persistent object you update across time, like during solving the model, use a `mutable struct`
2. If, in the process of solving the model, parameters are constant, then I would use a non-mutable `struct` and then use `@set` to analyze comparative statics, making a new object as needed. This will be very cheap for medium-sized `struct`s of numbers, so don’t worry about 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: [July 16, 2021, 8:47pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/11 "2021-07-16T20:47:41Z")

</div>

Probably you meant:

```julia
@with_kw struct Params
  x::Vector{Float64} = [0.5]
end

```

I agree that having _one_ value in an immutable struct that must be mutable lacks a beautiful syntax. I have even asked that here before: [Mutable scalar in immutable object: the best alternative?](https://discourse.julialang.org/t/mutable-scalar-in-immutable-object-the-best-alternative/57401)

In the cases I needed that I finally keep using a vector with a single element.

None of the alternatives is completely clean, IMO. To have a clean syntax use a mutable struct,

```julia
julia> @with_kw mutable struct Params
         α::Float64 = 1.0
       end
Params

julia> a = Params()
Params
  α: Float64 1.0

julia> a.α = 2.0
2.0

julia> a
Params
  α: Float64 2.0

```

But that may have its performance penalties.

(now I see that a great part of this was already mentioned before)

---

<div class="post-metadata">

### Author: ![PatrickMcFarlane](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickmcfarlane/32/50027_2.png) [@PatrickMcFarlane](https://discourse.julialang.org/u/PatrickMcFarlane)
#### Post date: [July 16, 2021, 10:59pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/12 "2021-07-16T22:59:26Z")

</div>

> [@lmiq](#):
>
> Probably you meant:
> 
> ```julia
> @with_kw struct Params
> x::Vector{Float64} = [0.5]
> end
> 
> ```

Yes sorry should have written `Array{Float64,1}` or better yet, your suggestion `Vector{Float64}`.

When I fix that, the other potential syntax errors (e.g., forgetting square brackets when creating the `struct` or the `.[1]` when mutating the value) still persist and produce the same errors.

My error inadvertently demonstrated my point which is that one has to be more careful with syntax with this approach to avoid errors compared to just using an immutable struct and `@set`…or even easier, a named tuple.

Still, it’s a technique worthwhile keeping in the quiver. My parameters `struct` will maybe have about 40-50 elements, mostly scalars or very small arrays (e.g., 2x2 or 4x1). Not sure if that qualifies as big or not…guess I’ll just have to test it both ways (mutable, vs. arrays, vs. `@set`) to see if there’s a significant performance advantage with one approach over the other.

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [July 16, 2021, 11:02pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/13 "2021-07-16T23:02:30Z")

</div>

I think with 40-50 elements that qualifies as big, to the extent that a parametric struct might not be the best solution. Not that I have any concrete examples for where that might fail, only that it seems rare for me to see structs of that size.

I would be interested to hear of other peoples’s solutions to heterogenous containers of this size.

EDIT: One solution might be to have a nested struct, but where you overload methods for `UnPack.unpack` to access the properties easily, see [here](https://github.com/mauro3/UnPack.jl#customization-of-unpack-and-pack).

---

<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: [July 16, 2021, 11:34pm UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/14 "2021-07-16T23:34:05Z")

</div>

> [@PatrickMcFarlane](#):
>
> immutable struct and `@set` …or even easier, a named tuple.

Using `@set` is of course one of the options. On the other side, how can tuple help there? (If there is a better syntax using a tuple for that I will be glad to know).

Ps: not sure if you are aware of it, but for the small arrays, use StaticArrays. (These are recommended for sizes of about 100 elements. Probably that size is more or less where using a mutable struct will start to be advantageous relative to an immutable with Setfield).

---

<div class="post-metadata">

### Author: ![PatrickMcFarlane](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickmcfarlane/32/50027_2.png) [@PatrickMcFarlane](https://discourse.julialang.org/u/PatrickMcFarlane)
#### Post date: [July 17, 2021, 12:21am UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/15 "2021-07-17T00:21:39Z")

</div>

> [@lmiq](#):
>
> Using `@set` is of course one of the options. On the other side, how can tuple help there? (If there is a better syntax using a tuple for that I will be glad to know).

Yes you are correct. `@set` alone won’t work - the tuple doesn’t get changed when you call it again. I saw [this thread](https://discourse.julialang.org/t/alternative-to-mutable-named-tuple/38375/8) explaining how to make it work with the BangBang package though. For example:

```julia
julia>using BangBang

julia> ParamTupl = @with_kw (α = 0.5, β = 0.9)
##NamedTuple_kw#257 (generic function with 2 methods)

julia> p = ParamTupl()
(α = 0.5, β = 0.9)

julia> @set p.β = 0.7
(α = 0.5, β = 0.7)

julia> p
(α = 0.5, β = 0.9)

# now with BangBang
julia> @set!! p.β = 0.7
(α = 0.5, β = 0.7)

julia> p
(α = 0.5, β = 0.7)

```

The main advantage with named tuples is that you don’t have to specify types to get optimizations to work so in that sense they may be a bit more user friendly. Not sure there are advantages beyond that.

---

<div class="post-metadata">

### Author: ![PatrickMcFarlane](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickmcfarlane/32/50027_2.png) [@PatrickMcFarlane](https://discourse.julialang.org/u/PatrickMcFarlane)
#### Post date: [July 17, 2021, 12:58am UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/16 "2021-07-17T00:58:25Z")

</div>

> declaring types in this way will lead to type instabilities. You want to declare the types in the same line as `struct` . That way Julia can “see” the types of an object at compile time and create more optimized code.

I’m new to Julia, so just to clarify, did changing my `Array{Float64}` to `Array{Float64,1}` fix the type stability issue you were referring to? I don’t think what I wanted to do was declare a parametric type…just a composite type I think.

The Julia manual seems to use similar syntax in the section on composite types.

Regarding the use-case. The parameters container, whatever that may be, will need to mutated infrequently - for example only when developing the model or making significant changes. The process of calibrating the model involves running the model many times (e.g., via some sort of numerical solver) while making adjustments to the parameters. Each run of the model would involve lots of calls to the parameters container without doing any mutations.

More typically, I will be just running the calibrated model to illustrate the effects of various shocks (e.g., monetary policy shocks, government spending shocks, tax policy changes, etc.)

So I think this probably argues for using an immutable container.

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [July 17, 2021, 1:28am UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/17 "2021-07-17T01:28:39Z")

</div>

> So I think this probably argues for using an immutable container.

I agree, an immutable container is the right choice.

> [@PatrickMcFarlane](#):
>
> I’m new to Julia, so just to clarify, did changing my `Array{Float64}` to `Array{Float64,1}` fix the type stability issue you were referring to? I don’t think what I wanted to do was declare a parametric type…just a composite type I think.

I am pretty sure that `Array{Float64}` is not good because you aren’t specifying the dimension of the array. But I could be wrong about this and hope someone else chimes in.

```julia
struct MyType
    a::Vector{Float64} # alias for Array{Float64, 1}
end

```

will be perfectly performant.

But this will be limiting. When you optimize your code further, you may want to use Static Vectors from [StaticArrays.jl](https://github.com/JuliaArrays/StaticArrays.jl). You can’t go back and forth between Static Arrays and Base Arrays when the type is declared like that. But you _can_ if you do

```julia
julia> struct B{T <: AbstractVector{<:Real}}
           b::T
       end;

```

This is all pretty complicated, and you expressly said you didn’t want to get in the weeds with Julia’s type system. So I think the answer is

Yes, use something along the lines of

```julia
struct A
    a::Array{Float64, 1}
    b::...
    c::...
end

```

but make sure your declarations are fully specified, ie. don’t just write `Array{Float64}`. That will hurt performance.

If you feel like you will want more flexibility, then don’t just follow the syntax in the [Composite types](https://docs.julialang.org/en/v1/manual/types/#Composite-Types) section, but also the [Parametric types](https://docs.julialang.org/en/v1/manual/types/#Parametric-Types) section.

---

<div class="post-metadata">

### Author: ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)
#### Post date: [July 17, 2021, 3:25am UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/18 "2021-07-17T03:25:32Z")

</div>

> [@PatrickMcFarlane](#):
>
> I’m new to Julia

I think named tuples usually the better place to start then. You are less likely to make mistakes in setting the wrong parametric types (as you saw above) which could have catastrophic effects on performance. It isn’t worth the risk.

It will also be faster for you to code and design since you can just recreate and change your named tuples as you are playing around with it, while structures can’t be redefined so easily.

---

<div class="post-metadata">

### Author: ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)
#### Post date: [July 17, 2021, 3:32am UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/19 "2021-07-17T03:32:22Z")

</div>

> [@pdeffebach](#):
>
> This is all pretty complicated

Yes. But it is also useful to leave things more generic, as the performance differences and design flexibility can be huge.

There are some hints here:

> **[Introduction to Types and Generic Programming](https://julia.quantecon.org/getting_started_julia/introduction_to_types.html#Issues-with-Type-Declarations)**
>
> This website presents a set of lectures on quantitative economic modeling, designed and written by Jesse Perla, Thomas J. Sargent and John Stachurski. The language instruction is Julia.

But the summary is that you want to leave everything as generic as possible, without specifying any more specific types than you need. That gives you maximum flexibility in the future.

For parameters, etc the easiest way to do that before you really know the details of Julia types is just to use named tuples. They are completely generic and the compiler figures the types out for you.

---

<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: [July 17, 2021, 10:34am UTC](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705/20 "2021-07-17T10:34:38Z")

</div>

Interesting point of view. I think the struct will be useful, with a more restrictive type information, to avoid user errors. While you are exploring the parameters from a development perspective, certainly the tuples will be more convenient.

[Next page](https://discourse.julialang.org/t/best-practice-for-storing-passing-and-managing-parameters-in-economic-models/64705.md?page=2)
