Home > Software engineering >  Julia type system and behavior
Julia type system and behavior

Time:12-08

I'm still trying to wrap my head around Julia's types. For example assuming I wanted to define the structure of an Animal object. Taking as example typescript I would do something like this:

interface Animal {
    sound: string;
}

function sing(animal: Animal) {
    console.log(animal.sound);
}

const dog: Animal = {
    sound: 'woof',
};

// OR
class Dog implements Animal {
    sound = 'woof';
    // other Dog methods here
    run() {}
}

// Wrong implementations are caught immediately
const cow: Animal = {
    noise: 'bark'
}

// Error: Type '{ noise: string; }' is not assignable to type 'Animal'.
// Object literal may only specify known properties, and 'noise' does not exist in type 'Animal'.

How can I do this in Julia? In other words, Animal needs to have a .sound. This is what I tried:

abstract type Animal end

function sing(animal::Animal) 
    println(animal.sound)
end

struct Dog <: Animal
    sound::AbstractString
end

function run(dog::Dog) end

struct Cow <: Animal
    noise::AbstractString
end

But:

  • I don't get any warning from IDE that sing will not work with all the Animal implementation
  • When I try to run sing(Cow("moo")) I do get an error, but at the function sing!: ERROR: type Cow has no field sound

What am I missing? How can I maintain a large codebase if I get no warning before runtime? How can I define behaviour since I can't subtype concrete classes?

CodePudding user response:

Julia is not object oriented so taking OO is usually not comfortable.

Most often you will want to use multiple dispatch to define behavior for different object types eg.:

abstract type Animal end

getsound(::T) where T <: Animal = throw(ErrorException("not implemented for $T"))
struct Dog <: Animal end
struct Cow <: Animal end
struct Cat <: Animal
   specialsound::String
end
getsound(::Dog) = "hau"
getsound(cat::Cat) = cat.specialsound
sing(animal::Animal) = println(getsound(animal))

And here is the usage:

julia> sing(Dog())
hau

julia> sing(Cat("mew"))
mew

julia> sing(Cow())
ERROR: not implemented for Cow

Now regarding IDE - commenting out getsound(::T) in VS Codium does not underline the cow. However this indeed looks like something that could be added as compiler detects this as an error (assuming getsound(::T) where T <: Animal is not defined) :

julia> @code_typed sing(Cow())
CodeInfo(
1 ─     Main.getsound(animal)::Union{}
└──     unreachable
) => Union{}
  • Related