I did mention in a few prior posts that i am new to Julia so I still have some questions for the best usage.
I come from very OO languages like C# and Python where you can simply call all the functions defined on a type (Class or Instance) by the instance plus dot. This usualy also triggers the code hinting on what functions are defined on this types e.g.
MyClass MyInstance = new MyClass();
//Can simply call functions
MyInstance.myFunction();
//or wait for autocomplete:
MyInstance.
This can obviously not be done in Julia like this. What is the best way in Julia to do this aka find what functions are defined on a type?
Finding methods defined on a type in Julia is done by using the methodswith function:
# it will return all methods that have an `String` as argument
methodswith(String)
# the above might be overwhelming, so you might want to restrict
# the search to a module or a particular function
# restrict to Base module
methodswith(String, Base)
# or to setindex! function
methodswith(Int, setindex!)
The output is a little verbose to print here - however, keep in mind that methodswith returns a vector of methods.
I was about to answer the same and this made me wonder: could there be a functionswith that does the same as methodswith but gathering duplicate names and omitting signatures?
Bear in mind that methodswith isn’t exhaustive, and without specifying a module or function to look for methods, it doesn’t look into unexported functions or delve into submodules of the top level modules (issue #33866) like Main, imported packages, and some other standard libraries. For now you can check what are top level with Base.loaded_modules_array(), for example Base is in the top level but Threads is not because it is a submodule of Base.
Ok this is very practical.
Not as quick as the autocomplete in other languages but i have to admit that especially in python it does also not work that great. Time for Copilot then, might help me here.
@Benny ,
On a less serious note, methodswith is useless enough as it is - making it collect an even more extensive collection of methods will not improve things much (obviously it will - if the goal is to catch them all - but I am talking about usefulness).
I mean, if you actually know what you are searching for, you can run some additional filtering on the returned methods collection, but as an exploration tool is kinda weird to eyeball the signatures of hundreds of methods.
I think a better approach would be to return the docstrings instead of (or along with) the methods or simply function names - that would actually tell you something about the logic behind those names/signatures.
When the function is provided, methodswith(T, f) seems fairly robust in my experience, basically using it as methods(f) but filtered by argument types.
But yes, methods are organized by function not argument types, so it’s a hefty task to search modules recursively and exhaustively given an argument type alone. Still, if I provide a module, I do wish it would look at the unexported functions too, even if it didn’t recurse into submodules.
After I got used to the idea that dot-driven-development is not going to work in Julia, methodswith + methods always did the trick for me - I have no complaints.
I am talking more about the pure exploratory experience starting from a type - like a shot in the dark (and those who are fresh from class world can feel a little lost when trying to answer what method works on this type).
This is why I think Julia is one of the languages where it is much harder to learn the standard library - because the tooling/intellisense doesn’t start to help you until it is too late - meaning that you have already found out the name of the function you want).
But all this annoyance is a price worth paying for having multiple dispatch. And copilot and other assisting tools will only make things better.
You don’t need multiple dispatch to run into this, OOP has it too. For a simple example, take the NumPy array versus all the packages like SciPy importing it. An array class can have some fundamental methods like appending, getting the length, maybe some statistics like mean/sum/var. But the vast majority of functions that take in an array should not be attached to the array class, and I’m pretty sure the NumPy array class prevents attempts to do that. That said, part of the desire for a more discoverable and formal interface system in Julia is finding those fundamental methods for an abstract type and its subtypes, even if optional.
It’s designed to find the source code for a given method (so not exactly what’s wanted here), but the user interface allows interactively filtering the list of methods.