Consider two simple functions that take one `Float64`

and return another `Float64`

:

```
julia> f(x) = x^2
f (generic function with 1 method)
julia> g(x) = x^3
g (generic function with 1 method)
```

Also, consider a higher-order function that takes a function and returns another function:

```
julia> h(fun::Function) = x -> 2fun(x)
h (generic function with 1 method)
julia> h(f)(2.)
8.0
julia> h(g)(2.)
16.0
```

Now, I want to apply `h`

to an array of functions. However, such operation’s type stability depends on whether the array is homogeneous or not:

```
julia> fun_homog = [g, g]
2-element Array{#g,1}:
g
g
julia> fun_inhomog = [g, h]
2-element Array{Function,1}:
g
h
julia> @code_warntype broadcast(h, fun_homog)
(No instability)
julia> @code_warntype broadcast(h, fun_inhomog)
(Lots of instability)
```

The point here is that `fun_homog`

's element type is `#g`

, whereas `fun_inhomog`

's element type is abstract `Function`

.

I wonder if this kind of instability can be eliminated by allowing function type specification (like C’s function pointer). Clearly, `f`

and `g`

here are of the same type, in the sense that both take one `Float64`

and return another `Float64`

. However, currently once an array `[f, g]`

is formed, the array does not recognize such similarity between `f`

and `g`

.

In other words, I wonder if the array `[f, g]`

can be typed as something like `Array[::Function(::Float64)::Float64]`

to indicate that the array’s elements are functions that take one `Float64`

and return another `Float64`

, and also wonder if such information could be used to eliminate the aforementioned type instability.