DEV Community

Medea
Medea

Posted on

Commenting: where?

Some people comment on the line after the code is done:

print(hello) # printing hello
Enter fullscreen mode Exit fullscreen mode

and some people comment on the line after:

print(hello)
# printing hello
Enter fullscreen mode Exit fullscreen mode

I personally comment on the line after.


Which way do you do it?

Discussion (30)

Collapse
dvddpl profile image
Davide de Paolis

first answer: nowhere. code should be readable and understandable without having to explain it in english ( which often ends up even more verbose and confusing, and most of the time outdated)

second answer: above. if you need to explain WHY some code does something ( and not WHAT) place it before, that means, the line above. you read the code from top to bottom, so first thing you read the comment that introduces/explain what is following.

Collapse
tandrieu profile image
Thibaut Andrieu

I wouldn't be so categorical. The auto-documented code may be possible with high level language like Python or Ruby, and simple business logic. But when dealing with low level kernel code in C, C++ or scientific algorithm, even in Python, I dare you to understand it without comment.
Could-you explain me what does this code ? 😁

// Compute an approximation of 1/sqrt(number)
float Q_rsqrt( float number )
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;

    x2 = number * 0.5F;
    y  = number;
    i  = * ( long * ) &y;
    i  = 0x5f3759df - ( i >> 1 );
    y  = * ( float * ) &i;
    y  = y * ( threehalfs - ( x2 * y * y ) );
}
Enter fullscreen mode Exit fullscreen mode

For the answer: en.wikipedia.org/wiki/Fast_inverse...

Collapse
natescode profile image
Nathan Hedglin • Edited on

😂 no one should code like, you do realize that's 30+ year old code right?

High level languages aren't special. Statically typed languages auto document types which should have good naming plus tools like Swagger UI help too.

I'd deny their pull request. These days we'd have a better named function and variables.

Furthermore, that's a good example of more complex code that needs a comment of WHY we need a faster inverse square root function.

Thread Thread
tandrieu profile image
Thibaut Andrieu

Yeah, this might not be a good example, but I like it so much 😂.

Just to says that not everyone is a web developers. When dealing with embed aeronautical computer, scientific processing or legacy industrial application, you don't have Swagger and all the modern fancy stuff. C++ is still not certified for aeronautics (as I know. Maybe now it is), and most of the code is in plain C. This kind of program is about 100 millions lines of codes, you just cannot refactor it.

You have to cope with legacy, and renaming a method or a variable in a several millions line of code monolith is not always possible. So when you had finally understood what this particular part of code is doing, you better comment it for the next poor fool who will get lost there. Comment don't break the code. Renaming does...

It may also be the case on brand new code. If you implement a research paper, either you use the same variables that the one used in paper equations and you end up with meaningless variable like "a", "beta", "mu", etc... so loved by mathematicians, either you try to use good naming but in this case you diverge from original documentation.

I agree, code should be self-documented when possible. But sometime comments is the only solution.

Thread Thread
natescode profile image
Nathan Hedglin • Edited on

Great example! Exactly my point! Do everything you can but often comments SHOULD still exist.

Swagger was just an example. Function and variable names are documentation, variable names are documentation, types are documentation, and lastly comments are documentation :-)

Collapse
vulcanwm profile image
Medea Author

Oh okay

Collapse
myleftshoe profile image
myleftshoe

I prefer minimal comments too - you have to maintain them as well as the code.

I don't know what is worse for a complex piece of code - no comments or comments that no longer reflect what is going on - as you said, it can lead to more confusion and send you down a rabbit hole.

Collapse
vulcanwm profile image
Medea Author

Ah okay

Collapse
vulcanwm profile image
Medea Author

Oh okay-

Collapse
kelvinokuroemi profile image
KelvinOkuroemi

Everybody says this without examples.
Could you give an example of a comment that explains the why?

Collapse
dvddpl profile image
Davide de Paolis • Edited on

the WHY is mostly some business logic rule or requirement, or something that by thinking about the feature/functionality is cumbersome or counterintuitive. ( or maybe you want to point out some very hidden internals of a native or 3rd party method ).

const add = (a, b) => a + b
Enter fullscreen mode Exit fullscreen mode

here a comment is absolutely useless, what value would a comment like receives 2 numbers as parameters and returns one number which is the sum of the 2 add?

if on the other hand you have a method that sums number but should never return an odd number and therefore appends 1 to make the result even ( dont ask me why you would have such a method, just made that up), a comment might make sense indeed.

