# Can we change the Julia help from bottom-up to top-down?

**URL:** <https://discourse.julialang.org/t/can-we-change-the-julia-help-from-bottom-up-to-top-down/77866>\
**Category:** General Usage\
**Tags:** suggestions\
**Created:** [March 14, 2022, 1:57pm UTC](https://discourse.julialang.org/t/can-we-change-the-julia-help-from-bottom-up-to-top-down/77866 "2022-03-14T13:57:24Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ZdM87](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdm87/32/15353_2.png) [@ZdM87](https://discourse.julialang.org/u/ZdM87)\
**Post date:** [March 14, 2022, 1:57pm UTC](https://discourse.julialang.org/t/can-we-change-the-julia-help-from-bottom-up-to-top-down/77866/1 "2022-03-14T13:57:24Z")

</div>

When you type ? in Julia and then type `<something>`, you get all the help information about `<something>` but if this information does not fit in the screen, you will get the tail of the information (like in a bottom-up view). So, you should scroll up to the top to read the information. In linux, for example, if you type `man <something>` you will get the help information about `<something>` in a top-down view and you use space to move down as you read.

I do not how to better formulate my question but in my opinion the top-down view should be the default behaviour, if possible.

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [March 14, 2022, 2:01pm UTC](https://discourse.julialang.org/t/can-we-change-the-julia-help-from-bottom-up-to-top-down/77866/2 "2022-03-14T14:01:56Z")

</div>

I think it would be better to pipe the help output into a pager. IIRC, there was a recent PR to do this that was approved at triage, but it requires a few bugs in the pager to be fixed first.

It’s one of those things where the core devs are absolutely on board, but someone just needs to put in the work and write the code (it could be you! 🙂 )

Edit: It’s these:

- [https://github.com/JuliaLang/julia/pull/41423](https://github.com/JuliaLang/julia/pull/41423)
- [https://github.com/JuliaLang/julia/issues/36460](https://github.com/JuliaLang/julia/issues/36460)

---

<div class="post-metadata">

**Author:** ![NiclasMattsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/niclasmattsson/32/21988_2.png) [@NiclasMattsson](https://discourse.julialang.org/u/NiclasMattsson)\
**Post date:** [March 14, 2022, 2:16pm UTC](https://discourse.julialang.org/t/can-we-change-the-julia-help-from-bottom-up-to-top-down/77866/3 "2022-03-14T14:16:08Z")

</div>

I honestly don’t think the problem is the direction of the help scrolling or the lack of paging. For me at least is primary issue is what I call “doc pollution”. In complex packages with a lot of dependencies, a common function gets concatenated docs for all sorts of obscure methods that most users are not interested in. This is the cruft you have to scroll past to get to the basic usage at the very top. For example:

```julia
help?> first # no loaded packages, so relatively brief
search: first firstindex popfirst! pushfirst! uppercasefirst lowercasefirst findfirst searchsortedfirst

  first(coll)

  Get the first element of an iterable collection. Return the start point of an AbstractRange even if it is empty.

  See also: only, firstindex, last.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> first(2:2:10)
  2

  julia> first([1; 2; 3; 4])
  1

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(itr, n::Integer)

  Get the first n elements of the iterable collection itr, or fewer elements if itr is not long enough.

  See also: startswith, Iterators.take.

  │ Julia 1.6
  │
  │ This method requires at least Julia 1.6.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> first(["foo", "bar", "qux"], 2)
  2-element Vector{String}:
   "foo"
   "bar"

  julia> first(1:6, 10)
  1:6

  julia> first(Bool[], 1)
  Bool[]

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(s::AbstractString, n::Integer)

  Get a string consisting of the first n characters of s.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> first("∀ϵ≠0: ϵ²>0", 0)
  ""

  julia> first("∀ϵ≠0: ϵ²>0", 1)
  "∀"

  julia> first("∀ϵ≠0: ϵ²>0", 3)
  "∀ϵ≠"

julia>

```

Compare with:

```julia
julia> using DataFrames

help?> first
search: first firstindex popfirst! pushfirst! uppercasefirst lowercasefirst findfirst searchsortedfirst

  first(coll)

  Get the first element of an iterable collection. Return the start point of an AbstractRange even if it is empty.

  See also: only, firstindex, last.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> first(2:2:10)
  2

  julia> first([1; 2; 3; 4])
  1

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(itr, n::Integer)

  Get the first n elements of the iterable collection itr, or fewer elements if itr is not long enough.

  See also: startswith, Iterators.take.

  │ Julia 1.6
  │
  │ This method requires at least Julia 1.6.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> first(["foo", "bar", "qux"], 2)
  2-element Vector{String}:
   "foo"
   "bar"

  julia> first(1:6, 10)
  1:6

  julia> first(Bool[], 1)
  Bool[]

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(s::AbstractString, n::Integer)

  Get a string consisting of the first n characters of s.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> first("∀ϵ≠0: ϵ²>0", 0)
  ""

  julia> first("∀ϵ≠0: ϵ²>0", 1)
  "∀"

  julia> first("∀ϵ≠0: ϵ²>0", 3)
  "∀ϵ≠"

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(q::Deque)

  Returns the first element of the deque q.

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(D::CircularDeque)

  Get the item at the front of the queue.

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(s::Stack)

  Get the top item from the stack. Sometimes called peek.

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(h::BinaryHeap)

  Returns the element at the top of the heap h.

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(h::BinaryMinMaxHeap)

  Get the first (minimum) of the heap.

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(sc)

  Argument sc is a SortedDict, SortedMultiDict or SortedSet. This function returns the first item (a k=>v pair for
  SortedDict and SortedMultiDict or a key for SortedSet) according to the sorted order in the container. Thus,
  first(sc) is equivalent to deref((sc,startof(sc))). It is an error to call this function on an empty container.
  Time: O(log n)

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(sc)

  Argument sc is a SortedDict, SortedMultiDict or SortedSet. This function returns the first item (a k=>v pair for
  SortedDict and SortedMultiDict or a key for SortedSet) according to the sorted order in the container. Thus,
  first(sc) is equivalent to deref((sc,startof(sc))). It is an error to call this function on an empty container.
  Time: O(log n)

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(sc)

  Argument sc is a SortedDict, SortedMultiDict or SortedSet. This function returns the first item (a k=>v pair for
  SortedDict and SortedMultiDict or a key for SortedSet) according to the sorted order in the container. Thus,
  first(sc) is equivalent to deref((sc,startof(sc))). It is an error to call this function on an empty container.
  Time: O(log n)

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(cb::CircularBuffer)

  Get the first element of CircularBuffer.

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(df::AbstractDataFrame)

  Get the first row of df as a DataFrameRow.

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  first(df::AbstractDataFrame, n::Integer; view::Bool=false)

  Get a data frame with the n first rows of df.

  If view=false a freshly allocated DataFrame is returned. If view=true then a SubDataFrame view into df is returned.

julia>

```

There are much worse examples, this was literally the first (haha) function I tried.

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [March 14, 2022, 2:18pm UTC](https://discourse.julialang.org/t/can-we-change-the-julia-help-from-bottom-up-to-top-down/77866/4 "2022-03-14T14:18:54Z")

</div>

How would one decide if a method is a method that users are interested in? Presumably, if it’s documented and loaded, then it’s of interest to the user?

You can filter the help docs by typing e.g. `help?> first(::Any)`, or similar for other signatures.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [March 14, 2022, 2:20pm UTC](https://discourse.julialang.org/t/can-we-change-the-julia-help-from-bottom-up-to-top-down/77866/5 "2022-03-14T14:20:56Z")

</div>

`TerminalPager` is your friend:

```julia
julia> using TerminalPager

#enter |? and you get a help prompt with pager:

pager?> 

```

---

<div class="post-metadata">

**Author:** ![NiclasMattsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/niclasmattsson/32/21988_2.png) [@NiclasMattsson](https://discourse.julialang.org/u/NiclasMattsson)\
**Post date:** [March 14, 2022, 2:32pm UTC](https://discourse.julialang.org/t/can-we-change-the-julia-help-from-bottom-up-to-top-down/77866/6 "2022-03-14T14:32:11Z")

</div>

> [@jakobnissen](#):
>
> How would one decide if a method is a method that users are interested in? Presumably, if it’s documented and loaded, then it’s of interest to the user?

In my example, getting help for `first(df::AbstractDataFrame)` and `first(df::AbstractDataFrame, n::Integer; view::Bool=false)` is certainly relevant if you’ve loaded DataFrames. But maybe not so much all the incidental stuff DataFrames needs to work, e.g. CircularBuffer, SortedMultiDict, BinaryMinMaxHeap, CircularDeque.

Maybe the help viewer could have basic and extended help, the latter accessed using a shortcut something like the [number]Ctrl-Q shortcut to jump to errors in stack traces?

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [March 14, 2022, 2:47pm UTC](https://discourse.julialang.org/t/can-we-change-the-julia-help-from-bottom-up-to-top-down/77866/7 "2022-03-14T14:47:28Z")

</div>

Maybe that could be a good idea… although I can foresee a lot of issues where people ask why, when they type `foo` in the help, the method they are looking for does not show up when others does. In order words, I feel like that would be just replacing one inconveniency with another.

---

<div class="post-metadata">

**Author:** ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)\
**Post date:** [March 14, 2022, 2:47pm UTC](https://discourse.julialang.org/t/can-we-change-the-julia-help-from-bottom-up-to-top-down/77866/8 "2022-03-14T14:47:56Z")

</div>

Extended Help is already possible.

[https://github.com/JuliaData/DataFrames.jl/issues/2248](https://github.com/JuliaData/DataFrames.jl/issues/2248)
