# Using code\_typed to generate docstring templates

**URL:** <https://discourse.julialang.org/t/using-code-typed-to-generate-docstring-templates/123725>\
**Category:** General Usage\
**Tags:** documentation\
**Created:** [December 11, 2024, 7:00pm UTC](https://discourse.julialang.org/t/using-code-typed-to-generate-docstring-templates/123725 "2024-12-11T19:00:59Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tetrakai](https://avatars.discourse-cdn.com/v4/letter/t/4da419/32.png) [@Tetrakai](https://discourse.julialang.org/u/Tetrakai)\
**Post date:** [December 11, 2024, 7:00pm UTC](https://discourse.julialang.org/t/using-code-typed-to-generate-docstring-templates/123725/1 "2024-12-11T19:00:59Z")

</div>

I came up with the following idea:

```julia
function doctemplate(f, args)
    x = @code_typed f(args...)
    src = x[1]
    sig = split(string(src.parent.def), " @")[1]
    args = string.(src.slotnames)[2:end]
    argtypes = string.(src.slottypes)[2:end]
    rettype = string(x[2])

    argvec = args .* " :: " .* argtypes .* " : ARG_DESC"
    argstr = join(argvec, "\n")

    docstr = """
        $sig

    METHOD_DESC

    # Arguments
    $argstr

    # Returns
    $rettype
    """

    return docstr
end

function addnums(a, b::Int16)
    res = a + b
    return res
end

docstr = doctemplate(addnums, (10, Int16(3)));
print(docstr)

```

That produces:

```julia
julia> print(docstr)
    addnums(a, b::Int16)

METHOD_DESC

# Arguments
a :: Int64 : ARG_DESC
b :: Int16 : ARG_DESC

# Returns
Int64

```

As can be seen, this produces a docstring with signature and types filled in.

I imagine a solution like here could be then implemented to insert these docstrings into the source:

> **[GitHub - baggepinnen/AutomaticDocstrings.jl: Automatically generated docstring stubs](https://github.com/baggepinnen/AutomaticDocstrings.jl)**
>
> Automatically generated docstring stubs

Then writing the docs becomes much more pleasurable, imo.

Is there anything odd about doing this? Few people care about auto-docstrings? It is considered bad practice? Am I reinventing the wheel?

Thanks for any feedback.

---

<div class="post-metadata">

**Author:** ![OmarElrefaei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/omarelrefaei/32/43002_2.png) [@OmarElrefaei](https://discourse.julialang.org/u/OmarElrefaei)\
**Post date:** [December 12, 2024, 8:38pm UTC](https://discourse.julialang.org/t/using-code-typed-to-generate-docstring-templates/123725/2 "2024-12-12T20:38:19Z")

</div>

Unfortunately Julia’s flexibility and type system is going to make it a little more complicated than that.  
Example, your function doesn’t restrict `a` to be an `Int64` but the docstring implies that. That happened because that was the type of the argument you actually passed (ie the `10`).

---

<div class="post-metadata">

**Author:** ![OmarElrefaei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/omarelrefaei/32/43002_2.png) [@OmarElrefaei](https://discourse.julialang.org/u/OmarElrefaei)\
**Post date:** [December 12, 2024, 8:45pm UTC](https://discourse.julialang.org/t/using-code-typed-to-generate-docstring-templates/123725/3 "2024-12-12T20:45:19Z")

</div>

I’ve been actually wondering if a more advanced tool that tries to heuristically infer arguments types from lots of example code (or test suites) for functions that have their arguments untyped. Because unfortunately there are many useful functions that don’t have their arguments typed, by do not in fact accept any type of variable.

The idea in my mind was about a documentation search tool that is more helpful than functions such as `methodswith`.

Anyway I’m rambling on a tangent. Don’t wory if it doesn’t make sense, that’s probably because it is not very clear in my head yet. I want to flush this idea out and ask the community like you if that might be a useful tool.

---

<div class="post-metadata">

**Author:** ![Tetrakai](https://avatars.discourse-cdn.com/v4/letter/t/4da419/32.png) [@Tetrakai](https://discourse.julialang.org/u/Tetrakai)\
**Post date:** [December 12, 2024, 11:53pm UTC](https://discourse.julialang.org/t/using-code-typed-to-generate-docstring-templates/123725/4 "2024-12-12T23:53:55Z")

</div>

Instead of allowed types, the docstring demonstrates _tested_ types.

Ie, as used within the package being documented, `a` is always `Int64`. There is a guarantee this has been tested.

Other types could still work, but similar ones probably result in degraded performance. Eg, something like `String15` vs `String` or `Vector` vs `MVector`. Or it may error, the docstring makes no claim about that.

Is it a bad idea for docstring to only indicate how the function is used within the package itself?

---

<div class="post-metadata">

**Author:** ![Tetrakai](https://avatars.discourse-cdn.com/v4/letter/t/4da419/32.png) [@Tetrakai](https://discourse.julialang.org/u/Tetrakai)\
**Post date:** [December 12, 2024, 11:55pm UTC](https://discourse.julialang.org/t/using-code-typed-to-generate-docstring-templates/123725/5 "2024-12-12T23:55:25Z")

</div>

> [@OmarElrefaei](#):
>
> I’ve been actually wondering if a more advanced tool that tries to heuristically infer arguments types from lots of example code (or test suites) for functions that have their arguments untyped.

Yes, except its not a heuristic. It is only guaranteed the documented type works.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [December 13, 2024, 2:03am UTC](https://discourse.julialang.org/t/using-code-typed-to-generate-docstring-templates/123725/6 "2024-12-13T02:03:53Z")

</div>

> [@Tetrakai](#):
>
> Is it a bad idea for docstring to only indicate how the function is used within the package itself?

If that function is intended to always take `a::Int64`, then no, but you should restrict the annotation accordingly. If you intend users to be able to provide other types for `a`, then yes it’s very bad to document only one possible type for it because documentation is for usage.

> [@Tetrakai](#):
>
> Instead of allowed types, the docstring demonstrates _tested_ types.

Some functions are documented with `abstract` types e.g. `AbstractArray`, but obviously not every concrete subtype that ever existed can be tested at once. The contract in composability is that the developer has adequately implemented and tested an interface and the users in turn have faithfully extended that interface to new types, therefore new code that developers can’t possibly anticipate will still work. Of course some part of that can go wrong in practice, hence bug reporting and patches.

---

<div class="post-metadata">

**Author:** ![OmarElrefaei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/omarelrefaei/32/43002_2.png) [@OmarElrefaei](https://discourse.julialang.org/u/OmarElrefaei)\
**Post date:** [December 13, 2024, 3:24pm UTC](https://discourse.julialang.org/t/using-code-typed-to-generate-docstring-templates/123725/7 "2024-12-13T15:24:43Z")

</div>

> [@Tetrakai](#):
>
> Instead of allowed types, the docstring demonstrates _tested_ types.

Check out this [talk](https://www.youtube.com/live/kc9HwsxE1OY?si=lWL1FHDlWSAG_IbR) by one of the developers from the core team. It was enlightening the first time I watched it.  
The idea of only documenting tested types might be very robust in the sense that it’ll never document something that doesn’t work, but it defies one of the most fundamental paradigms in Julia, [Multiple Dispatch](https://docs.julialang.org/en/v1/manual/methods/)

As a brief example, I might want to write a function that prints a matrix in a fancy way (maybe formats it as a markdown table). The best practice in Julia is to define `fancy_print(m::AbstractMatrix)` and use `m` within the function in a way that is compatible with any matrix object that is a sub-type of AbstractMatrix. If I do this right, then anyone can go ahead and use it as follows.

```julia
import LinearAlgebra: UpperTriangular
mat = [1 4 7; 2 5 8; 3 6 9]
upper_tri_mat = UpperTriangular(mat)

fancy_print(mat) # would work
fancy_print(upper_tri_mat) #would work

```

If appropriate, julia could even produce different machine code for the two different invocations (this is called method specialization)  
I might try to test my function with a few matrix types, but I can’t really test with all of them. One of the most elegant things about Julia is that a it allows someone else to define their own matrix type and use it with my fancy\_print function, and it’d work right out of the box.

> Reminder that you can’t have variables of type `AbstractMatrix` directly. All variables are of concrete types. [Abstract types](https://docs.julialang.org/en/v1/manual/types/#man-abstract-types) only define a hierarchy of types (and by convention an implicit common “interface”)

* * *

Yeah forgive me about that heuristic thing, it is a very different idea not about documentation at all.

---

<div class="post-metadata">

**Author:** ![Tetrakai](https://avatars.discourse-cdn.com/v4/letter/t/4da419/32.png) [@Tetrakai](https://discourse.julialang.org/u/Tetrakai)\
**Post date:** [December 14, 2024, 11:35pm UTC](https://discourse.julialang.org/t/using-code-typed-to-generate-docstring-templates/123725/8 "2024-12-14T23:35:47Z")

</div>

Thanks all.

First, I will say my current project isn’t really optimized for multiple dispatch (ie, reusability). Maybe there is a tradeoff vs performance or code-readability there, but I can definitely see a benefit even for my own potential similar future projects.

Second, what about docs for non-exported functions? From looking at julia packages I see it is common for those to have little/no documentation.

Wouldn’t it be better if those had some kind of auto-docstring, then the developer would only need to fill in the placeholder text? The default now is to just let the code speak for itself.

Seems like a “don’t let perfect be the enemy of good” situation.

Edit:  
A third point is the expected primary audience for my code is c++, etc devs with no familiarity with julia. So it seems useful to document everything.