const noOddsAdd = (a,b) => {
  let sum = a+b
// our legacy system can't accept odd numbers 
// therefore whenever we do a sum operation we need to return an even number 
// and add 1 to any odd result;
  return sum%2 !=0 ? ++sum : sum
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
dvddpl profile image
Davide de Paolis

another reason why comments should be minimal, even to explain the WHY above is that we should have Unit Tests! Unit Tests are uptodate documentation of the edge cases and weird behaviours of a method.

test("when sum would be odd, method returns an even number anyway", ()=>{
const result = noOddsAdd(4,5);
expect(result).toBe(10)
))
Enter fullscreen mode Exit fullscreen mode
Collapse
clpsplug profile image
C. Plug

This depends on the scope and the length of the comment and the PEP 8 coding standard.

  • On the same line if the comment:

    • is for only one line and it doesn't make the line longer than 120 characters (see PEP8,) or
    • it is for type-hinting a variable.
    run_something()  # Run something.
    instance = None  # type: Optional[SomeClass]
    
    • Such comment also has two spaces after the code as PEP8 recommends.
  • Before the block in question if the comment

    • is for a block of code or
    • the one-liner comment is so long it exceeds the 120 char limit.
    # A method streak to process an input.
    data = run_something(input)
    data = and_then_this(data)
    output = to_accomplish_your_task(data)
    
  • (Very rare) if an indented block is too big (or too complicated) to understand the structure, I may have to place a comment on the bottom of the block to indicate the end of what block.

  if something:
      VERY_LONG_CODE_HERE()
      SO_LONG_THAT_YOU_CANNOT_SEE()
      THE_START_AND_THE_END_OF_THE_IF_SIMULTANEOUSLY()
  # endif something:
Enter fullscreen mode Exit fullscreen mode

On the side note, I reckon one-liner comments usually are, or can be, made unnecessary by making the code obvious enough. Therefore, most of the comments in my code are above the lines involved.

Collapse
vulcanwm profile image
Medea Author

Cool!

Collapse
nombrekeff profile image
Keff • Edited on

For me it's above, so it follows the flow of the code.

But I strive to use the least amount of comments posible, as mentioned in other comments, code should explain itself. For me comments should explain why, not how. Why are we doing this in this particular way.

Comments are also another dependency to take care of when refactoring or modifying code. You must keep them updated with the code, otherwise they only add confusion and uncertainty. Should I trust the code or the comment? (the code of course)

Then it also depends on the standards of the codebase, maybe there is a standard define alreay, which you should follow. Otherwise it does not matter at all, meanwhile you're consistent.


Useless comments:

class User {
  // Returns the name of this user
  getName() {
     ...
  }
}

------

const name = user.getName(); // Get the user's name

const sum = a+b; // Sum the two values together
Enter fullscreen mode Exit fullscreen mode

As you can see these comments are useless as f*. They offer no value at all, just adds noise. You would be surprised at the amount of comments I've seen over the years following this line.

Now let's see some useful comments

public ensureCurrentItemIsOnList() {
    // This code is needed because if, in the first load, there is no `this.item` it would not be shown in the selector
    // So if `this.item` doesn't exist in the list we receive, we just add it to make it appear on the selector
    // This way we can list 10 items initially without problems, otherwise we should list every single item, which is not feasable
    if (this.item && !this.items.some((it) => it.id == this.item.id)) {
        this.items.unshift(this.item);
    }
}
Enter fullscreen mode Exit fullscreen mode

I could go on for quite a bit on this topic, so I will stop here for now. Might write an article on this if I find the time...

Collapse
vulcanwm profile image
Medea Author

Nice!

Collapse
jancis38 profile image
jancis38

You read the code top to bottom.
Why would you put the comment below? Are you crazy?!

Collapse
vulcanwm profile image
Medea Author

So you know what the code above shows?

Collapse
cappe987 profile image
Casper

I think a lot of languages and developers follow the convention of putting comments before code. I think it makes more sense because if you go to read a large block of code you first want it explained (the "why's" of the code) before reading the code itself. You typically want something explained to you before you try to understand it, and top-to-bottom is the natural reading direction. For a large code block you might even miss it if it is at the end.

Collapse
lionelrowe profile image
lionel-rowe

Either to the right (if comment and code are both very short) or above. Never after — that's just confusing and inconsistent with how standards such as JSDoc, JavaDoc, PHPDoc etc. work. For example:

/**
 * Capitalizes the first letter of a string
 * @param {string} str
 * @returns {string}
 */
const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1)
Enter fullscreen mode Exit fullscreen mode
Collapse
vulcanwm profile image
Medea Author

ah okay!

Collapse
jeremyf profile image
Jeremy Friesen

I would look to Language Server Protocol (LSP) implementations to determine where you put your comments. For example, Ruby's LSP implementation (Solargraph) uses Yard documentation to provide "intellisense" support. Yard assumes the documentation is before the declaration of the class, module, or method.

If I were to put my comments after a method call, then Solargraph wouldn't find them (or worse would associate them with the next method) and I wouldn't get any benefit of tools that support LSP.

Collapse
vulcanwm profile image
Medea Author

oh damn

Collapse
oryaacov profile image
Or Yaacov • Edited on

I rarely use comments (only when mandatory) , because as my CTO always say "write English, not code" .

but when I do, I actually put above :)

Collapse
vulcanwm profile image
Medea Author

oh lmao

Collapse
aghost7 profile image
Jonathan Boudreau

From what I've seen in the Python community its usually done above the code in question. Its better to follow the community style if you want others to have an easier time reading your code.

Collapse
vulcanwm profile image
Medea Author

Ah okay!

Collapse
ainospring profile image
Aino Spring

I personally just write comments over sections of my code for example init window or load config because I often have the problem that I can‘t really navigate through my code.

Collapse
vulcanwm profile image
Medea Author

that's a great way of doing it!