CanonicalTraits.jl icon indicating copy to clipboard operation
CanonicalTraits.jl copied to clipboard

Reasoning about return types?

Open cscherrer opened this issue 5 years ago • 8 comments

Hi Taine,

In one of your example, you have

@trait Addable{L, R} begin
    (+) :: [L, R] => Any
    (+) = Base.:+
end

I'd like to do something like this, but avoid the Any. I was thinking something like

@trait Addable{L, R, X} where {X = inferAddable(L,R)} begin
    (+) :: [L, R] => X
    (+) = Base.:+
end

But then I'm having trouble getting the @implement to work out. Is this currently possible?

cscherrer avatar Jan 26 '20 23:01 cscherrer

Hi, Chad, this is possible, and you solution looks good!

thautwarm avatar Jan 27 '20 06:01 thautwarm

I think there's no real reason to put the return type in trait parameters is there? You could just do

julia> @trait Addable{L, R} begin
           (+) :: [L, R] => infer(+, L, R)
           (+) = Base.:+
       end

julia> infer(::typeof(+), ::Type{Int}, ::Type{Int}) = Int;

julia> @implement Addable{Int, Int}

julia> 1 + 1
2

If we chose the wrong return type, this fails correctly:

julia> infer(::typeof(+), ::Type{Int}, ::Type{Int}) = Float64;

julia> 1 + 1
ERROR: TypeError: in typeassert, expected Float64, got a value of type Int64
Stacktrace:

MasonProtter avatar Jan 22 '21 23:01 MasonProtter

Great point @MasonProtter , thanks!

cscherrer avatar Jan 23 '21 12:01 cscherrer

This looks pretty good to me. I'm now thinking about how to make it version compatible.

thautwarm avatar Jan 23 '21 16:01 thautwarm

Besides, @cscherrer 's proposal is already implemented.

thautwarm avatar Jan 23 '21 16:01 thautwarm

It doesn't seem to work for me. Perhaps I'm doing something wrong?

julia> using CanonicalTraits

julia> inferAddable(::Type{Int}, ::Type{Int}) = Int
inferAddable (generic function with 1 method)

julia> @trait Addable{L, R, X} where {X = inferAddable(L,R)} begin
           (+) :: [L, R] => X
           (+) = Base.:+
       end

julia> @implement Addable{Int, Int}

julia> 1 + 1
ERROR: Not implemented trait Addable for (Int64, Int64, Int64).
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:33
 [2] Addable(::Type, ::Vararg{Type, N} where N)
   @ CanonicalTraits ~/.julia/dev/CanonicalTraits/src/Typeclasses.jl:157
 [3] +(+#2451::Int64, +#2452::Int64)
   @ Main ./none:0
 [4] top-level scope
   @ REPL[5]:1

MasonProtter avatar Jan 23 '21 16:01 MasonProtter

@MasonProtter This code works:

 @implement Addable{Int, Int, T} where T

Maybe I should enable something like

@implement Addable{Int, Int, _}

Directly supporting Addable{Int, Int} suffers from some analysis issues, but it is still negotiable.

thautwarm avatar Jan 24 '21 02:01 thautwarm

Ah, I see! Thanks for explaining.

MasonProtter avatar Jan 24 '21 02:01 MasonProtter