JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45k stars 5.42k forks source link

A publicly facing reflection API #20555

Open oxinabox opened 7 years ago

oxinabox commented 7 years ago

Julia allows for reflection. It is infact really powerful. You can do crazy things like examine the code for a function programatically.

My issue is that it is largely based on unexported methods, and on directly reading various fields. Sometimes in complicated ways. Code based on this "privately" facing API breaks every single release.

Consider, this example that came up in code I am writing. I would like to find out if a function has any methods that take a keyword arg with a given name.

function methods_with_kwarg(func::Function, kwarg_name::Symbol)
    #BLACK-MAGIC, 0.5 only
    supporting_methods = Method[]
    ml = methods(func)
    if isdefined(ml.mt, :kwsorter)
        kwsort_t = typeof(ml.mt.kwsorter)
        for mmm in ml.ms
            sig = mmm.sig
            all_kwarg_list = Base.kwarg_decl(sig, kwsort_t)
            if kwarg_name ∈ all_kwarg_list
                push!(supporting_methods, mmm)
            end
        end
    end
    supporting_methods
end
julia> methods_with_kwarg(repeat, :outer)

1-element Array{Method,1}:
 - repeat(A::AbstractArray) at abstractarraymath.jl:329

So in that code, 2 Public API method was used: methods and isdefined. And then 5 private API methods/fields: MethodTable.kwsorter, Method.sig, MethodList.ms, MethodList.mt, and Base.kwarg_decl.

They are all undocumented. and I know they change in 0.6, and in 0.4, and 0.3. It would be nice to be able to do reflection without having to go deep into the guts of the language.

Towards this end, I feel it is necessary to make a consideration of what reflection methods a language like julia should provide, and then define, export, and document methods to that end.

Ismael-VC commented 7 years ago

We should start with a list of this public and private methods/fuelds. Then change the short cryptic names and document everything even if not exported, so we can suggest how the API should look like. I didnt know about those private methods.

oxinabox commented 7 years ago

So that implementation can change, all fields basically require functions, that retrieve their value. Eg. paramaters(T) = T.parameters

smldis commented 6 years ago

I think this needs a (short or advanced) plan for 1.0/1.x at list for the publicly facing part.

smldis commented 6 years ago

I'll list some reflection uses I found for fields reflection (not listing the most common patterns that involve testing and documenting in repl and in compiled docs).

oxinabox commented 5 years ago

another I want is