Hello,
I am trying to use traits on functions and I would like to define the trait automatically based on existing methods.
I have several traits like EntityFeature and FrameFeature and a function featuretype(::typeof(myfun)) = EntityFeature() to get the trait and use it for dispatch.
The trait is assigned depending of existing methods of myfun.
Now what I would like to automatically define the featuretype function when I define myfun.
I have written a macro that works like this:
macro feature(fun)
    f = eval(fun)  # evaluate in the scope of this module
    T = fun.args[1].args[1] # hacky ? get function name
    if hasmethod(f, Tuple{Roadway, Entity})
        @eval featuretype(::typeof($T)) = EntityFeature()
    elseif hasmethod(f, Tuple{Roadway, Frame, Entity})
        @eval featuretype(::typeof($T)) = FrameFeature()
    elseif hasmethod(f, Tuple{Roadway, Vector{<:Frame}, Any})
        @eval featuretype(::typeof($T)) = TemporalFeature()
    else
        error(""""
              unsupported feature type
              try adding a new feature trait or implement one of the existing feature type supported
              """)
    end
    return 
end
The intended usage is
@feature function posgx(roadway::Roadway, veh::Entity) 
    return posg(veh).x 
end
The macro should define the function featuretype(::typeof(posgx)) = EntityFeature()
It works but I am having the following concerns:
- if I try to document one of the @feature functions with docstrings it breaks.
- it only evaluate the function within the scope of the module where the macro is defined
 I would really appreciate some feedback and help on this, thanks!
I would like to avoid using hasmethod at run time.
Here are some references:
- An excellent blog post on traits: https://www.juliabloggers.com/the-emergent-features-of-julialang-part-ii-traits/
- the full version of my code: AutomotiveDrivingModels.jl/features.jl at feature-extraction · sisl/AutomotiveDrivingModels.jl · GitHub