That advice still holds: type-fields used in performance critical parts of a code should have a concrete type. If you want the type-field to hold a range of types you need to parameterize the type.
You can check that yourself (using the linked example):
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: http://docs.julialang.org
_ _ _| |_ __ _ | Type "?help" for help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.6.0-dev.2826 (2017-02-14 13:01 UTC)
_/ |\__'_|_|_|\__'_| | Commit 2ecc2157c5* (12 days old master)
|__/ | x86_64-pc-linux-gnu
julia> type MySimpleContainer{A<:AbstractVector}
a::A
end
julia> type MyAmbiguousContainer{T}
a::AbstractVector{T}
end
julia> f(v) = v.a
f (generic function with 1 method)
julia> @code_warntype f(MySimpleContainer([1]))
Variables:
#self#::#f
v::MySimpleContainer{Array{Int64,1}}
Body:
begin
return (Core.getfield)(v::MySimpleContainer{Array{Int64,1}}, :a)::Array{Int64,1}
end::Array{Int64,1} # good
julia> @code_warntype f(MyAmbiguousContainer([1]))
Variables:
#self#::#f
v::MyAmbiguousContainer{Int64}
Body:
begin
return (Core.getfield)(v::MyAmbiguousContainer{Int64}, :a)::AbstractArray{Int64,1}
end::AbstractArray{Int64,1} # bad
That is a very helpful example, thanks. Would you not inherit from AbstractArray to get a bunch of functionality? I thought that was improved in v0.6.
Is there a good way to restrict the element type of v.a to be a subtype of Number and be performant? Similarly, if I try to restrict the eltype with a function call I run into problems:
julia> g{A<:AbstractVector,N<:Number}(m::MySimpleContainer{A{N}}) = "yes"
ERROR: TypeError: Type{...} expression: expected UnionAll, got TypeVar
julia> g(m::MySimpleContainer{A{N}}) where N<:Number where A<:AbstractVector = "yes"
ERROR: TypeError: Type{...} expression: expected UnionAll, got TypeVar
julia> g{A<:AbstractVector}(m::MySimpleContainer{A{<:Number}}) = "yes"
ERROR: TypeError: Type{...} expression: expected UnionAll, got TypeVar
julia> g{A<:AbstractVector}(m::MySimpleContainer{A}) where N<:Number where A <: AbstractVector{N}= "yes"
ERROR: UndefVarError: N not defined
julia> g{A<:AbstractVector}(m::MySimpleContainer{A}) where A<:AbstractVector{N} where N<:Number = "yes"
ERROR: TypeError: Type{...} expression: expected UnionAll, got #g
After reading the manual, I’m not sure how to use the where clause effectively.
Yes, but that is in 0.5 already (but maybe it improved). (But that is a different topic to the section of the manual you link to). See http://docs.julialang.org/en/stable/manual/interfaces/ for the bits you need to implement additionally.
type MySimpleContainer{A<:Number}
a::A
end
I struggle too . This seems ok:
g(m::MySimpleContainer{A}) where A<:AbstractVector{N} where N<:Number = "yes"