# The challenges of documenting generic functions

**URL:** <https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198>\
**Category:** General Usage\
**Tags:** documentation\
**Created:** [August 24, 2023, 9:18am UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198 "2023-08-24T09:18:23Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [August 24, 2023, 9:18am UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/1 "2023-08-24T09:18:23Z")

</div>

First of all, I must apologize, in advance, for the blunt language below. I’m not going to accuse anybody. I’ll just try to describe the problems I’ve encountered.

I have been using Julia for 1.5 years (and I’m sorry to skip great things about Julia) and the greatest difficulty in using Julia is the general “lack” of “manuals”.

Tutorials are excellent. But, to find out details of the arguments to library functions is sometimes extremely hard.

Most of julia’s core standard functions are very general and as a result, the most “accurate” description of the API must needs be abstract. For example, `Base.findall` is described (defined) as

> Return a vector `I` of the `true` indices or keys of `A`

There is no clue (to a newcomer) what `A` is expected to be. ~~The examples given there all use a vector for `A`.~~ From some of the examples given there, I got the (incorrect) impression that the `A` must be an array or vector. After a 1.5-year experience with Julia, I can tell that ranges and many more collections can works as `A`.

But, when I was a complete newbie, I naïvely thought that a vector is expected and wrote `findall(somecondition, collect(1:10))` in an example code in the Discourse. Then, a seasoned programmer lectured me that `collect()` should almost never be used. I asked why and where the API of `findall` is documented. Then I was shown to the source code!

The current state of documentation seems to be

1. examples,
2. the “accurate” description,
3. source code,
4. or nothing.

But, what most regular users need is something between 1 and 2: a “helpful” description of the API using an informal language (convention). For example, the `A` argument of `findall` is an “indexable collection like a vector or dictionary”, which would be linked to a discussion of generally what datatypes are indexable, where it would be explained that a Range like 1:10 is also indexable.

Here is another example of a different flavor. I was trying to find out how to specify color schemes for contour plots. I googled for “julia Plots contour color schemes” and found the excellent official documentation of color schemes:

[https://docs.juliaplots.org/latest/generated/colorschemes/](https://docs.juliaplots.org/latest/generated/colorschemes/)

except that it doesn’t tell you how to use those `palette` and `cgrads` objects and the “pre-defined color schemes” with the `contour` function.

So, I looked at the documentation of the `contour` function:

[https://docs.juliaplots.org/latest/series\_types/contour/](https://docs.juliaplots.org/latest/series_types/contour/)

The only example it includes is the `color=:turbo` style. Where are the `palette` and `cgrad` objects? Confusingly, I found another example `fill = (true, :ranbow)` on another website.

The problem here is that there is no API description of the `contour` function at one place. Or there may be one somewhere, which I haven’t been able to locate.

An example based description is excellent for a tutorial but it’s not adequate as a “manual”.

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [August 24, 2023, 10:25am UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/2 "2023-08-24T10:25:21Z")

</div>

> [@ryofurue](#):
>
> The examples given there all use a vector for `A`

Hm?

```julia
help?> findall
search: findall findmax! findmax findlast

  findall(f::Function, A)

  Return a vector I of the indices or keys of A where f(A[I]) returns true. If there are no such elements of A, return an empty array.

  Indices or keys are of the same type as those returned by keys(A) and pairs(A).

  Examples
  ≡≡≡≡≡≡≡≡

(...)

julia> d = Dict(:A => 10, :B => -1, :C => 0)
  Dict{Symbol, Int64} with 3 entries:
    :A => 10
    :B => -1
    :C => 0

  julia> findall(x -> x >= 0, d)
  2-element Vector{Symbol}:
   :A
   :C

```

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [August 24, 2023, 11:08am UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/3 "2023-08-24T11:08:43Z")

</div>

@ryofurue that all sounds reasonable to me. Documenting functions that can have arbitrary methods is hard and we probably don’t do it well enough a lot of the time.

If you have both motivation and a clear vision for improving the documentation, that makes you the best qualified person to start writing the PRs

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [August 24, 2023, 11:23am UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/4 "2023-08-24T11:23:35Z")

</div>

One thing I’ve wondered is if we could add a section header to docstrings something like `## Extended` that could hold examples, verbose descriptions, etc. Then when you `?some_function`, it would show list of more terse descriptions, but `?some_function -v` or `?some_function(::exact, ::input, ::types)` (where the types yield a single applicable method) would print the verbose version(s).

If I import `DataFrames` and then `?vcat`, I can scroll for days looking for the one I want.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [August 24, 2023, 11:43am UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/5 "2023-08-24T11:43:23Z")

</div>

The functionality exists:

```julia
julia> """
          f(x)

       My cool function.

       # Extended help

       My really cool function.

       """
       f(x) = 1
f

help?> f
search: f fd for fma fld fld1 fill fdio frexp foldr foldl flush floor float

  f(x)

  My cool function.

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

Extended help is available with `??`

help?> ? f
search: f fd for fma fld fld1 fill fdio frexp foldr foldl flush floor float

  f(x)

  My cool function.

  Extended help
  ≡≡≡≡≡≡≡≡≡≡≡≡≡

  My really cool function.

```

What I think, on the other side, is that it would be nice to have a link pointing to doc pages, when available, where more detailed description of the functions are available, as reading too much information from the REPL is not practical.

---

<div class="post-metadata">

**Author:** ![Ininterrompue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ininterrompue/32/5594_2.png) [@Ininterrompue](https://discourse.julialang.org/u/Ininterrompue)\
**Post date:** [August 24, 2023, 1:40pm UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/6 "2023-08-24T13:40:42Z")

</div>

I share your frustration with the docs, especially when learning about plotting. The contour function is in the API section [here](https://docs.juliaplots.org/latest/api/#Plots.contour-Tuple) but it doesn’t have anything close to full coverage of what is possible. (The [one](https://docs.juliaplots.org/latest/series_types/contour/) under series\_types was only meant to be a tutorial.) There’s a disconnect between people who want to plot something and do very common operations on it like change its color scheme, and trying to understand what things like `markercolor::Union{Integer, Symbol, ColorSchemes.ColorScheme, ColorTypes.Colorant}` mean [here](https://docs.juliaplots.org/latest/api/#Plots.scatter-Tuple). To be honest I could never get those cgrad and palette objects to work with contours.

I don’t think the structure of the API page that Documenter.jl uses, where all functions are on one long page, is the best way to present the desired information. [Matplotlib](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.contour.html) does it better with a function per page, considering the amount of keywords possible.

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [August 25, 2023, 1:55pm UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/7 "2023-08-25T13:55:21Z")

</div>

Thank you for pointing out my error. I’ve corrected the error in my post. My point stands, though: the official document lacks a user-friendly description of “what” `A` is.

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [August 25, 2023, 2:05pm UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/8 "2023-08-25T14:05:19Z")

</div>

I think the idea here is that `A` may be anything that has `keys`. Would it be better to provide some concrete examples of possible types in the text?

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [August 25, 2023, 2:10pm UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/9 "2023-08-25T14:10:04Z")

</div>

> If you have both motivation and a clear vision for improving the documentation, that makes you the best qualified person to start writing the PRs

I have a clear vision, I think, but I don’t have expertise to see whether my vision is a good one or not.

How do you think I should proceed? The following is a long (and not very well-written) discussion of my vision.

* * *

All experienced julia programmers have internalized _concepts_ like “iterables” and “indexables”, and so, they _naturally_ expect any “indexable” to work as the `A` argument of `findall(predicate, A)`.

But, this isn’t necessarily obvious to a newcomer. So, my idea is to explicitly write these “concepts” down as a document and use these concepts in the descriptions of the APIs throughout.

But at this point, the “write your own pull-request” work flow wouldn’t work, because I would need to convince everybody to use these concepts in the documentations.

Each time I ask for a helpful description, the experts’ answer has been that it’s impossible to give an “accurate” description because the API is completely general.

What I’m after is a description using a “convention”, which may not be 100% precise but would act as a helpful guidance when you read the manuals and it would also work as a strong constraint when you write your functions.

To elaborate on the latter point . . . For example, when you write your own function similar to `findall(predicate, A)`, you are strongly encouraged to write it in such a way that any “indexable” works as your `A`.

Here is an example: [Type of array index?](https://discourse.julialang.org/t/type-of-array-index/76065)  
, which is a thread I started more than a year ago. There, some people recommended that I should use `Int` because it always works as index into an array. But, I ended up writing a function that doesn’t assume that. Then recently I pleasantly realized that my function works for a `Dict`!

In hindsight, I wrote my function in such a way that any “indexable” works as the argument.

If everybody had known the concept, then that discussion would have been much simpler.

I tentatively call these concepts “type classes”, although I’m not at all sure whether this is a good term or not. The Haskell compiler, for example, enforces at compile time that each argument belongs to the right type classes. The julia language itself doesn’t have such a mechanism, but _by convention_, the core standard library is designed as if there were type classes. (And I’m sure that the writers of this excellent set of functions had this kind of convention.)

So, the following is a very rough stab at what I have in mind as a document of these concepts:

**“Iterable” or “Itarable Collection”:** Formally, any object that responds to the `iterate()` function is an Iterable. When you query an Iterable, it returns one “element” in the collection; when you query it a second time, it returns the next element; and . . . ; when there is no more element, it returns `nothing` by convention. [Now, this description is not accurate. The function `iterate()` works differently. My description just provides a “mental model”.]

The `for` construct uses this property of Iterable. [Are there other standard implicit uses of `iterate()`?]

For example, a `Vector` is an Iterable:

```julia
# Vector returns 3, then 9, then 4, then 1, and then nothing.
for i in [3, 9, 4, 1]
   println(i)

```

Likewise, a `Range` is an Iterable:

```julia
# Range returns 2, then 3, . . ., then 9, and finally nothing.
for i in 2:9
   println(i)

```

Also, a `Dict` is an Iterable:

```julia
# Dict returns ("pi", 3.14), then ("ee", 2.72), . . .
for (k,v) in Dict("pi"=>3.14, "ee"=>2.72, . . . )
   println(k, "=>", v)

```

You can turn a lot of objects into an Iterable even if they themselves are not Iterables. For example, an input stream of text can be turned into an Iterable by the `eachline()` function:

```julia
istream = open("textfile.txt", "r")
# eachline(istream) returns 1st line, 2nd line, . . . ,
# until the stream is exhausted.
for ll in eachline(istream)
  println(ll)

```

Internally, `eachline()` returns an object that responds to the `iterate()` function.

Analogously, you can create a different Iterable out of an object which is already an Iterable by itself:

```julia
# Vector as an Iterable provides its elements one by one:
for x in vec # vec is an Iterable by itself
  println(x)
end
# eachindex creates an Iterable that provides the indices into the vector.
for i in eachindex(vec) # different Iterable
  println(i)

```

Finally, you can write your own function (like `eachline()` above) to create an Iterable out of an object, if it makes sense to do so. As an exercise, try writing a function that would return each character from a String:

```julia
for c in eachcharacter("this is a sample string.")
  println(c)

```

[Link to the documentation of `iterate()`.]

**Indexable:**  
Formally, an Indexable is any object `A` that responds to `getindex(A,I)`.

If you give it a “key”, an Indexable gives you “the corresponding value”.  
A prime example is `Vector`:

```julia
v = [3.2, 4.0, 9.5, 1.1]
v[2] # -> 4.0
getindex(v, 2) # equivalent to v[2]

```

`Dict` is also an Indexable.  
. . . blah blah blah . . .

An Indexable is usually an Iterable. . . . blah blah blah.

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [August 25, 2023, 4:36pm UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/10 "2023-08-25T16:36:16Z")

</div>

The problem of vague documentation is to some extent a flip-side of multiple dispatch.

The core of the issue is that Julia does not distinguish very well between the documentation of a function name and the documentation of methods associated with that function name. The way it typically works is that there’s a docstring for the function name when that name is first introduced (as the docstring of some “canonical” method). Subsequent methods can (but often don’t) define their own docstrings, and the docstrings from all methods that are in the methods table at the time the documentation is generated are merged.

The “canonical” docstring for the function name necessarily has to be somewhat vague: The person introducing `findall` has absolutely no control over the methods of `findall` that someone else might implement, and what their arguments might be. All they can do is set some reasonable constraints on the arguments and the return values. These are only enforced informally, though.

Ideally, methods that stray too far from the canonical function-name-docstring should define their own docstring to extend the existing documentation – which, in fact, `findall` does: I’m also seeing docstrings for ` findall(A)` and `findall(c::AbstractChar, s::AbstractString)` You’ll never have a complete list of all the possible arguments to `findall` and their properties, though. Apart from the documentation, you might get a lot out of explicitly looking at the methods-table with `methods(findall)`.

There’s always room for improvement for any given documentation. But there’s also the fact that multiple dispatch is a double-edged sword. I would say that your experience as a “newcomer” was to some extent just the learning curve of coming to terms with the dynamic features of Julia.

It’s not just documentation: the exact same issue is at the root of the “traits” discussion. Julia’s design makes strict formal interfaces fundamentally difficult.

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [August 25, 2023, 4:45pm UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/11 "2023-08-25T16:45:27Z")

</div>

> [@goerz](#):
>
> has to be somewhat vague: The person introducing `findall` has absolutely no control over the methods of `findall` that someone else might implement, and what their arguments might be

I tend to find it very helpful when functions are documented in terms of consistency with other existing methods. e.g. `findall(x)` might be documented to return the same thing as `collect(i for (i,v) in enumerate(x) if v)`

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [August 25, 2023, 5:02pm UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/12 "2023-08-25T17:02:49Z")

</div>

> I think the idea here is that `A` may be anything that has `keys` . Would it be better to provide some concrete examples of possible types in the text?

I think that’s one way. But, in this particular case, the manual presents a set of related functions. So, perhaps, we want to say, at the top of the document, something like

> In this section, `A` is any indexable object such as array, vector, and range. The point is that all these objects can be indexed into like A[2] or A[“name”] or A[i].

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [August 25, 2023, 5:15pm UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/13 "2023-08-25T17:15:11Z")

</div>

> [@goerz](#):
>
> has to be somewhat vague: The person introducing `findall` has absolutely no control over the methods of `findall` that someone else might implement, and what their arguments might be.

That’s the very reason I have been quoting the word “accurate”. If you pursue absolute accuracy, you needs must be vague.

What I’m trying to advocate is a “convention”, a strong guidance, an agreement between developers and programmers. You don’t have to pursue absolute “control”.

That is, we could agree that the `A` argument of the `findall(predicate, A)` function should be an “Indexable” and strongly encourage adherence to this convention. We could write up such a convention and encourage everybody to follow it.

Then the documentation of the IPA would be done using the terminology from the convention.

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [August 25, 2023, 5:38pm UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/14 "2023-08-25T17:38:47Z")

</div>

To some extent, this is a problem in languages with single dispatch too. How most of them seem to handle it is by having a separate docs entry for each method. Does Documenter.jl do the same by default if you use `@autodoc` or pass it a list of modules and functions? If not, I think a big part of the problem could be addressed by tooling without any language or cultural-level changes (besides adding specific docstrings on more specific methods).

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [August 25, 2023, 6:12pm UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/15 "2023-08-25T18:12:58Z")

</div>

Imho, it’s usually confusing and unnecessary when packages extend functions by providing different behavior. If the new interface is different from the original interface, it’s normally better to introduce a new function rather than complicating an existing one.

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [August 25, 2023, 10:17pm UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/16 "2023-08-25T22:17:07Z")

</div>

> [@ToucheSir](#):
>
> To some extent, this is a problem in languages with single dispatch too.

At least in dynamic languages, i.e., with duck-typing, this is indeed similar. I recall that the sklearn docs are full of “array-like of shape (x, y)”.  
On the other hand, many languages explicitly distinguish between functions (which have a single implementation only) and methods (which might be defined differently in different classes). Thus, especially in statically typed languages, e.g., Rust or Haskell, it is very clear which interfaces  
are used and what is required by them. Here are some examples from the [Rust documentation on traits](https://doc.rust-lang.org/book/ch10-02-traits.html):

```rust
// Trait definition, i.e., summarize can have multiple implementations for different types
pub trait Summary {
    fn summarize(&self) -> String;
}

// Generic function, i.e., single implementation
// Uses summarize and thus requires argument type to implement Summary trait
pub fn notify<T: Summary>(item: &T) {
    println!("Breaking news! {}", item.summarize());
}

```

In contrast, in Julia any function can have multiple implementations (methods) and freely use other generic functions. Thereby blurring the definition and use of an interface.

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [August 26, 2023, 4:07am UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/17 "2023-08-26T04:07:31Z")

</div>

I was thinking of languages such as Java or C#, where the line can likewise be blurred if you have a bunch of method overloads that aren’t overriding some abstract method. They seem to get along well enough with their docs systems despite this, so I don’t see any reason Julia couldn’t do the same. For packages that overload methods in other packages/stdlibs, maybe something like the `impl X for Y` rendering used by Rustdoc would make sense. In other words, showing the source module of the function as well.

---

<div class="post-metadata">

**Author:** ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)\
**Post date:** [August 28, 2023, 8:40pm UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/18 "2023-08-28T20:40:25Z")

</div>

This is just my personal opinion about one aspect of the documentation that I think could be improved upon: **the examples used**. Sometimes they’re more complicated than they should.

For instance, let’s take the documentation of [broadcasting](https://docs.julialang.org/en/v1/manual/arrays/#Broadcasting).

First, not sure why using `a = rand(2,1); A = rand(2,3);` as the simplest example to illustrate what broadcasting does. In general, I see a tendency to use matrix as a first example, which I think it’s not the best approach.

I’d consider it as a first example (cases with matrices and others can be added after that).

```julia
x = [1,2,3]
y = [10,10,10]

broadcast(*, x, y)

```

to show that it’s unnecessary, and then compare it with

```julia
x = [1,2,3]
y = 10

broadcast(*, x, y)

```

Second, examples sometimes use functions that are quite specific and/or require additional notions. In the same section, I wouldn’t have used `ceil.(UInt8, [1.2 3.4; 5.6 6.7])`. It requires that the user know swhat `ceil` does and what `Uint8` is, when the documentation should start with an example that covers the whole audience.

Third, I’d also avoid defining collections within the arguments of a function. The example of `ceil` is one case. Another is:  
`([1, 2, 3], [4, 5, 6]) .+ ([1, 2, 3],)`  
which requires rereading it twice to separate the brackets and see what’s going on.

Alternative:

```julia
x = ([1, 2, 3], [4, 5, 6])
y = ([1, 2, 3],)

x .+ y

```

and again, I would’ve probably used a simpler example for making the point.

I focused on broadcasting, but it’s just a random example of a common pattern.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [August 29, 2023, 5:26am UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/19 "2023-08-29T05:26:01Z")

</div>

> [@ryofurue](#):
>
> I’m not going to accuse anybody. I’ll just try to describe the problems I’ve encountered.

While I agree that a lot of documentation could be improved (this is true for almost all software), note that discussions like this are unlikely to accomplish a significant change because they are not specific enough.

It is better to focus effort on actually fixing the docs whenever you encounter a problem. Eg PR that reviews the docs for a group of methods and clarifies these questions.

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [August 29, 2023, 6:17am UTC](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198/20 "2023-08-29T06:17:27Z")

</div>

> [@Tamas\_Papp](#):
>
> It is better to focus effort on actually fixing the docs whenever you encounter a problem. Eg PR that reviews the docs for a group of methods and clarifies these questions.

Please look at my response to @Raf (I think. I’m sorry if I’m mistaken), who gave me the same advice.

In short, my vision is to write up a document, which would define type classes _as convention_ (because the language itself doesn’t have a mechanism to enforce type classes). Then we would use the terms and ideas in the document to revise the documentations.

In that post of mine, I just presented a sample of the document I have in mind, but I don’t have expertise enough to complete a draft of such a big document.

So, to accomplish what I think we can/should do, just the _write-your-PR approach_ doesn’t work.

[Next page](https://discourse.julialang.org/t/the-challenges-of-documenting-generic-functions/103198.md?page=2)
