You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I tried the following code and the result is not what I expect.
using Traits
IsGoodTrait(x) = IsGoodTrait(typeof(x))
IsGoodTrait(::Type) = false
IsGoodTrait(::Type{<:AbstractFloat}) = true
IsGoodTrait(::Type{<:AbstractString}) = true
# base function
foo(x) = "not implemented"
@traits function foo(x::T) where {T<:Number, IsGoodTrait(T)}
println("$T has Good trait")
end
I get the following result. Maybe this is a bug?
julia> foo("s")
"not implemented"
julia> foo(1.2)
Float64 has Good trait
julia> foo(1) # I think this should return "not implemented"
ERROR: MethodError: no method matching '__traits__.Main.foo'(::Type{Tuple{Traits.Syntax._BetweenCurliesAndArgs,T} where T<:Number}, ::Int64, ::Traits.Syntax._BetweenArgsAndTypeVars, ::Type{Int64}, ::Traits.Syntax._BetweenTypeVarsAndTraits, ::Val{false})
Closest candidates are:
'__traits__.Main.foo'(::Type{Tuple{Traits.Syntax._BetweenCurliesAndArgs,T} where T<:Number}, ::Any, ::Traits.Syntax._BetweenArgsAndTypeVars, ::Any, ::Traits.Syntax._BetweenTypeVarsAndTraits, ::Val{true}) at e:\work\julia\test\test.jl:11
'__traits__.Main.foo'(::Type{Tuple{Traits.Syntax._BetweenCurliesAndArgs,T} where T<:Number}, ::Type{Traits.Syntax.InnerFuncFixedDocSig{Tuple{Pair{:a1,:x}},Tuple{Pair{:T1,:T}},Tuple{Pair{Symbol("Val{IsGoodTrait(T1)}()"),Symbol("var\"'Val{IsGoodTrait(T1)}()'\"::Val{true}")}}}}) at E:\.julia\packages\Traits\EKIlj\src\Syntax\Syntax.jl:464
Stacktrace:
[1] #foo#9(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(foo), ::Int64) at e:\work\julia\test\test.jl:10
[2] foo(::Int64) at e:\work\julia\test\test.jl:10
[3] top-level scope at REPL[3]:1
The text was updated successfully, but these errors were encountered:
Thanks for reporting. Just checked your example. First the solution, then the explanation.
You have to add the following clause for it to work
@traitsfunctionfoo(x::T) where {T<:Number}
"not implemented"end
Now the reason: @traits dispatch currently works like it constructs an outer function for normal dispatch (here the T<:Number belongs to normal dispatch). And within this outer function a call to an inner function is made which dispatches on respective extra traits.
Hence if you call foo(1), the outer function for your traits dispatch is called, however the respective inner function is only defined for IsGoodTrait(T) == true. Hence you get the no method found error.
With the added fallback, the respective innerfunction has a proper fallback.
But you are right, I myself see that one would like to have a generic fallback possibility. Lets discuss more about if and how something like that would be possible in Future.
Last remark: You can inspect the current definition of a traits definition via @traits_show_implementation foo
and you will see the outer and inner function respectively
I tried the following code and the result is not what I expect.
I get the following result. Maybe this is a bug?
The text was updated successfully, but these errors were encountered: