Here's one possible implementation of (some of) your example. I created 2 macros which could simulate multiple inheritance... both are probably implemented in a nicer way already... but I just wanted to show something simple. The parent macro converts a type expression into an assignment "name = fields_block". The inherit macro injects the parent fields into the type expression.
isexpr(x, head) = isa(x, Expr) && x.head == head
macro parent(expr::Expr)
@assert isexpr(expr, :type)
tname = expr.args[2]
tfields = filter(x->!isexpr(x,:line), expr.args[3].args)
quote
$(esc(tname)) = $tfields
end
end
macro inherit(expr::Expr, parents::Symbol...)
@assert isexpr(expr, :type)
for parent in parents
append!(expr.args[end].args, eval(parent))
end
quote
$expr
end
end
#-----------------
abstract Animal
@parent type CatOrDog
age::Int
weight::Float64
end
kilo(x) = x.weight * 0.4535
@inherit type Cat <: Animal end CatOrDog
@inherit type Dog <: Animal end CatOrDog
abstract Country
type USA <: Country end
type UK <: Country end
incharge(a::Animal, ::USA) = "Mike"
incharge(a::Animal, ::UK) = "The Queen?"
play{T<:Animal}(a1::T, a2::T) = "no toys? boring"
play{T<:Animal}(a1::T, a2::T, toys::Int...) = "playing with Ints: $toys"
play{T<:Animal}(a1::T, a2::T, toys::String...) = "playing with Strings: $toys"
play(a1::Cat, a2::Dog, args...) = play(a2, a1, args...)
play(a1::Dog, a2::Cat, args...) = "Grrrrrrrrrrrrr.... meow"
cat = Cat(10, 8.0)
dog = Dog(20, 15.0)
#-----------------
julia> kilo(cat)
3.628
julia> incharge(cat, USA())
"Mike"
julia> incharge(cat, UK())
"The Queen?"
julia> play(dog, dog)
"no toys? boring"
julia> play(dog, cat)
"Grrrrrrrrrrrrr.... meow"
julia> play(dog, dog, "bone", "ball")
"playing with Strings: (\"bone\",\"ball\")"
julia> play(dog, dog, 1, 2)
"playing with Ints: (1,2)"