# Need to add flexibility to deeply nested functions---global parameter variable a good idea?

**URL:** <https://discourse.julialang.org/t/need-to-add-flexibility-to-deeply-nested-functions-global-parameter-variable-a-good-idea/48868>\
**Category:** General Usage\
**Created:** [October 23, 2020, 7:07am UTC](https://discourse.julialang.org/t/need-to-add-flexibility-to-deeply-nested-functions-global-parameter-variable-a-good-idea/48868 "2020-10-23T07:07:27Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![ElectronicTeaCup](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/electronicteacup/32/12647_2.png) [@ElectronicTeaCup](https://discourse.julialang.org/u/ElectronicTeaCup)\
**Post date:** [October 23, 2020, 7:07am UTC](https://discourse.julialang.org/t/need-to-add-flexibility-to-deeply-nested-functions-global-parameter-variable-a-good-idea/48868/1 "2020-10-23T07:07:28Z")

</div>

I have a general programming question (which I need to tacking using Julia). I have a couple of functions (that call other functions) to carry out my analysis (some signal processing tasks and sorting data the way I want). In turn these functions are called by a pipeline function that runs series of functions and takes specific outputs from them, and generates plots.

Sometimes I have to go back to the nested “analysis functions” to change something, however, these tweaks are usually very deeply nested so I’ve been manually change parts of the function and generate plots. This was fine when I had to run an instance or two, but now having to run the code several times I have address how to efficiently change the internals.

If I make optional arguments in the highest level function, it will have to to be passed down several functions which doesn’t seem right. I am currently thinking:

1. Make a global parameter variable, a named tuple, that the functions access. This puts all my parameters in the beginning of the script and I can iteratively add different parameters to it. But i will be using global variables

2. Change the layout of the analysis.

Would appreciate some feedback. Is going for a global parameter variable going to be very poor for performance? I need to be able to dynamically be able to modify parts of the pipeline that I had not previously considered needing flexibility. Perhaps the drop of performance is okay at this level, where I am trying different pipeline parameters? [~80% of my computation time is on reading the data, and the analysis doesn’t take more than about 5 minutes]

---

<div class="post-metadata">

**Author:** ![wulpuqu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wulpuqu/32/17640_2.png) [@wulpuqu](https://discourse.julialang.org/u/wulpuqu)\
**Post date:** [October 23, 2020, 7:40am UTC](https://discourse.julialang.org/t/need-to-add-flexibility-to-deeply-nested-functions-global-parameter-variable-a-good-idea/48868/2 "2020-10-23T07:40:58Z")

</div>

So lets say that I have a bunch of functions like the following one. By assuming that you have two kind of parameters: processing parameters and plotting parameters and functions like:

```julia
function processing(data,N,L=10;kw1,kw2)
function processing_bis(data,N,M,K)
function plotdata(N,size)

```

What I like to do is to overload this functions with either a struct, a dictionnary or a tuple containing all my parameters. For example, I can define my analysis parameters as

```julia
(mutable) struct AnalysisParameters
    N
    L
    kw1
    kw2
    M
    K
end

```

and overload processing functions like this

```julia
processing(data,params::AnalysisParameters)=processing(data,params.N,params.L;kw1=params.kw1,kw2=params.kw2)
processing_bis(data,params::AnalysisParameters)=processing_bis(data,params.N,params.M,params.K)

```

I will do the same thing for plotting by defining a `(mutable) struct PlottingParameters` and overload the appropriate functions. The advantage of this, is that you only have to modify your main script and add new methods taking your parameters.

Ultimately, if you are interested in keeping track of which parameters you used for your results and avoid overwriting or repeating some simulations, you can parametrize the filename of you results with the `hash` of your `struct/Dict/NameTuple` parameters, i.e if the hash already exists in the filenames of you results you can skip the computation and a slight change in parameters will result in two different filenames.

I hope it helps !

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [October 23, 2020, 8:01am UTC](https://discourse.julialang.org/t/need-to-add-flexibility-to-deeply-nested-functions-global-parameter-variable-a-good-idea/48868/3 "2020-10-23T08:01:05Z")

</div>

> [@ElectronicTeaCup](#):
>
> Sometimes I have to go back to the nested “analysis functions” to change something, however, these tweaks are usually very deeply nested so I’ve been manually change parts of the function and generate plots

I would pack these parameters in a `struct` and just pass them around. It does look a bit tedious, but I think it results in more organized code — personally, I know I would simply forget that there is a global variable when I look at the code a few months later.

---

<div class="post-metadata">

**Author:** ![ctkelley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ctkelley/32/10684_2.png) [@ctkelley](https://discourse.julialang.org/u/ctkelley)\
**Post date:** [October 23, 2020, 10:02am UTC](https://discourse.julialang.org/t/need-to-add-flexibility-to-deeply-nested-functions-global-parameter-variable-a-good-idea/48868/4 "2020-10-23T10:02:53Z")

</div>

Global variables can also break parallelism. Even in something as simple as a parallel for loop like an `floop` if each call to the function in the loop assigns different things to the global. As @Tamas_Papp says, globals make your debugging jobs harder.

---

<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 23, 2020, 2:04pm UTC](https://discourse.julialang.org/t/need-to-add-flexibility-to-deeply-nested-functions-global-parameter-variable-a-good-idea/48868/5 "2020-10-23T14:04:45Z")

</div>

Depending on how the code is structured, you can use closures to pass the function that will ultimately be tweaked, with parameters, to the internal functions:

```julia
julia> function outer(f,x)
         return inner(f,x)
       end
outer (generic function with 1 method)

julia> function inner(f,x)
           f(x)
       end
inner (generic function with 1 method)

julia> f(x,a) = a*x
f (generic function with 1 method)

julia> a = 5.
5.0

julia> outer(x -> f(x,a),2)
10.0

```

---

<div class="post-metadata">

**Author:** ![ElectronicTeaCup](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/electronicteacup/32/12647_2.png) [@ElectronicTeaCup](https://discourse.julialang.org/u/ElectronicTeaCup)\
**Post date:** [October 23, 2020, 2:07pm UTC](https://discourse.julialang.org/t/need-to-add-flexibility-to-deeply-nested-functions-global-parameter-variable-a-good-idea/48868/6 "2020-10-23T14:07:04Z")

</div>

Ah okay, so ultimately this would mean that _every_ function that needs to have a parameter tweaked will have an input which will be the parameter struct.

[Parameters.jl](https://github.com/mauro3/Parameters.jl) seems to have some helpful macros for this. Any differences using either a struct or a named tuple? (I saw that it can take either)

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [October 23, 2020, 2:15pm UTC](https://discourse.julialang.org/t/need-to-add-flexibility-to-deeply-nested-functions-global-parameter-variable-a-good-idea/48868/7 "2020-10-23T14:15:16Z")

</div>

An advantage of `NamedTuple`s is that Revise can handle them just fine, while `struct` redefinition requires a restart. But if you do it right, the _consumers_ of such types do not need to care (just use `Unpack.@unpack`, or property accessors). So when you are done you can finalize to a `struct` if you want to.
