jw3126
February 23, 2017, 3:06pm
1
From time to time I want to define a new type and have to introduce some redundant type parameters to do so.
For example I could want arrays that live in coordinate systems. In 0.5 I have to do something like
immutable CoordinateArray{A, C, T, N} <: AbstractArray{T, N}
coordinates::A
CoordinateArray(v) = new(CoordinateArray{T,N}(v))
end
However the T,N
parameters lead to all kinds of annoyances. They are a hack, which obfuscates
displaying and every now and then the fact that CoordinateArray{A, C}
is not a leaftype, forces
one to bookkeep them.
Is it possible to do something like
struct CoordinateArray{A <: AbstractArray{T, N}, C} <: AbstractArray{T, N}
coordinates::A
end
in 0.6? If not is something planned in this direction?
2 Likes
Yes, that’s “triangular dispatch” (nesting of type information like A<: B{C}
where C<:D
where …, though here you’re not talking about dispatch so it’s not the correct term?), and it’s possible in v0.6.
You may want to read this part of the news:
Julia v1.11 Release Notes
========================
New language features
---------------------
* `public` is a new keyword. Symbols marked with `public` are considered public
API. Symbols marked with `export` are now also treated as public API. The
difference between `public` and `export` is that `public` names do not become
available when `using` a package/module ([#50105]).
* `ScopedValue` implement dynamic scope with inheritance across tasks ([#50958]).
* The new macro `Base.Cartesian.@ncallkw` is analogous to `Base.Cartesian.@ncall`,
but allows to add keyword arguments to the function call ([#51501]).
* Support for Unicode 15.1 ([#51799]).
* A new `AbstractString` type, `AnnotatedString`, is introduced that allows for
regional annotations to be attached to an underlying string. This type is
particularly useful for holding styling information, and is used extensively
in the new `StyledStrings` standard library. There is also a new `AnnotatedChar`
type, that is the equivalent new `AbstractChar` type.
Language changes
This file has been truncated. show original
jw3126
February 23, 2017, 4:41pm
3
Thanks, I am aware of triangular dispatch, but I was not able to do the above example (I both searched the manual and tried variations of the above).
julia> struct CoordinateArray{A <: AbstractArray{T, N}, C} <: AbstractArray{T, N}
coordinates::A
end
ERROR: UndefVarError: T not defined
Can you point me to the correct syntax?
I think you need to where T where N
or something like that?
You don’t necessarily need where
julia> struct CoordinateArray{T,N,A<:AbstractArray{T,N},C} <: AbstractArray{T,N}
coordinates::A
end
I see, that’s the first bulletin:
Type parameter constraints can refer to previous parameters, e.g. type Foo{R<:Real, A<:AbstractArray{R}}. Can also be used in method definitions.
Ideally, it would be great to write the signature as
struct Foo{A<:AbstractArray{T,N}} <: AbstractArray{T,N} where T, N
end
But I don’t think this is possible (would love to be corrected).
3 Likes
jw3126
February 23, 2017, 5:24pm
8
Okay you got rid of the inner constructor, but CoordinateArray
has still 4 explicit parameters {T,N,A,C}
in your version. The goal was to get rid of N,T
.
mbauman
February 23, 2017, 5:24pm
9
I don’t think this can be accomplished through the new type-system alone… the missing feature is probably computed subtyping: https://github.com/JuliaLang/julia/issues/8322
struct Foo{A<:AbstractArray} <: AbstractArray{eltype(A),ndims(A)}
end
3 Likes