struct A{T}
nothing
end
Can we use the name A without a parameter?
julia> A
A
Yes, how about with a type parameter?
julia> A{Int64}
A{Int64}
no problem. But:
function b{T}(x::T)
return x
end
b (generic function with 1 method)
Name ‘b’ without parameter?
julia> b
b (generic function with 1 method)
yes, but
julia> b{Int64}
ERROR: TypeError: Type{…} expression: expected UnionAll, got #b
Stacktrace:
[1] macro expansion at ./REPL.jl:97 [inlined]
[2] (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:73
Naming the function with a type parameter gives a (strange!) error
Seems inconsistent to this naive user, and the message seems mysterious.
I agree that this can be confusing. Fortunately, Julia v0.6 introduces a new syntax for b
:
function b(x::T) where T
return x
end
which no longer (incorrectly) implies that you could write b{Int}
.
1 Like
To expand on this a little, in Julia there are two types of constructors
-
Inner: these accept type parameters (i.e. the arguments in the
{}
) and are declared inside the type
declaration. i.e. they are called like XType{T}(args...)
-
Outer: these do not take any type parameters and are declared outside of the
type
declaration. i.e. they are called like XType(args...)
.
This seems quite confusing at first, but is actually quite useful as it is helpful to be able to declare either type of constructor. However, like @rdeits pointed out, there is now an additional syntax available for sorting this out.
The only “inconsistency” is that we don’t allow explicitly specifing the type parameters for a method. And that’s also related to that type cannot be overload but functions can.
2 Likes