mauro3 / Traits.jl

Exploration of traits in Julia
Other
39 stars 6 forks source link

super call #30

Closed bjmtrk closed 8 years ago

bjmtrk commented 8 years ago

Hi, I am a bit confused how to do the super call.

using Traits

@traitdef T1{X} begin
    fun(X) -> Number
end

@traitdef T2{X} <: T1{X} begin
    fun(X) -> Number
end

@traitimpl T1{Int64} begin
    fun(x::Int64)  = 2x
end

@traitimpl T2{Int64} begin
    fun(x::Int64)  = 4x  + T1.fun(x)
end

Can we do something like this?

Thanks

mauro3 commented 8 years ago

Methods within a trait definition do not belong to that trait, i.e. they are not dispatched on based on the trait, only on the type. Thus your

@traitimpl T1{Int64} begin
    fun(x::Int64)  = 2x
end

makes a method fun(x::Int64). That also means that for your example, that all types which belong to trait T1 also belong to trait T2.

This is not going to change, thus I'm closing this. But feel free to use this issue to ask further questions concerning this.

bjmtrk commented 8 years ago

Then the question is how can i dispatch the to the call to the fun based on trait type T1?

mauro3 commented 8 years ago

I think you're a bit confused with object oriented programming. The function fun does not belong to the trait, it's completely independent. Any type X for which there exists a method of fun which can be called via fun(x) (with x::X) is part of trait T1. That's it. For your original example this means that T1==T2 as any type fulfilling T1 will also fulfill T2.

Anyway, you may want to make functions which dispatch on that trait T1 and on another trait, say TT:

@traitfn f{Y; T1{Y}}(y::Y) = 1
@traitfn f(Y; TT{Y}}(y::Y) = 2

Hope that helps?

bjmtrk commented 8 years ago

So basically you are using the traits as a collection of methods nothing more, they are not like mixins. Then my question becomes : @traitfn f{Y; T1{Y}}(y::Y) = 1 @traitfn f(Y; T2{Y}}(y::Y) = 2 + f(y)

how can i make f(y) to call @traitfn f{Y; T1{Y}}(y::Y) = 1? thanks

mauro3 commented 8 years ago

First, note that this very common pattern in OO languages is not used much in Julia, see https://github.com/JuliaLang/julia/pull/13123. I'm not sure quite why. Anyway, you can do it like so:

@traitfn f(Y; T2{Y}}(y::Y) = 2 + f(Tuple{T1{X}}, y)

that call directly calls the method which contains the logic for T1. See https://github.com/mauro3/Traits.jl#inner-workings and using macroexpand on the @traitfn. Maybe I should add an trait_invoke some day...

PS: @bjmtrk, better quote the macrocalls with backticks "". Otherwise it will ping github users with that name (although it seems@traitfn` is not taken yet ;-)