# Why isn't this type signature allowed?

**URL:** <https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170>\
**Category:** New to Julia\
**Tags:** parametric-methods\
**Created:** [August 2, 2022, 2:46pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170 "2022-08-02T14:46:49Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [August 2, 2022, 2:46pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/1 "2022-08-02T14:46:49Z")

</div>

Given that functions `f`, `g`, and `h` all work, why isn’t function `i` allowed?  
Shouldn’t `i` work like an alias for `g` just like `h` does?

```julia
x = 1
y = 0.1
function f(x::Number, y::Number)
    return "This is function f."
end
function g(x::T1 where T1<:Number, y::T2 where T2<:Number)
    return "This is function g."
end
function h(x::Vector{<:Number}, y::Vector{<:Number}) # Call with h([x], [y])
    return "This is function h."
end
function i(x<:Number, y<:Number)
    return "This is function i."
end

```

```julia
ERROR: syntax: "x <: Number" is not a valid function argument name

```

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [August 2, 2022, 2:51pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/2 "2022-08-02T14:51:07Z")

</div>

It’s unclear if you’re referring to the type of the argument, or if the type _is_ the argument

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [August 2, 2022, 2:53pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/3 "2022-08-02T14:53:50Z")

</div>

Is that different from `h`? I could have a vector of types.

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [August 2, 2022, 3:00pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/4 "2022-08-02T15:00:52Z")

</div>

A `Vector{<:Number}` is a vector of values, each of which is a `Number`. It’s not a vector of types

---

<div class="post-metadata">

**Author:** ![kellertuer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kellertuer/32/220707_2.png) [@kellertuer](https://discourse.julialang.org/u/kellertuer)\
**Post date:** [August 2, 2022, 3:10pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/5 "2022-08-02T15:10:34Z")

</div>

> [@Nathan\_Boyer](#):
>
> ```julia
> function i(x<:Number, y<:Number)
> return "This is function i."
> end
> 
> ```

For me (even in reading) it is not clear for this whether you mean that `x` is a _type_ that inherits from number or a variable of a type that inherits from number.

_edit_: To be more precise, you could pass `x=Float64` in there, which is one way to read your definition, but since it is not clear what you mean (informally reading it for me it does not get clear at least, but the compiler also complains)

I do see two solutions with different goals. You probably meant

```julia
function i(x::T, y::S) where {T<:Number, S<:Number}
    return "This is function i."
end

```

that is x and y are some kind of numbers (informally said).  
This is basically your `g` just that the scope of the `T` and `S` is a little larger, because you could also do

```julia
function i(x::T, y::T) where {T<:Number}
    return "This is function i."
end

```

which would say they are some kind of number, but the same.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [August 2, 2022, 3:15pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/6 "2022-08-02T15:15:57Z")

</div>

> [@kellertuer](#):
>
> For me (even in reading) it is not clear for this whether you mean that `x` is a _type_ that inherits from number or a variable of a type that inherits from number.

Yup, this is the crux – `x::T` works when `x` are values, `x<:T` works for types `x` (of course any `x` can be both a value and type, but the operator gives context then). Function arguments are always treated as values, so you can’t `<:` them.

---

<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:** [August 2, 2022, 3:30pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/7 "2022-08-02T15:30:13Z")

</div>

> [@Nathan\_Boyer](#):
>
> I could have a vector of types.

In that case, you can use

```julia
function h(x::Vector{Type{<:Number}}, y::Vector{Type{<:Number}})
    return "This is function h."
end

```

Interestingly, this will fail:

```julia
julia> h([Int], [Float32])
ERROR: MethodError: no method matching h(::Vector{DataType}, ::Vector{DataType})

```

because

```julia
julia> typeof([Int])
Vector{DataType}

```

You have to enforce the eltype:

```julia
julia> h(Type{Int}[Int], Type{Float32}[Float32])
"This is function h."

```

Similarly, `i` could be

```julia
function i(x::Type{<:Number}, y::Type{<:Number})
    return "This is function i."
end

```

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [August 2, 2022, 3:43pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/8 "2022-08-02T15:43:31Z")

</div>

I’m starting to get it.  
`f` just doesn’t seem like it should work to me. `x` is not a `Number` it is an `Int` which is a subtype of `Number`. Thus I want to indicate that with `x<:Number` just like in `h`.

Also, DNF showed that you have to explicitly write `Type` whenever you want to operate on types themselves, so the type vs value argument seems clear regardless.

---

<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:** [August 2, 2022, 4:02pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/9 "2022-08-02T16:02:46Z")

</div>

> [@Nathan\_Boyer](#):
>
> `f` just doesn’t seem like it should work to me. `x` is not a `Number` it is an `Int` which is a subtype of `Number`.

But `x` _is_ a `Number`:

```julia
julia> 1 isa Number
true

```

That is how subtype relationships work. For any value of type `T`, that value is also belongs to the supertypes of `T`:

```julia
julia> isa.(1, (Int, Signed, Integer, Real, Number, Any))
(true, true, true, true, true, true)

```

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [August 2, 2022, 4:12pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/10 "2022-08-02T16:12:03Z")

</div>

I see. So the Vector equivalent to `f` is `j`:

```julia
function j(x::Vector{Number}, y::Vector{Number})
    return "This if function j."
end

```

```julia
julia> j(Vector{Number}([x]), Vector{Number}([y]))
"This if function j."

```

---

<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:** [August 2, 2022, 4:23pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/11 "2022-08-02T16:23:44Z")

</div>

> [@Nathan\_Boyer](#):
>
> So the Vector equivalent to `f` is `j`:
> 
> ```julia
> function j(x::Vector{Number}, y::Vector{Number})
> return "This if function j."
> end
> 
> ```

Almost, but not quite. Due to type in variance, `Vector{Int}` is not a subtype of `Vector{Number}`. The equivalent is

```julia
function j(x::Vector{<:Number}, y::Vector{<:Number})
    return "This if function j."
end

```

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [August 2, 2022, 6:25pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/12 "2022-08-02T18:25:43Z")

</div>

Yes, I do know that fact and have it as function `h`. Although I guess I don’t fully understand since `j` works as I expected but `k` doesn’t:

```julia
struct MyType{T<:Number}
    x::T
end
function k(x::Vector{MyType{<:Number}})
    return "This is function k."
end

```

```julia
julia> k([MyType(x)])
ERROR: MethodError: no method matching k(::Vector{MyType{Int64}})
Closest candidates are:
  k(::Vector{MyType})

```

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [August 2, 2022, 6:49pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/13 "2022-08-02T18:49:21Z")

</div>

Try

```julia
function k(x::Vector{<:MyType{<:Number}})

```

---

<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:** [August 2, 2022, 6:59pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/14 "2022-08-02T18:59:23Z")

</div>

You can also write

```julia
function k(x::Vector{MyType{T}}) where {T<:Number}

```

I was a bit surprised, because I though that `Vector{MyType{<:Number}}` was the same as `Vector{MyType{T}} where {T<:Number}`. But it turns out to be a tiny bit different:

```julia
julia> Vector{MyType{<:Number}} === Vector{MyType{T}} where {T<:Number}
false

julia> Vector{MyType{<:Number}} === Vector{MyType{T} where {T<:Number}}
true

```

The difference is the location of the closing `}`s.

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [August 2, 2022, 7:14pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/15 "2022-08-02T19:14:12Z")

</div>

> [@GunnarFarneback](#):
>
> Try
> 
> ```julia
> function k(x::Vector{<:MyType{<:Number}})
> 
> ```

Yes, but why?  
What is the full identical equivalence for this form?

> [@DNF](#):
>
> The difference is the location of the closing `}`s.

I don’t see how that would make a functional difference. The `where` defines `T` the same either way, and the `where` location doesn’t matter in this case from the [documentation](https://docs.julialang.org/en/v1/manual/types/#man-parametric-composite-types):

> A correct way to define a method that accepts all arguments of type `Point{T}` where `T` is a subtype of [`Real`](https://docs.julialang.org/en/v1/base/numbers/#Core.Real) is:
> 
> ```julia
> function norm(p::Point{<:Real})
> sqrt(p.x^2 + p.y^2)
> end
> 
> ```
> 
> (Equivalently, one could define `function norm(p::Point{T} where T<:Real)` or `function norm(p::Point{T}) where T<:Real`; see [UnionAll Types](https://docs.julialang.org/en/v1/manual/types/#UnionAll-Types).)

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 2, 2022, 7:15pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/16 "2022-08-02T19:15:41Z")

</div>

> [@DNF](#):
>
> The difference is the location of the closing `}`s.

Or, more semantically, whether the vector has to contain elements of the same `MyType` which all are constrained to the same `T<:Number`, or whether the vector can contain different `MyType`, possibly with different `T` (each of which is still constrained to be `<:Number`).

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 2, 2022, 7:17pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/17 "2022-08-02T19:17:58Z")

</div>

> [@Nathan\_Boyer](#):
>
> I don’t see how that would make a functional difference. The `where` defines `T` the same either way, and the `where` location doesn’t matter in this case from the [documentation](https://docs.julialang.org/en/v1/manual/types/#man-parametric-composite-types):

The case you quote from the docs is not the same, because that only has one level of type parameters.

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [August 2, 2022, 7:20pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/18 "2022-08-02T19:20:56Z")

</div>

Ah, thanks. That makes sense.

The shorthand version from Gunnar doesn’t equal the longhand version from DNF though. What does it expand to?

```julia
julia> Vector{<:MyType{<:Number}} === Vector{MyType{T}} where {T<:Number}
false

```

Also, how can these all be true?

```julia
julia> isconcretetype(Vector{MyType})
true

julia> isconcretetype(Vector{MyType{Int}})
true

julia> isconcretetype(Vector{MyType{<:Number}})
true

```

(This one is false: ` isconcretetype(Vector{<:MyType{<:Number}})`.)

---

<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:** [August 2, 2022, 7:30pm UTC](https://discourse.julialang.org/t/why-isnt-this-type-signature-allowed/85170/19 "2022-08-02T19:30:58Z")

</div>

At least we have

```julia
julia> (Vector{MyType{T}} where {T<:Number}) <: Vector{<:MyType{<:Number}}
true

```
