Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Abstract types and inheritance in Julia

Suppose I define a function on an abstract type A in Julia:

abstract A
function mysum(a::A)
  a.x + a.y
end

Implicitly any subtype should have the fields x and y for this function to work. So the functions defined on A are what set the requirements for subtypes. These functions could be written anywhere and one can imagine a situation where the functions are much more complex and the requirements are harder to spot. Is there someway to declare the requirements a subtype of an abstract type must have besides just implicitly from functions?

This seems to be related to Julia#6975 but if its not related to that could someone clarify the difference.

Finally, why would anyone want to use a type union instead of an abstract type. The abstract type is more flexible and extensible, the type union is fixed. For example

Why this:

type A
  x
end

type B
  x
end

typealias C Union{A,B}

Instead of this:

abstract C

type A <: C
  x
end

type B <: C
  x
end
like image 334
mv3 Avatar asked Oct 23 '16 16:10

mv3


People also ask

What are abstract types in Julia?

Abstract types allow the construction of a hierarchy of types, providing a context into which concrete types can fit. This allows you, for example, to easily program to any type that is an integer, without restricting an algorithm to a specific type of integer.

Does Julia support inheritance?

Julia do not supports inheritance by design, hence we pursue code reuse by means of composition.

What is mutable struct in Julia?

type and immutable are valid up to julia 0.6, mutable struct and struct are the names of the same objects in julia 0.6 and forward. mutable in mutable struct means that the fields can change - which is actually fairly rarely used so being immutable is the default. mutable struct 's are slower than struct s.


1 Answers

First question: I do not think there is a way to achieve this currently, but it is at the heart of the discussions about adding traits to the language. You have already found one issue discussing this, and I believe it is on the informal roadmap beyond version 1.0 (at least I've seen it mentioned.)

I think the recommended way of implementing what you are looking for is something along these lines (note that type has been deprecated and replaced by struct):

abstract type A end

struct B <: A
    x
    y
end

struct C <: A
    w
    z
end

prop1(b::B) = b.x
prop2(b::B) = b.y
prop1(c::C) = c.w
prop2(c::C) = c.z  # changed from prop2(c::C)=c.w

mysum(a::A) = prop1(a) + prop2(a)

That is, instead of requiring B and C to have the same fields, you implement methods that define their behaviour. Then the actual field names remain internal implementation details of each concrete type.

As for union types, they can be used (among other things) to add methods to types that do not have a common supertype. Abstract types are fine, but you cannot always shoehorn all your types into a common hierarchy, and frequently you will add methods to collections of types that you did not define yourself.

like image 70
DNF Avatar answered Sep 23 '22 08:09

DNF