# Vector{Real}, Vector{Float64} MethodError

**URL:** <https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926>\
**Category:** New to Julia\
**Created:** [July 2, 2019, 2:05pm UTC](https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926 "2019-07-02T14:05:09Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![jamblejoe](https://avatars.discourse-cdn.com/v4/letter/j/ee7513/32.png) [@jamblejoe](https://discourse.julialang.org/u/jamblejoe)\
**Post date:** [July 2, 2019, 2:05pm UTC](https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926/1 "2019-07-02T14:05:09Z")

</div>

Hi,  
the following code runs fine:

```julia
function h(x::Real)
    println(x)
end

function j(x::Float64)
    println(x)
end

arr2 = [1.0, 2.0]
h(arr2[1])
j(arr2[1])

```

giving me

> 1.0  
> 1.0

But this code

```julia
function f(v::Vector{Real})
    println(v)
end

function g(v::Vector{Float64})
    println(v)
end

arr = [[1.0, 1.0], [1.0, 2.0]]
g(arr[1])
f(arr[1])

```

errors with

> [1.0, 1.0]

> MethodError: no method matching f(::Array{Float64,1})  
> Closest candidates are:  
> f(!Matched::Array{Real,1}) at In[2]:2
> 
> Stacktrace:  
> [1] top-level scope at In[2]:12

Why that and what am I doing wrong? I thought you can put Float64 everywhere where you can put Real in…

---

<div class="post-metadata">

**Author:** ![aharoun](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aharoun/32/6887_2.png) [@aharoun](https://discourse.julialang.org/u/aharoun)\
**Post date:** [July 2, 2019, 2:19pm UTC](https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926/2 "2019-07-02T14:19:40Z")

</div>

> [@jamblejoe](#):
>
> I thought you can put Float64 everywhere where you can put Real in…

That is not true. Specifically

```julia
julia> Float64<:Real
true

```

but

```julia
julia> Vector{Float64}<:Vector{Real}
false

```

This property of the type system is explained in the manual:  
[https://docs.julialang.org/en/v1/manual/types/index.html#Parametric-Composite-Types-1](https://docs.julialang.org/en/v1/manual/types/index.html#Parametric-Composite-Types-1)  
Especially notice the warning there.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [July 2, 2019, 4:14pm UTC](https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926/3 "2019-07-02T16:14:48Z")

</div>

You probably want

```julia
function f(v::Vector{<:Real})
    println(v)
end

```

which is (roughly) shorthand for

```julia
function f(v::Vector{T}) where {T<:Real}
    println(v)
end

```

---

<div class="post-metadata">

**Author:** ![jamblejoe](https://avatars.discourse-cdn.com/v4/letter/j/ee7513/32.png) [@jamblejoe](https://discourse.julialang.org/u/jamblejoe)\
**Post date:** [July 2, 2019, 4:59pm UTC](https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926/4 "2019-07-02T16:59:08Z")

</div>

@aharoun Thanks for the quick answer!  
So changing the code to (as mentioned in the manual)

```julia
function f(v::Vector{<:Real})
    println(v)
end
f(arr[1])

```

works and gives

> [1.0, 1.0]

as answer. So far, so good! @tkoolen Thanks for the answer as well! I just typed this in as I saw your post.

I read through the manual and understand the performance issues mentioned there. But I thought that the compiler would compile different versions of the same function for different arguments anyway. Why the need for the difference

```julia
Vector{<:Real}

```

and

```julia
Vector{Real}

```

?

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [July 2, 2019, 5:13pm UTC](https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926/5 "2019-07-02T17:13:48Z")

</div>

First, a bit of background. In Julia, there are no instances of abstract types. For example, `typeof(1) == Int`. `Int` is indeed a `Real` so `1 isa Real` is true, however `typeof(1) == Real` is **false**. You can think of the type system as a directed acyclic graph in which the concrete types are the leaves.

If you have a `Vector{Real}`, this is a `Vector` the elements of which are `Real`s. However, they can be _any_ concrete type which is descended from `Real`. So, for example you can have `Real[1, 1.0]`, that is, a `Vector` with one element which is `Int` and another which is `Float64`. Because the container type is `Vector{Real}`, the compiler only knows that the elements are guaranteed to be `Real`, but it does not know what concrete type they are. They could be, `Int`, `Float16`, `UInt8`, who knows.

When you write `Vector{<:Real}` this is the _union_ of all `Vector`s the elements of which are real, for example

```julia
julia> Vector{Real} <: Vector{<:Real}
true

julia> Vector{Int} <: Vector{<:Real}
true

julia> Vector{Float64} <: Vector{<:Real}
true

```

As should be becoming clear, it is “better” for performance reasons to have a `Vector{Float64}` than a `Vector{Real}` in which all of the elements happen to be `Float64`. This is because `Vector{Float64}` guarantees to the compiler that the elements are all `Float64`, whereas for `Vector{Real}` the elements can be any `Real` type.

So, back to the type signatures of functions. When you write `Vector{Real}` on an argument, you are requiring that the input be a `Vector{Real}` (perhaps confusingly, `Vector{Real}` is itself a concrete type, even though it has an abstract type as a parameter). In the vast majority of such instances, what you really want is to get a `Vector` the elements of which are `Real`. Yes, this could be `Vector{Real}`, but it can just as well be `Vector{Int}` or `Vector{Float32}` or `Vector{BigFloat}`. This is what `Vector{<:Real}` is telling it, the parameter of `Vector` must be a subtype of `Real`, but not necessarily equal to `Real`.

---

<div class="post-metadata">

**Author:** ![jamblejoe](https://avatars.discourse-cdn.com/v4/letter/j/ee7513/32.png) [@jamblejoe](https://discourse.julialang.org/u/jamblejoe)\
**Post date:** [July 2, 2019, 5:26pm UTC](https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926/6 "2019-07-02T17:26:48Z")

</div>

@ExpandingMan Thanks for this quick and detailed answer! Concluding for that, I would use the case

```julia
f(v::Vector{<:Real})

```

most often and only

```julia
f(v::Vector{Float64})

```

or

```julia
f(v::Vector{Int})

```

if I really need to do something fancy - e.g. bit-shifting would come to my mind or if I operate near memory bounds and need to restrict on how much I can store-, which crucially depends on how the numbers are stored in memory. I can not come up with a use case for

```julia
f(v::Vector{Real})

```

though. For what is it good then? Am I still getting something wrong?

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [July 2, 2019, 5:35pm UTC](https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926/7 "2019-07-02T17:35:34Z")

</div>

Indeed, I’ve been using the language extensively for almost 4 years and I have a hard time coming up with cases in which `Vector{Real}` is actually useful, especially as a type signature. In my experience, getting types correct can be a lot more difficult once IO is involved, so, for example, you might have a CSV parser which parses a file that has entries in a particular column like `1, 1.0, 2, 2.0` and istead of promoting to a float type (probably the better choice in this case) just takes it literally. This example is a bit contrived however, the “standard” Julia CSV parser, CSV.jl, is by now getting fairly mature, and is much more sophisticated than this, so this wasn’t a realistic example. It is also conceivable that a `Vector{Real}` can get produced somewhere by a “bug” (e.g. a package developer had to do something fancy to infer types, perhaps because IO is involved, and this failed in a circumstance the developer did not foresee).

You can safely assume that encountering a `Vector{Real}` would be very unusual.

It’s worth pointing out that `f(v::Vector{<:Real})` _does_ accept a `Vector{Real}` as an argument.

One other thing to add: most of the time you probably will want to go a step further and write `AbstractVector{<:Real}`. Julia and its common packages have a dizzying array of array types (pun intended) for all sorts of special purposes. One of the great strengths of Julia is that these tend to work together quite beautifully, precisely because Julia makes it easy to write some incredibly generic code, but this virtue is still dependent on developers not over-specializing their type signatures. `Vector` would basically assume that you are relying on a particular memory layout.

---

<div class="post-metadata">

**Author:** ![jamblejoe](https://avatars.discourse-cdn.com/v4/letter/j/ee7513/32.png) [@jamblejoe](https://discourse.julialang.org/u/jamblejoe)\
**Post date:** [July 2, 2019, 5:48pm UTC](https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926/8 "2019-07-02T17:48:38Z")

</div>

@ExpandingMan Thanks for pointing the IO example out. I will keep in mind that my parsed numbers will have the the correct type. So far I am writing code in Julia purely for my own scientific use - but this (hopefully) will change soon, as more people make the switch from MATLAB/Python to Julia for the computational part of their projects.

Thanks for pointing the `AbstractVector{<:Real}` possibility out! I will use that. I assume for the same reason one should use `AbstractArray` as well?

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [July 2, 2019, 5:52pm UTC](https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926/9 "2019-07-02T17:52:33Z")

</div>

> [@jamblejoe](#):
>
> I assume for the same reason one should use `AbstractArray` as well?

`AbstractArray` is a little different. `AbstractArray` is an array of arbitrary rank, where `AbstractVector == AbstractArray{T,1} where {T}` is necessarily rank 1. So it depends on your use case. If you expect your argument to be just an arbitrary iterable, you might even consider not even having a type signature for it at all, since you could just as well get a `Tuple`, but in those cases as often as not `AbstractArray` does just fine. If you are expecting a rank-1 object for whatever reason (maybe you are taking an inner product or whatever), you shouldn’t hesitate to use `AbstractVector`.

The rule of thumb is usually to choose the most general type for which the logic in your function makes sense (even if this involves omitting the type signature altogether).

---

<div class="post-metadata">

**Author:** ![jamblejoe](https://avatars.discourse-cdn.com/v4/letter/j/ee7513/32.png) [@jamblejoe](https://discourse.julialang.org/u/jamblejoe)\
**Post date:** [July 2, 2019, 5:56pm UTC](https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926/10 "2019-07-02T17:56:58Z")

</div>

@ExpandingMan Ok, I got this! Thank you very much! Your posts helped me a lot in understanding which types to use for declaring arguments!

---

<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:** [July 2, 2019, 5:57pm UTC](https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926/11 "2019-07-02T17:57:00Z")

</div>

It’s worth noting that there’s no magic involved here: the complete definition of `AbstractVector` is:

```julia
const AbstractVector{T} = AbstractArray{T,1}

```

(see [https://github.com/JuliaLang/julia/blob/042504df01e1ecdaf650390aabd82989907bde0c/base/array.jl#L23](https://github.com/JuliaLang/julia/blob/042504df01e1ecdaf650390aabd82989907bde0c/base/array.jl#L23) )

---

<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:** [July 3, 2019, 12:57pm UTC](https://discourse.julialang.org/t/vector-real-vector-float64-methoderror/25926/12 "2019-07-03T12:57:03Z")

</div>

> [@ExpandingMan](#):
>
> It’s worth pointing out that `f(v::Vector{<:Real})` _does_ accept a `Vector{Real}` as an argument.

At the same time, it is probably not a useful restriction for dispatch, since it will not accept eg `Any[1.0, 2.0, 3.0]`, which is a perfectly valid vector of `Float64`, and in a well-designed API any method that works for `[1.0, 2.0, 3.0]` should work for that, too.
