# Can't push a function into a function array

**URL:** <https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588>\
**Category:** General Usage\
**Tags:** question, array\
**Created:** [April 1, 2019, 7:33am UTC](https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588 "2019-04-01T07:33:09Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![roi.holtzman](https://avatars.discourse-cdn.com/v4/letter/r/f05b48/32.png) [@roi.holtzman](https://discourse.julialang.org/u/roi.holtzman)\
**Post date:** [April 1, 2019, 7:33am UTC](https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588/1 "2019-04-01T07:33:09Z")

</div>

I am new to Julia. I am trying to initialize an array of functions, and add a function to it.  
This is my code:

```julia
arr = Array{Function, 1}
push!(arr, sin)

```

And this is the error I’m getting

```julia
MethodError: no method matching push!(::Type{Array{Function,1}}, ::typeof(sin))
Closest candidates are:
  push!(::Any, ::Any, !Matched::Any) at abstractarray.jl:2095
  push!(::Any, ::Any, !Matched::Any, !Matched::Any...) at abstractarray.jl:2096
  push!(!Matched::Array{Any,1}, ::Any) at array.jl:860
  ...

```

What is my problem?

I also tried this version according to the [documentation](https://docs.julialang.org/en/v1/base/arrays/index.html#Core.Array-Tuple%7BUndefInitializer,Any%7D)

```julia
arr2 = Array{Function}(undef, 1)
push!(arr2, sin)

```

but then `arr2` is

```julia
2-element Array{Function,1}:
 #undef
    sin

```

and I cannot access the function. When I execute `arr2[1]` I get

```julia
UndefRefError: access to undefined reference

```

I do not understand why I get this behavior. I would love to some explanation.

---

<div class="post-metadata">

**Author:** ![anon67531922](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@anon67531922](https://discourse.julialang.org/u/anon67531922)\
**Post date:** [April 1, 2019, 7:42am UTC](https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588/2 "2019-04-01T07:42:25Z")

</div>

`Array{Function,1}` is a data type. You want an instance of that data type, i.e. you want an actual array, i.e.

```julia
arr = Array{Function,1}()

```

Edit: To explain a bit more…

> I do not understand why I get this behavior. I would love to some explanation.

```julia
arr2 = Array{Function}(undef, 1)

```

At this step, you have created a 1-element array of `Function` types with the first element initialized to `undef`.

```julia
push!(arr2, sin)

```

When you push `sin` to this array, you get a 2-element array of `Function` types, with the second element `sin` and the first is still `undef`.

> and I cannot access the function. When I execute `arr2[1]` I get

Julia is 1-indexed, so `arr2[1]` is grabbing the first element of your array which is `undef`. If you grad `arr2[2]`, it would be `sin`.

I hope this 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:** [April 1, 2019, 7:57am UTC](https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588/3 "2019-04-01T07:57:22Z")

</div>

In addition to the excellent explanation of @anon67531922: since `Function` is not a concrete type, there is no speed gain from specifying it — you might as well use `Any`. Eg

```julia
julia> arr = Vector()
0-element Array{Any,1}

julia> push!(arr, sin)
1-element Array{Any,1}:
 sin

```

---

<div class="post-metadata">

**Author:** ![roi.holtzman](https://avatars.discourse-cdn.com/v4/letter/r/f05b48/32.png) [@roi.holtzman](https://discourse.julialang.org/u/roi.holtzman)\
**Post date:** [April 1, 2019, 8:21am UTC](https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588/4 "2019-04-01T08:21:59Z")

</div>

> [@anon67531922](#):
>
> At this step, you have created a 1-element array of `Function` types with the first element initialized to `undef` .

What does the `undef` here mean?  
I thought that `undef` here is the way to initialize an array as written in the documentation:  
`Array{T}(undef, dims)` . So I do not understand why `arr2 = Array{Function}(undef, 1)` does not give an initialized array of function with dimension 1.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 1, 2019, 8:25am UTC](https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588/5 "2019-04-01T08:25:08Z")

</div>

> [@Tamas\_Papp](#):
>
> you might as well use `Any`

Using a more tightly type can prevent bugs if all you intended to put into the vector was `Function`. In addition, the comment

> [@Tamas\_Papp](#):
>
> since `Function` is not a concrete type, there is no speed gain from specifying it

is not always true. Julia can use partial type information (e.g. [Union-splitting: what it is, and why you should care](https://julialang.org/blog/2018/08/union-splitting)).

---

<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:** [April 1, 2019, 8:30am UTC](https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588/6 "2019-04-01T08:30:15Z")

</div>

> [@roi.holtzman](#):
>
> What does the `undef` here mean?  
> I thought that `undef` here is the way to initialize an array as written in the documentation

I think you misunderstood something, `undef` explicitly means that elements are _not_ initialized and can have arbitrary (for concrete bits types) or undefined values.

---

<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:** [April 1, 2019, 8:34am UTC](https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588/7 "2019-04-01T08:34:18Z")

</div>

> [@kristoffer.carlsson](#):
>
> Using a more tightly type can prevent bugs if all you intended to put into the vector was `Function` .

Generally, this is may be a good strategy, but not with `Function`, since it does not cover all things that can act like functions for practical purposes, eg

```julia
julia> struct Foo end

julia> (::Foo)(x) = x + 1

julia> g = Foo()
Foo()

julia> g(1)
2

julia> Foo <: Function
false

```

---

<div class="post-metadata">

**Author:** ![anon67531922](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@anon67531922](https://discourse.julialang.org/u/anon67531922)\
**Post date:** [April 1, 2019, 8:38am UTC](https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588/8 "2019-04-01T08:38:29Z")

</div>

Hi @roi.holtzman 👋

If you are trying to optimize for speed, it is good to stay away from pushing elements to a vector because that will lead to resizing and allocations etc. So it is better to start with an initialized array and then assign values to it.

So if you want a 1-element array of `Function` types with the first element equal to `sin`, there are several ways to do it:

If you are not sure how many elements there will be, you can start with an array constructor with array argument:

```julia
arr = Vector{Function}([sin])
1-element Array{Function,1}:
 sin

```

and then you can `push!` more functions to this array.

If you know how many elements there will be in your array, e.g. 10, it is probably better to initialize the array first

```julia
arr = Array{Function}(undef,10)

```

and then assign them one by one, e.g.

```julia
arr[1] = sin

```

Depending on where your functions are coming from, you can use iterators:

```julia
julia> ftup = (sin,cos,tan)
(sin, cos, tan)

julia> [f for f in ftup]
3-element Array{Function,1}:
 sin
 cos
 tan

```

Getting back to your example, you had

```julia
arr = Array{Function}(undef,1)

```

which creates a 1-element array whose element is undefined and then you can set it to `sin` via

```julia
arr[1] = sin

```

I hope that helps.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 1, 2019, 10:49am UTC](https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588/9 "2019-04-01T10:49:32Z")

</div>

> [@Tamas\_Papp](#):
>
> Generally, this is may be a good strategy, but not with `Function`

Even with `Function` if you know that you will not push callable objects into it.

---

<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:** [April 1, 2019, 11:14am UTC](https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588/10 "2019-04-01T11:14:37Z")

</div>

You are of course right; I just don’t think that this is generally good style in practical Julia code, as allowing `::Function` values but _not_ other callables is rarely a meaningful restriction.

I agree with your point in general, for most other abstract types, except for `Function`.

Also, I think that introducing `Function` to the language was perhaps a mistake, as it is generally misunderstood. Eg even `Base` and the standard libraries are full of definitions where `Callable`, or no restriction, would make much more sense.

---

<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:** [April 1, 2019, 11:47am UTC](https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588/11 "2019-04-01T11:47:04Z")

</div>

Since you want to `push!` to the vector, you should start with it _empty_ — ` Array{Function}(undef, 1)` is not empty, it has a single, undefined element. If you want it empty, it should be `Array{Function}(undef, 0)`.

To make an empty vector with elements of type `T`, you can write

```julia
arr = Vector{T}() 

```

But, in fact, there is a nicer and simpler syntax that I prefer: `T[]`. In your example that would become

```julia
arr = Function[]

```

In summary, you can write

```julia
Array{Function}(undef, 0)
Array{Function, 1}(undef, 0)
Array{Function, 1}()
Vector{Function}(undef, 0)
Vector{Function}()
Function[]

```

And probably some more. Note that `Array{Function}()` does _not_ work, because the compiler cannot tell if you want a 0 length vector, or a 0x0 matrix etc.

It’s a bit confusing with this many ways, I guess, but it all makes sense when you realize that `Vector{T}` is just an alias for `Array{T, 1}`, and that calling the constructors with `()` is equivalent to calling it with `(undef, 0)` if the constructor is `Array{T, 1}`, or `(undef, 0, 0)` if the constructor is `Array{T, 2}`, etc. If the constructor is just `Array{T}`, it becomes ambiguous, so be careful about using that.

In general, I prefer using `Vector` over `Array` because it’s clearer and less error prone (you often forget the `, 1`) . But in this concrete case `Function[]` wins for me.

---

<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:** [April 1, 2019, 11:51am UTC](https://discourse.julialang.org/t/cant-push-a-function-into-a-function-array/22588/12 "2019-04-01T11:51:22Z")

</div>

If you already have an initial element to start with, like `sin`, you can write:

```julia
arr = Function[sin]

```

If you just write `arr = [sin]`, then `arr` will be restricted to containing only elements of type `typeof(sin)`.

This is, BTW, faster than this suggestion

> [@anon67531922](#):
>
> ```julia
> arr = Vector{Function}([sin])
> 1-element Array{Function,1}:
> sin
> 
> ```

because here you first allocate an array `Vector{typeof(sin)}` and then convert it to a `Vector{Function}`.
