# Confused with type explicit declaration

**URL:** <https://discourse.julialang.org/t/confused-with-type-explicit-declaration/2618>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [March 12, 2017, 8:50am UTC](https://discourse.julialang.org/t/confused-with-type-explicit-declaration/2618 "2017-03-12T08:50:09Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![asbisen](https://avatars.discourse-cdn.com/v4/letter/a/a9a28c/32.png) [@asbisen](https://discourse.julialang.org/u/asbisen)\
**Post date:** [March 12, 2017, 8:50am UTC](https://discourse.julialang.org/t/confused-with-type-explicit-declaration/2618/1 "2017-03-12T08:50:09Z")

</div>

Hi All,

I am a little confused with the error I am getting with passing arguments to functions that have explicit type declaration. Per my understanding one should be able to pass an `Array{Float64,2}` to a function that expects `AbstractMatrix{AbstractFloat,2}`. Below is a sample code that explains the issue.

The question is why am I getting error with `predict1()` and why I need to call `convert(AbstractMatrix{AbstractFloat}, X)` in `predict2()` to make the function execute successfully.

```julia
function rescale{T<:AbstractFloat}(X::AbstractMatrix{T}, μ::Vector{T}, σ::Vector{T})
  Xnew = (X .- μ') ./ σ'
end

immutable Scale
  μ::Vector{AbstractFloat}
  σ::Vector{AbstractFloat}

  function Scale{T<:AbstractFloat}(μ::Vector{T}, σ::Vector{T})
    new(μ, σ)
  end
end

function Scale{T<:AbstractFloat}(X::AbstractMatrix{T})
  μ = mean(X, 1) |> vec
  σ = std(X, 1) |> vec
  Scale(μ, σ)
end

function fit{T<:AbstractFloat}(::Type{Scale}, X::AbstractMatrix{T})
  cs = Scale(X)
end

function predict1{T<:AbstractFloat}(cs::Scale, X::AbstractMatrix{T})
  Xnew = rescale(X, cs.μ, cs.σ)
end

function predict2{T<:AbstractFloat}(cs::Scale, X::AbstractMatrix{T})
  Xnew = rescale(convert(AbstractMatrix{AbstractFloat}, X), cs.μ, cs.σ)
end

function test1()
  X = rand(100, 80)
  clf = Scale(X)
  predict1(clf, X)
end

function test2()
  X = rand(100, 80)
  clf = Scale(X)
  predict2(clf, X)
end

```

Error with `predict1()`

```julia
julia> test1()
ERROR: MethodError: no method matching rescale(::Array{Float64,2}, ::Array{AbstractFloat,1}, ::Array{AbstractFloat,1})
Closest candidates are:
  rescale{T<:AbstractFloat}(::AbstractArray{T<:AbstractFloat,2}, ::Array{T<:AbstractFloat,1}, ::Array{T<:AbstractFloat,1}) at REPL[1]:2
Stacktrace:
 [1] predict1 at ./REPL[5]:2 [inlined]
 [2] test1() at ./REPL[7]:4

```

Thanks

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [March 12, 2017, 9:29am UTC](https://discourse.julialang.org/t/confused-with-type-explicit-declaration/2618/3 "2017-03-12T09:29:10Z")

</div>

The reason is that in your definition `Scale` holds `AbstracFloat`, `X` holds `Float64` and `rescale` requires common type `T` in three arguments.

If you define `Scale` as:

```julia
immutable Scale{T<:AbstractFloat}
  μ::Vector{T}
  σ::Vector{T}
end

```

Then `Scale` in `test1` will hold `Float64` and `test1` will work (but then `test2` will throw an error).

You might want to read about _invariance_ in Julia documentation [http://docs.julialang.org/en/stable/manual/types/#man-parametric-types](http://docs.julialang.org/en/stable/manual/types/#man-parametric-types).

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [March 12, 2017, 2:39pm UTC](https://discourse.julialang.org/t/confused-with-type-explicit-declaration/2618/4 "2017-03-12T14:39:39Z")

</div>

> [@bkamins](#):
>
> If you define Scale as:

Also note that this is just better for performance anyways. You never want to have unstrict typing of fields (when you can avoid it).
