In object-oriented languages, it is easy to see what methods a type has. For example, to find a replace command for strings, I just need to search in the methods that a string object exposes (using, e.g., __dict__
in python). In Julia, because of multiple dispatch, methods just occupy the global namespace, and I can’t restrict my search in the function space according to types. I was wondering if there are ways to do this.
3 Likes
have you tried methods
and methodswith
?
methodswith(typ[, module or function]; supertypes::Bool=false])
Return an array of methods with an argument of type typ.
The optional second argument restricts the search to a particular module or function (the default is all top-level modules).
If keyword supertypes is true, also return arguments with a parent type of typ, excluding type Any.
methods(f, [types], [module])
Return the method table for f.
If types is specified, return an array of methods whose types match. If module is specified, return an array of methods defined in that module. A
list of modules can also be specified as an array.
│ Julia 1.4
│
│ At least Julia 1.4 is required for specifying a module.
7 Likes
Can you provide an example of using this to get methods for Poisson
from Distributions
? I tried the following, but it did not show, e.g., rand(Poisson(1))
.
julia> typeof(Poisson(1))
Poisson{Float64}
julia> methods(typeof(Poisson(1)))
# 1 method for type constructor:
[1] (::Type{Poisson{T}})(λ::Real) where T<:Real in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:26
julia> methodswith(typeof(Poisson(1)))
julia> methods(Poisson(1))
# 0 methods:
julia> methodswith(Poisson(1))
ERROR: MethodError: no method matching methodswith(::Poisson{Float64})
Closest candidates are:
methodswith(::Type; supertypes) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.4/InteractiveUtils/src/InteractiveUtils.jl:168
methodswith(::Type, ::Function) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.4/InteractiveUtils/src/InteractiveUtils.jl:136
methodswith(::Type, ::Function, ::Any; supertypes) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.4/InteractiveUtils/src/InteractiveUtils.jl:136
...
Stacktrace:
[1] top-level scope at REPL[121]:1
julia> methodswith(Poisson)
[1] ccdf(d::Poisson, x::Int64) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariates.jl:557
[2] cdf(d::Poisson, x::Int64) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariates.jl:556
[3] cf(d::Poisson, t::Real) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:113
[4] convolve(d1::Poisson, d2::Poisson) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/convolution.jl:45
[5] cquantile(d::Poisson, q::Real) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariates.jl:562
[6] entropy(d::Poisson{T}) where T<:Real in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:68
[7] invlogccdf(d::Poisson, lq::Real) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariates.jl:564
[8] invlogcdf(d::Poisson, lq::Real) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariates.jl:563
[9] kurtosis(d::Poisson) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:65
[10] logccdf(d::Poisson, x::Int64) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariates.jl:559
[11] logcdf(d::Poisson, x::Int64) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariates.jl:558
[12] logpdf(d::Poisson, x::Int64) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariates.jl:554
[13] mean(d::Poisson) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:52
[14] mgf(d::Poisson, t::Real) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:108
[15] mode(d::Poisson) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:54
[16] modes(d::Poisson) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:57
[17] params(d::Poisson) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:45
[18] pdf(d::Poisson, x::Int64) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariates.jl:553
[19] quantile(d::Poisson, q::Real) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariates.jl:561
[20] rate(d::Poisson) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:48
[21] sampler(d::Poisson) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:147
[22] skewness(d::Poisson) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:63
[23] var(d::Poisson) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:61
[24] broadcast(::typeof(pdf), d::Poisson, X::UnitRange) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:102
[25] broadcast!(::typeof(pdf), r::AbstractArray, d::Poisson, rgn::UnitRange) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:99
[26] convert(::Type{Poisson{T}}, d::Poisson{S}) where {T<:Real, S<:Real} in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariate/discrete/poisson.jl:41
[27] maximum(d::Poisson) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariates.jl:148
[28] minimum(d::Poisson) in Distributions at /Users/evar/.julia/packages/Distributions/dTXqn/src/univariates.jl:147
julia>
You can find rand
if you add the keyword argument supertypes=true
:
julia> methodswith(Poisson; supertypes=true)
[snip output ...]
[96] rand(s::Sampleable) in Distributions at D:\.julia\packages\Distributions\vskB8\src\genericrand.jl:22
(Just note that Sampleable
is a supertype of Poisson
)
3 Likes
One more note: see that, although it is a good approximation, methodswith
does not fully solve the original question (“search for functions whose first argument can be of a specific type”):
- On the one hand,
methodswith
tells you about functions that have been written with methods that take specific types (or optionally their supertypes) for arguments in any position. - On the other hand,
Any
is excluded from the list of supertypes considered bymethodswith
(otherwise the output would be endless), but for many types there are numberless generic functions that work with them, even without the authors of the type or the function taking care of that. - Also, the output of
methodswith
is not fixed, but depends on what packages are loaded.
Anyway, Julia is not like Python: methods are not subordinate to types/classes, so I think that it is reasonable that the original question, asked from a Pythonic perspective, does not have a precise answer in Julia.
4 Likes