Say I have two types that are both subtypes of an abstract type
abstract A
type B <: A
x
y
z
end
type C <: A
x
y
z
w
end
is there any way of creating C without having to basically copy/paste B and add the extra parameters? The main issue is that B and C are really close and I would prefer as little code duplication as possible. I know the manual says that concrete types can't subtype each other:
One particularly distinctive feature of Julia’s type system is that concrete types may not subtype each other: all concrete types are final and may only have abstract types as their supertypes.
Is there any way around this?
In these cases I usually prefer to compose my types.
Here is an example of what I mean:
abstract A
type B <: A
x
y
z
end
type C <: A
b::B
w
end
Notice how C is still a subtype of A, but contains an instance of B as a field.
It is true that you can no longer access c.x, but rather you have to do c.b.x. There is a simple way around this.
Suppose you have a function
function my_func(a::A)
# do something with a.x, a.y, a.z
end
If my_func is supposed to work with any subtype of A, it can only access fields that are common across all subtypes of A. In this case that is x, y, and z.
Knowing that, I would also define a specialized version of that method to dispatch on instances of C as follows:
my_func(c::C) = my_func(c.b)
This is a bit more verbose, but you can easily wrap all these functions in a metaprogramming for loop that uses @eval and generate them all at once. See docs for more info
I would do
type XYZ
x
y
z
end
type B <: A
xyz::XYZ
end
type C <: A
xyz::XYZ
w
end
Of course, for performance reason I normally use immutable as well as annotate as much types as possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With