# Finding all the functions with a parametric abstract type as a argument

Reflective programming/Metaprogramming challenge:
I am interested in exploring which methods are defined directly for some (usually parametric) and usually abstract types. To be clear, my interest is only in those methods defined with that particular type (with a `UnionAll` or specific generic parameter) and not simply the list of methods with which the type could be called.

To simplify, we could only look for those that have the type in the first 2 (or whatever) arguments.

As an example, lets say I have the following types, which may be in some module

``````module MyModule
abstract type SomeSuper end
abstract type Pointy{T} <: SomeSuper end
struct Point{T} <: Pointy{T}
x::T
y::T
end

f1(x::SomeSuper) = 1
f2(x::SomeSuper) = 1
f2(x::Pointy{T}) where T = 2
f3(x::Pointy{Float64}) where T = 3
f4(x::Pointy{T}) where T = 1
end

f5(x::MyModule.Pointy{T}) where T = 1 # different namespace
f6(y, x::MyModule.Pointy{T}) where T = 1
f7(x::Point{T}) where T = 1 # note the concrete sub-type
``````

We can call them as well, just to ensure all the names are loaded in whichever way necessayr

``````# calling works
p = MyModule.Point{Float64}(0.1, 0.2)
MyModule.f2(p)
MyModule.f3(p)
MyModule.f4(p)
f5(p)
f6(1, p)
f7(p)
``````

We could even assume that they are available with `using` if that helps

I want to be able to have something called `getfunctions` which returns the list of functions that directly mention the type, or methods if that is easier. The signature would be something like

``````fs = getfunctions(MyModule.Pointy) # note abstract type without specific parameters

# should be
fs == [:f2, :f3, :f4, :f5, :f6] # could have namespace qualifications, if easier
``````

In this, `:f1` doesnâ€™t match because there are no methods which mention Pointy directly, and `:f7` doesnâ€™t match because it only refers to sub-types of `Pointy`. All of the other ones have an argument to a method which refers to either `Pointy` with any parameter or a `Pointy` with a particular generic parameter.

Any thoughts on whether this is possible or how it could be written? I think it would be a generally useful bit of code to explore the type-system.

Not a direct answer, but with my InteractiveCodeSearch.jl you can just run `@search MyModule` and then type `Pointy` to get a rough list of functions using it.

If you want a programmatic interface, I guess you can look at what `methods` returns:

``````julia> for m in methods(MyModule.f2)
@show m.sig
end
m.sig = Tuple{typeof(Main.MyModule.f2),Main.MyModule.Pointy{T}} where T
m.sig = Tuple{typeof(Main.MyModule.f2),Main.MyModule.SomeSuper}
``````
1 Like

Looks great. I want to explore rather than have a programmatic interface, so this might be perfect. My real interest is not a simple set of types, but rather examining types in `Base.Number`, `Base.AbstractRange`, etc, so I will see if the large number of values returned works in the UI.

A report: The `InteractiveCodeSearch.jl` based solution is pretty good. Cool package, which I hope you publicize much more! My real test, is to try to explore `Base.Number`, `Base,AbstractFloat`, etc.

The only issue is that the `@search Base` and then `Number` since it uses strings rather than types, you can get a lot of false-positives for the sort of thing I am interested in, but even in Base it was useful.

Thanks, good that you find it useful! Yeah, I guess I better make an ANN post in discourse.

I agree that string-based matching is very crude (but actually already quite useful, mostly because `peco` is really efficient). It would be nice to make something like hoogle where you can search functions based on signature. Now that I figured out how to search based on return type, itâ€™s matter of coding things upâ€¦

Meanwhile, in `peco` you can use other search mode like regex by pressing `C-r` (`peco.RotateFilter`) a few times. It may help you decreasing false-positives (if you havenâ€™t tried it already).

BTW, your example let me fix some bugs (thanks!). One of the bugs is that you couldnâ€™t run `@search Main :r` to search all methods. Once https://github.com/JuliaLang/METADATA.jl/pull/18833 is merged, youâ€™d be able to do that.