Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

list of available methods in REPL #30052

Closed
sdewaele opened this issue Nov 16, 2018 · 8 comments · Fixed by #38791
Closed

list of available methods in REPL #30052

sdewaele opened this issue Nov 16, 2018 · 8 comments · Fixed by #38791
Labels
stdlib:REPL Julia's REPL (Read Eval Print Loop)

Comments

@sdewaele
Copy link

It would be great to get suggestions from the REPL on methods for a given type. For example, I enter a DataFrame df on the REPL, and it provides me with a list of methods that I can use with a DataFrame. Amongst others, this would suggest head for the DataFrame. I could then select and autocomplete with [TAB] in the same way as currenly be done with autocompletion of fields etc. Finally, the REPL prepends the selection to create the resulting method call, e.g. head(df). This can be based on methodswith.

With this feature, we replicate the benefit that the Python user enjoys when she types df.[TAB] to get a list of names (including functions) associated with an object.

One way to evoke this list may be to type (df)[TAB] to get the list list of methodswith(typeof(df)), but any better suggestion from a REPL expert is welcome.

An alphabetically ordered list would be a good start. As a refinement, the list can have clever prioritization/filtering, e.g. prioritize methods where the type is the only argument, the first argument, methods that are unique to this type (as opposed to e.g. + which is defined for many types), ... .

@antoine-levitt
Copy link
Contributor

I thought this would be pretty cool: discoverability via dot completion is one of the best things about OOP languages, and it'd be awesome to have the same thing in Julia. I hacked together this patch: https://gist.github.com/antoine-levitt/4526575d11d7f5eb2e6a767e926f1606. It works, but it's slightly less useful that one would like, because of the large number of methods that match pretty much everything under the sun: here is for instance a list of the functions that match a QR factorization (which has very few actually useful methods)

julia> a = randn(1)
1-element Array{Float64,1}:
 -0.21519161391684696

julia> b = qr(a)
LinearAlgebra.QRCompactWY{Float64,Array{Float64,2}}
Q factor:
1×1 LinearAlgebra.QRCompactWYQ{Float64,Array{Float64,2}}:
 1.0
R factor:
1×1 Array{Float64,2}:
 -0.21519161391684696

julia> (b)
==                  code_native          fetch                in                   isreadonly           modf                 reim                 typejoin
acosd               code_typed           fieldcount           intersect            issetgid             mtime                replace              union
acotd               collect              filemode             inv                  issetuid             norm                 replace!             unique
acscd               cosd                 filesize             isabstracttype       issocket             ntoh                 repr                 unique!
all                 count                fill                 isbits               issorted             objectid             rethrow              unsigned
allunique           ctime                finalize             isblockdev           issticky             oneunit              setdiff              uperm
any                 deepcopy             findall              ischardev            iszero               operm                show                 values
apropos             det                  findfirst            isconcretetype       iterate              pairs                signed               vcat
argmax              display              findlast             isdir                join                 pointer_from_objref  sincos               walkdir
argmin              dropdims             findmax              isdispatchtuple      last                 print                sind                 widen
asecd               dump                 findmin              isempty              less                 println              size                 zip
asind               eachindex            first                isequal              logdet               printstyled          sizeof               
asyncmap            edit                 float                isfifo               lstat                prod                 skipmissing          
atand               eltype               foreach              isfile               ltoh                 promote              something            
axes                enumerate            functionloc          isimmutable          map                  promote_type         stat                 
broadcast           error                gperm                islink               maximum              propertynames        string
cat                 esc                  hash                 ismissing            methods              rand                 sum
clipboard           eval                 hcat                 ismount              minimum              range                summary
coalesce            eval                 htol                 isone                mktemp               readchomp            symdiff
code_llvm           exit                 hton                 ispath               mktempdir            readlines            tand
code_lowered        extrema              identity             isperm               mod2pi               redisplay            task_local_storage

Of course, one could blacklist the methods that match Any, but that's a bit too restrictive, since users are used to have REPL completion giving them all the possible options. Not sure how to proceed from there...

@sdewaele
Copy link
Author

Thanks for writing the patch. Very nice! I think having a list of all methods except for those who match Any would still be useful. Definitely more useful than having none of this functionality at all.

Would it be possible to have a short list first, then a longer list after a user enters another key, e.g. when repeatedly entering [TAB], or another key (e.g. 1,2,3) after the first [TAB]?

BTW, I later realized that an alternative way to evoke this completion may be to enter b) instead of (b) - less typing.

@antoine-levitt
Copy link
Contributor

I'm not sure if that's such a good idea. We usually rely on completion to tell us all the things that make sense in a given context, not a restricted version of it for discoverability purposes. Ways out are a different keybinding (e.g. shift-tab?), or a methodswith method that would take a tuple of arguments and match their types (eg methodswith((1,2.0))).

@sdewaele
Copy link
Author

OK, I understand the need for consistency. A different key binding would be fine for the shorter list.
I like the of having a tuple of arguments, this is a natural extension of the single-argument case.

@antoine-levitt
Copy link
Contributor

I think this really calls for a more general UI to have a general help/interaction system accessible through keybindings. TAB is too limitative here. E.g. you could type qr(A), press alt-e (or some other key chord) and have it run @edit qr(A). The same for other helper functions such as methodswith or a variation thereof (this thread), @code_warntype, @less or whatever. Basically, turn the REPL into a basic IDE. This would make a very good idea for a package.

@chethega
Copy link
Contributor

I think the right way of organizing would be by type hierarchy: First the most specific, going down to more general. First strip one type-var after the other, then go to supertype, continue. Ensure that each method appears only once, and withing each section order alphabetically. Each non-empty section gets a header for the relevant generalization of the type.

This has the beneficial side-effect that we additionally display the type hierarchy.

Also, possibly mark @generated methods as such, e.g. by color.

@sairus7
Copy link
Contributor

sairus7 commented Dec 26, 2018

See also duplicate issue here:
JunoLab/Juno.jl#199

@mbauman mbauman added the stdlib:REPL Julia's REPL (Read Eval Print Loop) label Dec 31, 2018
@cmcaine
Copy link
Contributor

cmcaine commented Feb 24, 2019

Fish shell shows you more completion options if you press tab again (there's a hint telling you to press tab for more). That feels very natural to me. In an IDE you can just show a list with a scrollbar.

In any case, there are hundreds of methods that will match common examples, so I think it is necessary to sort/score the results with some heuristics (defined in same module as type, closeness of type match, previous uses, etc).

timholy added a commit that referenced this issue Dec 9, 2020
timholy added a commit that referenced this issue Jul 25, 2021
timholy added a commit that referenced this issue Aug 9, 2021
* ?(x, y)TAB completes methods accepting x, y

Closes #30052
xref #38704
xref #37993

Co-authored-by: Jameson Nash <vtjnash@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib:REPL Julia's REPL (Read Eval Print Loop)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants