Skip to content

Instantly share code, notes, and snippets.

@tshort
Last active November 9, 2019 00:08
Show Gist options
  • Save tshort/9d773947e8631fe0a2d59f3789c8c7f6 to your computer and use it in GitHub Desktop.
Save tshort/9d773947e8631fe0a2d59f3789c8c7f6 to your computer and use it in GitHub Desktop.
Trait example from "Rust By Example"

Here is a Julia implementation from this trait example in Rust By Example.

## Define the object

mutable struct Sheep
    name::String
    naked::Bool
end
Sheep(name) = Sheep(name, false)

is_naked(x::Sheep) = x.naked
name(x::Sheep) = x.name
noise(x::Sheep) = is_naked(x) ? "baaaah?" : "baaah!"

## For now, let's not define the custom version of `talk` and let it use
## the trait version.
# talk(x::Sheep) = println(name(x), " pauses briefly... ", noise(x))

function shear(x::Sheep) 
    if is_naked(x)
        println(name(x), " is already naked...")
    else
        x.naked = true
        println(name(x), " gets a haircut!")
    end
end

## Define the trait

struct Animal end
struct NonAnimal end

isanimal(x::T) where T =
    # The Animal trait has to have the following methods:
    if hasmethod(name, Tuple{T}) &&
       hasmethod(noise, Tuple{T})
        Animal()
    else 
        NonAnimal()
    end

talk(x::T) where T = talk(isanimal(x), x)
talk(::Animal, x) = println(name(x), " says ", noise(x))

## Let's try it

dolly = Sheep("Dolly")

talk(dolly)
shear(dolly)
talk(dolly)

Right now, this uses dynamic dispatch because of hasmethod. For a static version of hasmethod, see Tricks.jl.

For more on Julia traits, see Lyndon White's blog post and the Julia manual here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment