# A family of function and its arguments as argument of other custom function

**URL:** https://discourse.julialang.org/t/a-family-of-function-and-its-arguments-as-argument-of-other-custom-function/88792
**Category:** General Usage
**Tags:** question, functions
**Created:** [October 16, 2022, 3:40am UTC](https://discourse.julialang.org/t/a-family-of-function-and-its-arguments-as-argument-of-other-custom-function/88792 "2022-10-16T03:40:49Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![maoc](https://avatars.discourse-cdn.com/v4/letter/m/58956e/32.png) [@maoc](https://discourse.julialang.org/u/maoc)
#### Post date: [October 16, 2022, 3:40am UTC](https://discourse.julialang.org/t/a-family-of-function-and-its-arguments-as-argument-of-other-custom-function/88792/1 "2022-10-16T03:40:49Z")

</div>

I am trying to define a function which one of its arguments is a class of other functions, with diverse parameters (for example, distribution functions). So, I don’t know how to pass these parameters because the parameters, according to the distribution, doesn’t have the same pattern. For example

```julia
function foo(;distribution::Function, x = 0, parameters) 
    y = x + rand(distribution (parameters) )
    return y
end

```

In this case, I need to execute, for example:

```julia
# For normal(0,1)
foo(Normal, x = 2, 0,1)
# Or for normal(1,2)
foo(Normal, x = 2, 1,2)

```

Or

```julia
# For TDist(ν)
foo(TDist, x = 4, ν = 2 )

```

I spent some time looking for a solution, but I couldn’t find it. I would like a solution to include as arguments not only distributions and their parameters, but any kind of functions with several parameters.

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [October 16, 2022, 3:54am UTC](https://discourse.julialang.org/t/a-family-of-function-and-its-arguments-as-argument-of-other-custom-function/88792/2 "2022-10-16T03:54:00Z")

</div>

```julia
julia> using Distributions

julia> function foo(distribution, x, parameters...)
           y = x + rand(distribution(parameters...))
           return y
       end

julia> foo(Normal, 2, 0, 1)
0.7412695175676529

julia> foo(TDist, 4, 2)
1.5158055345656356

```

---

<div class="post-metadata">

### Author: ![maoc](https://avatars.discourse-cdn.com/v4/letter/m/58956e/32.png) [@maoc](https://discourse.julialang.org/u/maoc)
#### Post date: [October 16, 2022, 4:52am UTC](https://discourse.julialang.org/t/a-family-of-function-and-its-arguments-as-argument-of-other-custom-function/88792/3 "2022-10-16T04:52:20Z")

</div>

Why I can not do this?

```julia
function foo(distribution; x=0, parameters... )  
    y = x + rand(distribution(parameters...) ) 
    return y
end

```

Note that

```julia
foo(TDist,2 ,1)
0.010202203826929823

```

But

```julia
foo(TDist,x=2 ,1)
UndefKeywordError: keyword argument distribution not assigned

```

On the other hand

```julia
foo(TDist,2,ν=1)
UndefKeywordError: keyword argument distribution not assigned

```

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [October 16, 2022, 4:58am UTC](https://discourse.julialang.org/t/a-family-of-function-and-its-arguments-as-argument-of-other-custom-function/88792/4 "2022-10-16T04:58:10Z")

</div>

distributions’ constructors don’t take keyword arguments, don’t use them

---

<div class="post-metadata">

### Author: ![maoc](https://avatars.discourse-cdn.com/v4/letter/m/58956e/32.png) [@maoc](https://discourse.julialang.org/u/maoc)
#### Post date: [October 16, 2022, 5:01am UTC](https://discourse.julialang.org/t/a-family-of-function-and-its-arguments-as-argument-of-other-custom-function/88792/5 "2022-10-16T05:01:36Z")

</div>

Right. How about:

```julia
foo(TDist,x=2 ,1)

```

---

<div class="post-metadata">

### Author: ![maoc](https://avatars.discourse-cdn.com/v4/letter/m/58956e/32.png) [@maoc](https://discourse.julialang.org/u/maoc)
#### Post date: [October 16, 2022, 5:27am UTC](https://discourse.julialang.org/t/a-family-of-function-and-its-arguments-as-argument-of-other-custom-function/88792/6 "2022-10-16T05:27:17Z")

</div>

Something is not working. A concrete example: firts I am definig a function that simulate an autoregressive time series:

```julia
using Distributions

function simulateAR1(;ρ,σ = 1,x₀ = 0,μ = 0,T=1000)
    #noise
    η = rand( Normal(0,σ), T) 
    # My X
    X = zeros(T)
    # Looping 
    X[1] = x₀
    for t in 2:T
        X[t] = ρ*X[t-1] + η[t]
    end    
    return (X .+ μ)
end    

```

Test Ok

```julia
ξ = simulateAR1(ρ = 0.9)

```

Now, I want to do some Compound Sum of any distribution (it can be the the AR(1) distribution or other)

```julia
function CP(distribution, λ,parameters...)
    N = rand(Poisson(λ))
    A = zeros(T,N)
    for j =1:N
        aux = distribution(parameters...)
        for t=1:T
            A[t,j]=aux[t]
        end
    end
    Y=sum(A,dims=2)
    return Y
end

```

But

```julia
# In this case N poisson with lambda =2
CP(simulateAR1 ,2, 0.9)
UndefVarError: T not defined

```

Moreover

```julia
CP(simulateAR1 ,2, 0.9, T =100)
MethodError: no method matching CP(::typeof(simulateAR1), ::Int64, ::Float64; T=100)
Closest candidates are:
  CP(::Any, ::Any, ::Any...) at In[4]:1 got unsupported keyword argument "T"

```

Note, that I want input any other distributions with any kind of arguments. For example:

```julia
function non_ergodic1(; p₀ = .5 , p=.5 , T = 1000)
    moeda = rand(Bernoulli(p))
    if (moeda == 0)
        p = 1
    end
    ξ = [rand(Bernoulli(p)) for t in 1:T]
    return ξ
end

```

Defining function has been a headache for me. Help!

---

<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 16, 2022, 11:08am UTC](https://discourse.julialang.org/t/a-family-of-function-and-its-arguments-as-argument-of-other-custom-function/88792/7 "2022-10-16T11:08:19Z")

</div>

It will be hard to interface with every function like that. One alternative is to keep the internal interface fixed and use closures:

```julia
function foo(distribution::F, x) where {F<:Function}
    y = x + rand(distribution())
end

# call with
x = 2.0
foo(() -> Normal(0,1), x) 

```

Thus, your function expects, always, a function without parameters (or whatever), and interfacing with it is done by defining anonymous functions which adapt to that interface.

---

<div class="post-metadata">

### Author: ![maoc](https://avatars.discourse-cdn.com/v4/letter/m/58956e/32.png) [@maoc](https://discourse.julialang.org/u/maoc)
#### Post date: [October 16, 2022, 10:15pm UTC](https://discourse.julialang.org/t/a-family-of-function-and-its-arguments-as-argument-of-other-custom-function/88792/8 "2022-10-16T22:15:57Z")

</div>

Your solution works:

```julia
function CP(distribution::F, λ;T=1000) where {F<:Function}
    N = rand(Poisson(λ))
    A = zeros(T,N)
    for j =1:N
        aux = distribution()
        for t=1:T
            A[t,j]=aux[t]
        end
    end
    Y=sum(A,dims=2)
    return Y
end

```

Notice that simulateAR1 runs ok according to the function defined above:

```julia
simulateAR1(ρ=0.9);

```

Moreover

```julia
#Ok
CP(() -> simulateAR1(ρ=0.9), 2) ;

```

But why this does not work?

```julia
CP(simulateAR1(ρ=0.9), 2)

```

Thanks!

---

<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 16, 2022, 10:49pm UTC](https://discourse.julialang.org/t/a-family-of-function-and-its-arguments-as-argument-of-other-custom-function/88792/9 "2022-10-16T22:49:14Z")

</div>

> [@maoc](#):
>
> `() -> simulateAR1(ρ=0.9)`

This notation define a new function, without parameters, that returns the result of the right side. You are passing the function, not the result of the evaluation of the function, which is what you do in the second case:

```julia
() -> Normal(1.0)

# or

f() = Normal(1.0)

```

are function definitions, the first anonymous, and you are using that in that case, the second one just a regular function, without parameters.

`Normal(1.0)` is the call to the `Normal` function and returns a value (the distribution), not a function.
