Where is the "?" being served from?



When we type “?”, where is the help being served from? Is there a big file somewhere with this information?
I’ve tried searching the .julia folder (for instance length(collection)), but curiously there are no hits.


Okay, if ASCII search cannot find it, then it is probably baked into the compiled files, isn’t it?


Depends what you mean with “served”. Docstrings are attached to objects with


and the docstring for length is defined at https://github.com/JuliaLang/julia/blob/636f5ad21ff3fa2ff55bbd2f602355d3932c2d5b/base/abstractarray.jl#L124-L143.

These get parsed into Markdown and stored.

If you want to follow the thread you can do

julia> @macroexpand @doc +
:((Base.Docs.doc)((Base.Docs.Binding)(Main, :+)))

julia> @which (Base.Docs.doc)((Base.Docs.Binding)(Main, :+))
doc(binding::Base.Docs.Binding) in REPL at stdlib/v1.0/REPL/src/docview.jl:85

But where they are ultimately stored is in the sysimage (with everything else).


Just to go one level deeper, it’s stored in a hidden dictionary within each module that has docstrings:

julia> getfield(Base, Docs.META)
IdDict{Any,Any} with 729 entries:
  Base.parentmodule               => MultiDoc(Type[Tuple{Module}, Tuple{DataType}, Tuple{Function}, Tuple{Any,Any}], IdDict{Any,Any}(Tuple{Any,Any}=>DocStr(svec("    parentmodule(f::Function, types) ->…
  Base.strip                      => MultiDoc(Type[Tuple{AbstractString}], IdDict{Any,Any}(Tuple{AbstractString}=>DocStr(svec("    strip(str::AbstractString, [chars])\n\nRemove leading and trailing cha…
  Base.__precompile__             => MultiDoc(Type[Union{Tuple{}, Tuple{Bool}}], IdDict{Any,Any}(Union{Tuple{}, Tuple{Bool}}=>DocStr(svec("    __precompile__(isprecompilable::Bool)\n\nSpecify whether t…
  Base.bswap                      => MultiDoc(Type[Tuple{Union{Int8, UInt8}}], IdDict{Any,Any}(Tuple{Union{Int8, UInt8}}=>DocStr(svec("    bswap(n)\n\nReverse the byte order of `n`.\n\n# Examples\n```j…
  Base.any!                       => MultiDoc(Type[Tuple{Any,Any}], IdDict{Any,Any}(Tuple{Any,Any}=>DocStr(svec("    any!(r, A)\n\nTest whether any values in `A` along the singleton dimensions of `r` a…
  ⋮                               => ⋮

julia> getfield(Base, Docs.META)[Docs.Binding(Base, :length)]
Base.Docs.MultiDoc(Type[Union{}, Tuple{AbstractArray}, Tuple{AbstractString}], IdDict{Any,Any}(Union{}=>DocStr(svec("    length(collection) -> Integer\n\nReturn the number of elements in the collection.\n\nUse [`lastindex`](@ref) to get the last valid index of an indexable collection.\n\n# Examples\n```jldoctest\njulia> length(1:5)\n5\n\njulia> length([1, 2, 3, 4])\n4\n\njulia> length([1 2; 3 4])\n4\n```\n"), ```
length(collection) -> Integer




Just checked this out for a (likely unique) name in the Statistics.quantile help using ripgrep (rg), a tool which I only know since very short time. Incredibly fast!

$ rg -al Hyndman /Applications/Julia-1.0.app/