<p>Most languages have a way of writing doc comments. Doc comments above a function, class, or struct provide a strucutred way to describe every part of the function, like this:</p>
<pre><code>/** Compute the sum of two numbers
  * @param A the first operand
  * @param B the second operand
  * @returns the sum of A and B
  */
function sum(a, b) {...}
</code></pre>
<p>This can then be used by IDEs and documentation generators to give nice pretty tool-tips when typing the argument to a function. Super helpful.</p>
<p>To my frustration however, many developers do not type doc comments, forcing me to open the function to figure out what the arguments mean and what the return value is, interrupting your workflow.</p>
<p>Why don't languages enforce documenting every method? Seems it would be very convenient. People could leave it blank but often just being reminded that there is a space is enough to encourage documenting.</p>
<p>My idea is my language will enforce documenting every field and parameter. It will use some different syntax distinct from comments. The compiler could also use this to generate more helpful error messages. Is this a good idea?</p>

<comments><documentation>
Enforcing doc comments in the compiler, good idea or not?
CC BY-SA 4.0
2023-05-19T17:33:50.573Z
Seems like linter should do this rather than a compiler.
chrisaycock
CC BY-SA 4.0
2023-05-24T02:45:09.480Z
I think it's worth mentioning that the concept of "doc comment" does exist in PHP. It's part of RTTI: `(new ReflectionClass("A"))->getDocComment()`. I think it's also worth mentioning that both PHP and your idea are gonna frustrate Python programmers for you are writing your comment at the wrong place.
Longinus
<p>My experience, when comments were enforced by policy, was things like:</p>
<pre><code>x = x + 1       // Add one to x.
l = readline()  // Read the next line.
return y        // Return the value we just calculated.
</code></pre>
<p>They meet the mandated requirements, but are less than useless.</p>
<p>Giving meaningful names is a far better way of documenting what is happening:</p>
<pre><code>line_count = line_count + 1
line = readline()
return sum
</code></pre>
<p>Where comments really <em>are</em> useful is documenting <em>why</em> something is done (or other things that can't be made obvious by simply reading the code).</p>
<p>Too many people find it easier to follow the letter of the law, not its spirit.</p>
<hr />
<p>You can't change human nature.
But, if you have the time and patience, you <em>can</em> inspire people to change their behaviour.</p>
<p>Show the author the <code>x = x + 1</code> line and ask <em>why</em> they incremented it.
They'll likely have to look back in the code to figure out what <code>x</code> is first.
Then show them that had the variable been called <code>line_count</code>, the &quot;why&quot; would have been obvious, and you wouldn't have asked the embarrassing question in the first place.</p>

CC BY-SA 4.0
2023-05-19T18:51:52.567Z
2023-05-19T19:48:04.760Z
2023-05-19T19:48:04.760Z
Ray Butterworth
CC BY-SA 4.0
2023-05-20T03:33:57.327Z
I agree with this, but it's a bit of a straw man argument. Nobody sane thinks every *statement* should be commented, but there are good reasons to expect every public *declaration* to be commented, and some linters enforce this rule.
kaya3
CC BY-SA 4.0
2023-05-20T03:40:09.643Z
@kaya3, you've obviously never worked for a manager who got there via an MBA rather than by promotion through the ranks.
Ray Butterworth
CC BY-SA 4.0
2023-05-20T03:49:43.587Z
That's true, I haven't :D but at least, the question only asks about *"Doc comments above a function, class, or struct"*, and *"documenting every method"* vs. *"documenting every field and parameter"* ─ not statements.
kaya3
CC BY-SA 4.0
2023-05-23T21:30:02.940Z
@kaya3 Statements, declarations, it's the same phenomenon. I've worked on code bases where a linter required documentation for every public declaration, and a lot of it was of the form “`frobnicate(x)`: the function frobnicates its argument” (in a context where the meaning of “frobnicate” was not at all obvious).
Gilles 'SO- stop being evil'
<h1>Not everything needs to be</h1>
<p>Consider this real-world example (with documentation included):</p>
<pre class="lang-swift prettyprint-override"><code>/// The different lifecycles for dependencies that are provided by default.
///
/// This is meant to be used with ``Service/init(_:_:name:_:)``; each case describes a different way
/// of determining when the callback should be called vs. when the previous return value should be
/// re-used.
public struct Scope: Equatable {
    internal let value: UnderlyingType
    
    /// Call the provided callback every time the dependency is requested.
    public static let transient = Scope(value: .transient)
    /// Create a lazy-loaded singleton, and re-use the same one for further requests.
    /// - Note: This scope is for singletons that are created by the callback. If the singleton is
    /// created elsewhere, use ``Service/init(constant:_:name:)`` instead.
    public static let singleton = Scope(value: .singleton)
    /// Re-use an existing instance if it exists, but do not hold onto an unused instance.
    /// - Important: This scope can only be used with classes and actors. Value types are not
    /// allowed to be registered weakly.
    public static let weak = Scope(value: .weak)
    
    internal enum UnderlyingType: Equatable {
        case transient
        case singleton
        case weak
    }
}
</code></pre>
<p>(<a href="https://github.com/Tiny-Home-Consulting/Dependiject/blob/4a3cd4fbfb95b1e171081d595c45688bbc07ddc4/Dependiject/RegistrationConvertible.swift#L49" rel="noreferrer">Source</a>)</p>
<p>In this case, the struct-wrapping-an-enum is only used <a href="https://github.com/Tiny-Home-Consulting/Dependiject/issues/67" rel="noreferrer">so that more cases can be added with a minor version bump</a>. The documentation of each case already lives on the <code>public</code> members, so forcing documentation on the enum would be redundant.</p>

CC BY-SA 4.0
2023-05-19T17:43:02.280Z
2023-05-19T17:43:02.280Z
Bbrk24
CC BY-SA 4.0
2023-05-19T17:46:52.543Z
Well you could use `@inheritdoc` concept like many languages have when the documentation is the same as the parent class/method
mousetail 'he-him'
CC BY-SA 4.0
2023-05-19T17:49:27.203Z
InheritDoc tags usually go superclass to subclass or interface to implementation, not outer scope to inner scope as would apply here.
Bbrk24
CC BY-SA 4.0
2023-05-19T17:54:23.917Z
For another example, see [this file](https://github.com/Tiny-Home-Consulting/Dependiject/blob/master/Dependiject/RegistrationBuilder.swift) -- these methods are only called by a compile-time transformation (a limited macro system), so the user doesn't ever see them.
Bbrk24
<p>No expert, but this would probably lead to some terrible stuff:</p>
<ul>
<li>people might add /*** - */ before every function just for quick prototyping, and then they would forget about it.</li>
<li>they might try to avoid functions wherever possible, stuffing everything in one big main()-style function.</li>
</ul>
<p>I do like the idea though, so here is my suggestion:</p>
<ul>
<li>If you have some config file (Cargo.toml etc), consider optionally enabling this as a warning or error, so users can choose what they need for each project.</li>
<li>Only enforce it for public functions - whether that means all functions declared public or just the ones exposed by the project (for the library authors out there) is up to you or the config file, if it exists:</li>
</ul>
<pre><code>/// this is used in the library, but its purpose is pretty clear from
/// the name and input/output types, no real need to enforce a comment (imo).
fn transform_something(a) -&gt; b { ... }
/// this is exposed to users of the library in this example,
/// so I should explain what it does and why.
public fn perform_calculation(string) -&gt; b {
    transform_something(string.parse_to_a())
}
</code></pre>

CC BY-SA 4.0
2023-05-23T19:45:52.943Z
2023-05-23T19:45:52.943Z
Dummi26
<p>I think this is definitely a bad idea. This will immediately become cumbersome for library authors, as well as application developers (those who develop things are intended to be used by non-programmers).</p>

CC BY-SA 4.0
2023-05-19T19:30:13.833Z
2023-05-19T19:30:13.833Z
ice1000
CC BY-SA 4.0
2023-05-23T20:32:45.433Z
I disagree at least in the context of open-source library functions. A doc-comment (even an empty one) on a public function can be edited by a new contributor. Occasionally this leads to a general description of the function, followed by a description of a few arguments, followed by a few general remarks, followed by a detailed description, followed by a comprehensive description of the whole method. It doesn't happen in the majority of cases, but it's worth lowering the cognitive barrier for each step.
finnw
# Enforcing doc comments in the compiler, good idea or not?
Posted by: username_0 on 2023-05-19
Most languages have a way of writing doc comments. Doc comments above a function, class, or struct provide a strucutred way to describe every part of the function, like this:
/** Compute the sum of two numbers
  * @param A the first operand
  * @param B the second operand
  * @returns the sum of A and B
  */
function sum(a, b) {...}

This can then be used by IDEs and documentation generators to give nice pretty tool-tips when typing the argument to a function. Super helpful.
To my frustration however, many developers do not type doc comments, forcing me to open the function to figure out what the arguments mean and what the return value is, interrupting your workflow.
Why don't languages enforce documenting every method? Seems it would be very convenient. People could leave it blank but often just being reminded that there is a space is enough to encourage documenting.
My idea is my language will enforce documenting every field and parameter. It will use some different syntax distinct from comments. The compiler could also use this to generate more helpful error messages. Is this a good idea?
**Tags:** comments documentation
> **Comments:**
> **username_1**: Seems like linter should do this rather than a compiler.  
> **username_2**: I think it's worth mentioning that the concept of "doc comment" does exist in PHP. It's part of RTTI: `(new ReflectionClass("A"))->getDocComment()`. I think it's also worth mentioning that both PHP and your idea are gonna frustrate Python programmers for you are writing your comment at the wrong place.  
---
## 4 answers
### Answer by username_3 on 2023-05-19. Score: 9
My experience, when comments were enforced by policy, was things like:
x = x + 1       // Add one to x.
l = readline()  // Read the next line.
return y        // Return the value we just calculated.

They meet the mandated requirements, but are less than useless.
Giving meaningful names is a far better way of documenting what is happening:
line_count = line_count + 1
line = readline()
return sum

Where comments really are useful is documenting why something is done (or other things that can't be made obvious by simply reading the code).
Too many people find it easier to follow the letter of the law, not its spirit.

You can't change human nature.
But, if you have the time and patience, you can inspire people to change their behaviour.
Show the author the x = x + 1 line and ask why they incremented it.
They'll likely have to look back in the code to figure out what x is first.
Then show them that had the variable been called line_count, the "why" would have been obvious, and you wouldn't have asked the embarrassing question in the first place.
> **Comments:**
> **username_4** (2023-05-20): I agree with this, but it's a bit of a straw man argument. Nobody sane thinks every *statement* should be commented, but there are good reasons to expect every public *declaration* to be commented, and some linters enforce this rule.  
> **username_3** (2023-05-20): @kaya3, you've obviously never worked for a manager who got there via an MBA rather than by promotion through the ranks.  
> **username_4** (2023-05-20): That's true, I haven't :D but at least, the question only asks about *"Doc comments above a function, class, or struct"*, and *"documenting every method"* vs. *"documenting every field and parameter"* ─ not statements.  
> **username_5** (2023-05-23): @kaya3 Statements, declarations, it's the same phenomenon. I've worked on code bases where a linter required documentation for every public declaration, and a lot of it was of the form “`frobnicate(x)`: the function frobnicates its argument” (in a context where the meaning of “frobnicate” was not at all obvious).  
---
### Answer by username_6 on 2023-05-19. Score: 6
Not everything needs to be
Consider this real-world example (with documentation included):
/// The different lifecycles for dependencies that are provided by default.
///
/// This is meant to be used with ``Service/init(_:_:name:_:)``; each case describes a different way
/// of determining when the callback should be called vs. when the previous return value should be
/// re-used.
public struct Scope: Equatable {
    internal let value: UnderlyingType
    
    /// Call the provided callback every time the dependency is requested.
    public static let transient = Scope(value: .transient)
    /// Create a lazy-loaded singleton, and re-use the same one for further requests.
    /// - Note: This scope is for singletons that are created by the callback. If the singleton is
    /// created elsewhere, use ``Service/init(constant:_:name:)`` instead.
    public static let singleton = Scope(value: .singleton)
    /// Re-use an existing instance if it exists, but do not hold onto an unused instance.
    /// - Important: This scope can only be used with classes and actors. Value types are not
    /// allowed to be registered weakly.
    public static let weak = Scope(value: .weak)
    
    internal enum UnderlyingType: Equatable {
        case transient
        case singleton
        case weak
    }
}

(Source)
In this case, the struct-wrapping-an-enum is only used so that more cases can be added with a minor version bump. The documentation of each case already lives on the public members, so forcing documentation on the enum would be redundant.
> **Comments:**
> **username_0** (2023-05-19): Well you could use `@inheritdoc` concept like many languages have when the documentation is the same as the parent class/method  
> **username_6** (2023-05-19): InheritDoc tags usually go superclass to subclass or interface to implementation, not outer scope to inner scope as would apply here.  
> **username_6** (2023-05-19): For another example, see [this file](https://github.com/Tiny-Home-Consulting/Dependiject/blob/master/Dependiject/RegistrationBuilder.swift) -- these methods are only called by a compile-time transformation (a limited macro system), so the user doesn't ever see them.  
---
### Answer by username_7 on 2023-05-23. Score: 4
No expert, but this would probably lead to some terrible stuff:

people might add /*** - */ before every function just for quick prototyping, and then they would forget about it.
they might try to avoid functions wherever possible, stuffing everything in one big main()-style function.

I do like the idea though, so here is my suggestion:

If you have some config file (Cargo.toml etc), consider optionally enabling this as a warning or error, so users can choose what they need for each project.
Only enforce it for public functions - whether that means all functions declared public or just the ones exposed by the project (for the library authors out there) is up to you or the config file, if it exists:

/// this is used in the library, but its purpose is pretty clear from
/// the name and input/output types, no real need to enforce a comment (imo).
fn transform_something(a) -> b { ... }
/// this is exposed to users of the library in this example,
/// so I should explain what it does and why.
public fn perform_calculation(string) -> b {
    transform_something(string.parse_to_a())
}
---
### Answer by username_8 on 2023-05-19. Score: 4
I think this is definitely a bad idea. This will immediately become cumbersome for library authors, as well as application developers (those who develop things are intended to be used by non-programmers).
> **Comments:**
> **username_9** (2023-05-23): I disagree at least in the context of open-source library functions. A doc-comment (even an empty one) on a public function can be edited by a new contributor. Occasionally this leads to a general description of the function, followed by a description of a few arguments, followed by a few general remarks, followed by a detailed description, followed by a comprehensive description of the whole method. It doesn't happen in the majority of cases, but it's worth lowering the cognitive barrier for each step.  
---
