`help?> X` should suggest `Base.X` if `X` is an un-exported member of `Base`

I think it would be helpful if when searching help?> X for an object X that is defined in, but not exported from, Base, if the help?> X menu offered to show you the documentation of Base.X rather than just say Couldn't find X.

The specific example that inspired this:

help?> Fix2
search: chopprefix chopsuffix findnext findmax! findmax TaskFailedException firstindex

Couldn't find Fix2
Perhaps you meant fill, if, diff, Pipe, Cint, Dict, Dims, Libc, Text, abs2, big or bind
  No documentation found.

  Binding Fix2 does not exist.

help?> Base.Fix2
  Fix2(f, x)


  A type representing a partially-applied version of the two-argument function f, with
  the second argument fixed to the value "x". In other words, Fix2(f, x) behaves
  similarly to y->f(y, x).

It would be nice if help?> Fix2 suggested that I search for Base.Fix2 or even offer to show it automatically (kind of like how the new Pkg offers to install a package you try to using that you don’t yet have installed).

4 Likes

More generally, the “perhaps you meant” section could also list Foo.X if the user happens to have loaded a package Foo, which has an un-exported function X.

3 Likes
julia> apropos("Fix2")
Base.:>=
Base.:<
Base.in
Base.Fix2
Base.Fix1

6 Likes

I would be annoyed if ?Fix2 worked but Fix2 didn’t. Perhaps you meant Base.Fix2 would be nice though.

This is a so-so solution. apropos is pretty slow, returns a lot of non-matches, and takes a while to return if the function you’re interested in has no documentation. I think the first call to apropos actually runs through and loads the docs for every function in the workspace, which is incredibly expensive.

Does the speed depend on what you’re searching for? I see:

julia> @time apropos("Fix2")
Base.:!=
Base.Fix1
Base.Fix2
Base.startswith
Base.:>
Base.contains
Base.isequal
Base.:<
Base.endswith
Base.:==
Base.:<=
Base.:>=
Base.occursin
Base.in
  0.825711 seconds (2.44 M allocations: 160.969 MiB, 3.54% gc time, 77.51% compilation time)

In julia 1.8.2 on linux. Second call is faster.

julia> @time apropos("Fix2")
Base.:>
Base.occursin
Base.in
Base.:!=
Base.:<
Base.:>=
Base.startswith
Base.:<=
Base.endswith
Base.Fix2
Base.Fix1
Base.isequal
Base.contains
Base.:==
  8.814449 seconds (3.48 M allocations: 211.022 MiB, 6.51% gc time, 90.66% compilation time: 48% of which was recompilation)

Very odd - mine was in a new 1.8.2 session on Windows, seems unusual that Windows should be an order of magnitude faster? (This is getting a bit offtopic though, might warrant splitting the thread if there’s an issue with the speed of apropos)

It would be nice if the helped search in packages, but possibly AVOIDING unexported from Base.

It does search exported from Base, and if not exported it’s not part of Julia’s API, so I’m not sure it should be shown (possibly it’s helpful until it isn’t and dropped from Base, has happened before). Or IF then with a big warning. If you know of something there, which is documented AND useful for regular developers I think you should open an issue and get it exported. Maybe there’s a reason it isn’t.