# Passing arrays with unspecified type

**URL:** <https://discourse.julialang.org/t/passing-arrays-with-unspecified-type/39407>\
**Category:** General Usage\
**Created:** [May 13, 2020, 2:08pm UTC](https://discourse.julialang.org/t/passing-arrays-with-unspecified-type/39407 "2020-05-13T14:08:48Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [May 13, 2020, 2:08pm UTC](https://discourse.julialang.org/t/passing-arrays-with-unspecified-type/39407/1 "2020-05-13T14:08:48Z")

</div>

This is a question about efficiency. Suppose I have a routine which performs an operation in the same manner on an array irrespective of whether the entries are Int, Float or Complex. The output type will be an array with the same data-type. How can I implement that without overloading the function with different argument types ?  
For example, consider the simple function

```julia
function f(a::Array{Float64,1}) ::Array{Float64,1}
 for i in 1:size(a,1)
  a[i]*=i;
 end
end

```

The actual body of the funciton is not relevant, in reality it will be something more complicated. If I want this function to work for Int64 and Complex{Float64} arrays too, do I need to repeat the definition but with different argument types ? I have read in Julia’s performance enhancing tips that specifying the data type can lead to more efficient use of time and memory. IS there a trade-off ?

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [May 13, 2020, 2:28pm UTC](https://discourse.julialang.org/t/passing-arrays-with-unspecified-type/39407/2 "2020-05-13T14:28:49Z")

</div>

As a general rule, it is important to label fields of a _struct_ or the elements of a container you are constructing with their types, but you _do not_ need to label the types of your function inputs for performance. In fact, it says so right here in the manual: [Performance Tips · The Julia Language](https://docs.julialang.org/en/v1/manual/performance-tips/index.html#Type-declarations-1)

> In many languages with optional type declarations, adding declarations is the principal way to make code run faster. This is _not_ the case in Julia. In Julia, the compiler generally knows the types of all function arguments, local variables, and expressions.

What that means is that any of the following function definitions will give _exactly the same performance_:

```julia
function f1(a) # matches any `a`; equivalent to `a::Any`
  ...
end

function f2(a::AbstractArray) # matches an array with any number of dimensions
  ...
end

function f3(a::AbstractVector) # matches an array with exactly one dimension
  ...
end

function f4(a::AbstractVector{<: Number}) # matches an array with exactly one dimension
                                           # whose elements are all some kind of `Number`
  ...
end

function f5(a::Vector{Float64}) # matches only exactly a Vector of Float64
  ...
end

```

Try it! Define each of those functions and install BenchmarkTools.jl via:

```julia
]add BenchmarkTools

```

and then do:

```julia
using BenchmarkTools
@btime f1($a)
@btime f2($a)
@btime f3($a)
@btime f4($a)
@btime f5($a)

```

So why would you choose `f4` instead of `f1` ? Adding types to your function arguments is a matter of API design. If you define an `f4(a::AbstractVector{<:Number})`, then you can also define `f4(a::SomeOtherType)` and the compiler will automatically pick the appropriate method for whatever input is passed in. Or you might choose to specify your argument types as a signal to users of your code so that they know what you’re expecting them to provide.

---

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [May 13, 2020, 2:36pm UTC](https://discourse.julialang.org/t/passing-arrays-with-unspecified-type/39407/3 "2020-05-13T14:36:38Z")

</div>

This is extremely useful, including the comparative tests ! Thank you very much for your time and effort !

---

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [May 19, 2020, 11:45pm UTC](https://discourse.julialang.org/t/passing-arrays-with-unspecified-type/39407/4 "2020-05-19T23:45:15Z")

</div>

A follow-up question : suppose I wish to pass an argument which is Array of arbitrary type but exactly 2 dimensions. What would be the syntax ?

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [May 20, 2020, 1:17am UTC](https://discourse.julialang.org/t/passing-arrays-with-unspecified-type/39407/5 "2020-05-20T01:17:16Z")

</div>

If you mean an array with 2 elements, like `[3, 4]`, then the answer is that you cannot restrict the length of an array like that, since the _type_ of a standard Julia array does not contain the information about its length.

A good alternative would be to use a _tuple_ instead:

```julia
julia> f(x, (y, z)) = x * (y + z)
f (generic function with 1 method)

julia> f(1, (2, 3))
5

```

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [May 20, 2020, 1:54am UTC](https://discourse.julialang.org/t/passing-arrays-with-unspecified-type/39407/6 "2020-05-20T01:54:26Z")

</div>

Or you can check out StaticArrays for small fixed-size arrays: [https://github.com/JuliaArrays/StaticArrays.jl](https://github.com/JuliaArrays/StaticArrays.jl)

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [May 20, 2020, 2:05am UTC](https://discourse.julialang.org/t/passing-arrays-with-unspecified-type/39407/7 "2020-05-20T02:05:43Z")

</div>

What you are probably looking for here is a `Tuple` not an `Array`. The difference is that `Tuples` allow inference on small statically sized heterogeneous collections.

---

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [May 20, 2020, 2:48am UTC](https://discourse.julialang.org/t/passing-arrays-with-unspecified-type/39407/8 "2020-05-20T02:48:20Z")

</div>

@Oscar_Smith @rdeits @dpsanders I apologize, I meant 2 dimensional array as input with unspecified data-type.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [May 20, 2020, 3:04am UTC](https://discourse.julialang.org/t/passing-arrays-with-unspecified-type/39407/9 "2020-05-20T03:04:36Z")

</div>

Ah, that would be `f(a::AbstractMatrix)` or equivalently `f(a::AbstractArray{T, 2}) where T`
