Survey on Python comments

Well… yes. That’s right. They DON’T come from the code, they come from the design.

That is WHY they are explained in comments. That is what comments are for.

And that’s what I’m trying to explain here. You claimed that all my code comments could be generated from the executable code, but you haven’t given me any examples, and I have given you multiple counterexamples where you’re admitting that the comments could not have been generated from the code.

So I ask again: What is your tool achieving, and unless it’s completely new programmers who need assistance understanding the meaning of the code they’re looking at, who is the audience for the tool?

But you don’t explain the numbers, you explain what the function does or rather, what are each individual fields in your money list is. Essentially you are providing documentation of your data structure in the implementation details of it. It isn’t explained in the comments why dollars are 5000000 and the others are only 500, it also doesn’t state if there are any dependency between them. Is the fact that the other currencies are 500 dependent on the fact that dollars are 5000000? Are they incremented together or always independently? There are lot of information here that could be in the comments and are very useful, but isn’t.

I mean, I don’t disagree with you that comment generation systems have limitations. But they are actually quite useful. The comments here in this example where you basically say “this addition adds function name” can be generated by an algorithm that uses names in it’s input.
Here is a snippet from your project that I saw, I meant most of these comments here can be generated automatically. I don’t know if you actually wrote them, though. This is just a project on your front GitHub page.

def make_popup(lines):
		nonlocal popup
		lines = lines[:height - 5] # Truncate if we don't have enough screen space
		popup = curses.newwin(len(lines) + 2, width - 4, 2, 2)
		popup.erase()
		popup.border()
		for i, line in enumerate(lines):
			if not isinstance(line, tuple): line = (line,)
			popup.addstr(i + 1, 1, line[0][:width - 6], *line[1:])
		popup.refresh()
		curses.curs_set(0)
	nonautodeps = []
	while True:
		height, width = scr.getmaxyx() # Also used by make_popup()
		if height != lastheight:
			# Note that a resize event is sent through as a pseudo-key, so
			# this will trigger immediately, without waiting for the next
			# actual key.
			lastheight, lastpage = height, None
			scr.setscrreg(0, height - 1)
			perpage = min(height - 8, len(upgrades))
			scr.move(perpage + 2, 0)
			scr.clrtobot()
			print()
			if auto: print("Plus %d auto-installed packages." % auto)
			print("Select packages to upgrade, then Enter to apply.")
			print("Press ? for help, or Q to quit without making any changes")
		pagestart = pkg - pkg % perpage
		if pagestart != lastpage:
			lastpage = pagestart
			# Update (only if the page has changed)
			for i, d in enumerate(desc[pagestart : pagestart + perpage]):
				scr.addstr(i + 2, 0, fmt % ((actions[pagestart + i],) + tuple(d.values())))
			# Erase any spare space, including the mandatory blank at the end
			for i in range(i + 1, perpage + 1):
				# Is this the best way to clear a line??
				scr.move(i + 2, 0)
				scr.clrtoeol()
			scr.setscrreg(2, perpage + 4)

		scr.move((pkg % perpage) + 2, 1)
		key = scr.getkey()
		if popup:
			# Restricted key handling when a popup is open
			if key in "Aa" and nonautodeps:
				for i, p in enumerate(upgrades):
					if p in nonautodeps:
						toggle(i, "A")
			if key in "?QqIiAa":
				popup = None
				nonautodeps = []
				scr.touchwin()
				scr.refresh()
				curses.curs_set(2)
			continue

Yes, and? That’s exactly the purpose of code comments: to explain information that isn’t otherwise obvious, showing why it’s doing what it’s doing, explaining the purpose of the function. I think it’s quite obvious that, in the case of “add more dollars”, it will add 50 million of them. That part isn’t in the comment, because that number is self-explanatory (if it weren’t, it would be worth stating in the comment - for example, if it actually added 50 million cents, which is a common way to store funds).

But would your script have generated any of it, or are you asking for those comments to be created by a human? This is further proof that you cannot autogenerate comments.

Okay then. Strip the comments from that function, then feed it to your script, and tell me what it comes up with. It might get the truncation of lines one, but I’m rather more dubious about the others.

Honestly, yes, I have already said it, the comments about money that you have there can be generated, they are very trivial. They can be inferred from code itself. My point is that the current comment you have there basically doesn’t say anything interesting and combining the addition with the function name you get that comment. But the actual information that would be impossible to generate and would be useful for someone who reads this code without you is not there, such as the relationship between those currencies or if they are completely independent or why those are the numbers.

This information is basically a specification. It must be written by someone and not the algorithm. Or it must be provided in some way and then the text would be generated by the algorithm. Obviously an algorithm cannot just generate specifications out of thin air. I never claimed it could. I am also not trying to make a system that generates requirements based on the code.
You yourself provided an example with that JS snippet which is non-trivial and not everyone will be able to see what it actually does, while the comment generation system provides a proper description that explains what’s going on. This is basically the use case for my comment generation system.

I can’t analyse large projects yet, this is future work for my system. But I am telling you that it is technologically possible to do to generate comments like in this snippet.

Well, let me know when you can back your words with code and I’ll reevaluate. Until then, this has been nothing more than you bragging that this could in theory be possible, while also not actually having anything useful generated by your scripts. I personally don’t think it will EVER be possible to replace those comments, so if you disagree, make it happen.

I honestly don’t know why you are so skeptical and also where you saw bragging. My system is rudimentary at the current stage, which I always said from the start. As for the comments you are asking, ChatGPT can already make documentation similar to what you have, so I don’t need to prove anything. It is not exactly the same, but it is quite useful. I just asked it to generate line by line comment of that snippet and this what it did

def make_popup(lines):
    # Use the 'nonlocal' keyword to indicate that 'popup' refers to the outer scope variable
    nonlocal popup
    # Limit the number of lines to fit within the height of the screen minus 5
    lines = lines[:height - 5]
    # Create a new window for the popup
    popup = curses.newwin(len(lines) + 2, width - 4, 2, 2)
    popup.erase()
    popup.border()
    
    # Display each line of the popup
    for i, line in enumerate(lines):
        # Check if the line is a tuple, if not convert it to a tuple
        if not isinstance(line, tuple):
            line = (line,)
        # Add the formatted line to the popup window
        popup.addstr(i + 1, 1, line[0][:width - 6], *line[1:])
    
    # Refresh the popup window
    popup.refresh()
    # Hide the cursor
    curses.curs_set(0)

# List to store packages without automatic dependencies
nonautodeps = []

while True:
    # Get the height and width of the screen
    height, width = scr.getmaxyx()
    
    # Check if the height has changed
    if height != lastheight:
        # Update the lastheight and lastpage variables
        lastheight, lastpage = height, None
        # Set the scrolling region for the screen
        scr.setscrreg(0, height - 1)
        # Calculate the number of packages to display per page
        perpage = min(height - 8, len(upgrades))
        scr.move(perpage + 2, 0)
        scr.clrtobot()
        print()
        
        # Display information about auto-installed packages if applicable
        if auto:
            print("Plus %d auto-installed packages." % auto)
        print("Select packages to upgrade, then Enter to apply.")
        print("Press ? for help, or Q to quit without making any changes")

    # Calculate the starting index of the current page
    pagestart = pkg - pkg % perpage
    
    # Check if the page has changed
    if pagestart != lastpage:
        lastpage = pagestart

        # Display information about each package on the current page
        for i, d in enumerate(desc[pagestart : pagestart + perpage]):
            scr.addstr(i + 2, 0, fmt % ((actions[pagestart + i],) + tuple(d.values())))

        # Clear any remaining lines on the screen
        for i in range(i + 1, perpage + 1):
            scr.move(i + 2, 0)
            scr.clrtoeol()
        
        # Set the scrolling region for the screen
        scr.setscrreg(2, perpage + 4)

    # Move the cursor to the current package position on the screen
    scr.move((pkg % perpage) + 2, 1)
    
    # Get the key input from the user
    key = scr.getkey()
    
    # Check if there is an open popup
    if popup:
        # Handle specific keys when a popup is open
        if key in "Aa" and nonautodeps:
            # Toggle the selection of packages with non-automatic dependencies
            for i, p in enumerate(upgrades):
                if p in nonautodeps:
                    toggle(i, "A")
        if key in "?QqIiAa":
            # Close the popup and reset related variables
            popup = None
            nonautodeps = []
            scr.touchwin()
            scr.refresh()
            # Show the cursor
            curses.curs_set(2)
        continue

  • I am willing to believe that your tool and ChatGPT are cable of writing text that describes code in a useful way, especially for beginners.
  • I am not willing to believe that those text are ever useful as comments on the code. They might be useful for docstrings and as popup explanations next to code in IDEs
  • code comments are for information not present in the code. This can never be reliably inferred by tools (unless they get a lot more context than just the code), since that is computationally impossible.

Stop calling this “code comments” and I think both me and @Rosuav are not going to have anything against this.


… Did you actually read those comments? Or do you actually think the differences are completely irrelevant? In what world is documenting that nonlocal popup makes the variable popup non-local useful? Where is the note about the resize event being a pseduo-key?

In fact, this is a great example of why we are so skeptical: The comments by ChatGPT are largely redundant if you know the framework, and the extra contextual information that the human comments added are gone now.

1 Like

This is not even slightly similar. These comments are redundant with the code - which is to be expected, since they were generated from it - which causes additional cognitive load without adding any new information.

  • # Create a new window for the popup - that’s useful if you have no idea what curses.newwin() does, but otherwise, not much help. This is part of the category of “annotations useful if you’re trying to get your head around a codebase”, but they absolutely should NOT be saved with the code in this way - they should be a sidebar or something, to emphasize that they are derivative information and only valuable so long as you don’t change the code.
  • # Use the 'nonlocal' keyword to indicate that 'popup' refers to the outer scope variable - a lot of words to give no information whatsoever. Yes, it’s nonlocal. The comment doesn’t say anything about the significance of that outer scope or anything. All it tells you is what any Python programmer will be able to find out by looking up the docs (or, more likely, will already just know).
  • # Update the lastheight and lastpage variables - Utterly useless and serves no purpose even when accurate.

(edit: oops, sent it prematurely, will continue in a second post)

  • # Limit the number of lines to fit within the height of the screen minus 5 - this is the sort of comment that might be useful, but can very very easily become inaccurate. If the code is now changed to subtract 6, or 3, or any other number, the comment has become worse than useless. That’s why I deliberately DON’T repeat such trivial information in the comment. ChatGPT created a worse version of the existing comment, and it only managed that because this is one of the few places where I actually put a fairly obvious point into a comment. You’ll notice that most of the time, I don’t have these sorts of things.
  • Where’s any reference to the resize event and how it’s delivered? Nowhere, because that’s not shown in the code. Thus there’s no comment about it.
  • I mentioned a “mandatory blank” on the page. ChatGPT didn’t pick up on the + 1 in that range, because it didn’t understand the significance. That’s why I had a comment about it.
  • # Handle specific keys when a popup is open - wow, that’s ONE comment that it mostly got. I said # Restricted key handling when a popup is open because this is a cut-down set of handlers, so it’s more about restricting than about doing different and specific things, but I’ll call that one close enough.
  • # Close the popup and reset related variables - yes. I can see that it’s reseting a bunch of variables. You really don’t need to say that. MAYBE saying “Close the popup” would help to explain what popup = None does, but I honestly don’t think it’s all that significant.

So… one. Maybe two, if you’re pushing it. But a huge number where it spent a lot of words to tell us nothing, and a whole lot of completely missing comments.

For someone who has no idea what the code is doing, and wants some sidebar annotations, this MIGHT be of value. It’s not code comments, it’s code analysis. But it definitely should NOT be considered automation of code commenting, and has nothing whatsoever to do with either “code comments” as usually described, or docstrings.

Exactly. Couldn’t have put it better.

Is the intent to create “Code logic explanations”?

Comments are for whatever anyone wants. You seem to have a very narrow idea of the use of comments.

Comments can hold nearly anything. You can use them for

  • extra information that is not expressed/implied by the code,
  • but they can also contain documentation,
  • properties of the code like measures of complexity,
  • they can contain further code that either got deprecated or that is going to be used in some other circumstances,
  • they can contain opinion of the code, e.g. making fun of it.
  • they can contain history of the code, or references.

Also, if a human is able to write a comment, (I believe Church–Turing–Deutsch principle) a computer can do it too. All of the above can be done by a computer.

Also, even if the computation required to generate certain type of comment is completely mechanic, local, depending only on the piece of code, it is not without value. A computation takes time and energy. When this is significant, there is value in having the result pre-computed written in there as a note. The next person only needs to read it.

2 Likes

Yes, but there’s something common to all of these: They contain information not expressed in the code itself. That is what comments are for.

The exact nature of that information, as you say, can vary enormously. A lot of good comments explain the “why” of the code, as opposed to the “what”, but they can be pretty much anything. Nobody’s disputing that.

That’s what I’m disputing. Prove me wrong: get a computer to actually add information that isn’t part of the code itself.

I disagree with that, on the basis that such pre-computed analysis can easily get desynchronized with the code itself. When that happens, the comments become worse than useless. Any sort of analysis that is entirely generated from the code should be a sidebar, NOT part of the code and definitely not saved inside it.

I am sure you can think examples by yourself. The last bullet point is the first that crossed my mind; you can have a program that when it finds a function of even just an expression that it recognizes as a known one or similar enough, it add a comment that attributes it: “This is Cardano’s formula, discovered in the 16th century.”

Like everything. Not a reason for not using for as long as it lasts. Timestamps can be used to have an idea, for example. A team’s workflow is also part of preserving it. One can always misbehave.

Out of curiosity I asked ChatGPT:

Can you please add better code comments to the following Python code function:

import struct

def f(y):
    x2 = y * 0.5
    i = struct.unpack('<i', struct.pack('<f', y))[0]
    i = 0x5f3759df - ( i >> 1 )
    y = struct.unpack('<f', struct.pack('<i', i))[0]
    return y * ( 1.5 - ( x2 * y * y ) )

And it replied:

Certainly! Here’s an improved version of the Python code with more detailed comments:

import struct

def fast_inverse_sqrt(y):
    """
    Calculate the fast inverse square root using bit-level manipulation
    and Newton's method.

    Parameters:
    - y (float): The input floating-point number for which
                 the inverse square root is calculated.

    Returns:
    - float: The inverse square root of the input number.
    """

    # Step 1: Compute intermediate values
    x2 = y * 0.5

    # Step 2: Bit-level hacking to manipulate the floating-point representation
    i = struct.unpack('<i', struct.pack('<f', y))[0]  # Interpret the float bits as an integer
    i = 0x5f3759df - (i >> 1)  # Magic number manipulation to get an initial guess
    y = struct.unpack('<f', struct.pack('<i', i))[0]  # Interpret the integer bits as a float

    # Step 3: Refine the estimate using Newton's method
    result = y * (1.5 - (x2 * y * y))  # Only one iteration is often sufficient

    # Step 4: Return the inverse square root estimate
    return result

# Example usage:
# result = fast_inverse_sqrt(4.0)
# print(result)

Asking if it can explain the magic number it is certain that it can, but only gives:

The magic number itself comes from empirical optimization done in the past and is specific to the IEEE-754 floating-point representation. Its use is somewhat arbitrary and may not be immediately intuitive without proper documentation or background knowledge about the fast inverse square root algorithm.

(Not a very representative case because a lot of analysis / “training data” is available about this topic Fast inverse square root - Wikipedia )

1 Like

Really. So you’re saying that code comments can be answered just by Googling stuff you can find in the code, and therefore a computer could add them? Is that it?

Go look back at the examples already posted. When I say they contain information not in the code, I really truly mean it. They contain information that is not in the code in any way. Do you understand what this means? It means that, fundamentally, they cannot be generated from the code itself.

If you disagree, prove it, not by taking a reworking of a known and very short algorithm, but by getting a computer to add real comments to real code. It’s already been tried once in this thread, and the results were dismal.

Exactly. Not representative at all.

Just naming this function as ‘fast_inverse_sqrt’ is enough. Whatever comment you add in the code is redundant, and it is not going to teach you about the Fast inverse square root or 0x5f3759df. You either have enough knowledge about the domain in application, or you have to go and study these algorithms.

Take a look at the comments in the original code:

float q_rsqrt(float number)
{
  long i;
  float x2, y;
  const float threehalfs = 1.5F;

  x2 = number * 0.5F;
  y  = number;
  i  = * ( long * ) &y;                       // evil floating point bit level hacking
  i  = 0x5f3759df - ( i >> 1 );               // what the fuck?
  y  = * ( float * ) &i;
  y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
  // y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

  return y;
}

That’s how comments are used—short and descriptive.
In other words, don’t tell me twice and thrice what the code is doing.

If it is not written, then I am not saying it. Don’t fight men made out of straw that you yourself built.
What is written is an example only.

Not the only use for comments.

Moreover, code doesn’t exist in isolation. It is not true that any of those comments that you mean, cannot be generated from the code itself. Note that “from the code” does not mean “from the code alone”. You, a computer (again I belong to the CTD thesis faith), generated them. You used external information. A computer can do that. Software can google, can query databases that are not the code, but are about code, it can query a stochastic model that has been fitted with knowledge from people in the area of expertise relevant to the context in which the code will be used. The resulting comment is value added. Value, depends on who is reading, on where and how the software is used.

I pass. There is no value for me in it. You have made the choice of being obtuse, and will stay there until you choose not to. When that happens you will find lots of examples of your own.

My current example is not with Python and not a programming language. It is MathML with LaTeX in XML comments. In abstract there are lots of flaws with it, but in the context in which it lives (huge document, with a long history, with mistakes in the MathML, and that is in a process of transition that will take a while) it serves us.


Again, because comments can contain nearly anything, whatever we say they are for is not going to include all their uses.

2 Likes

Redundant \neq useless

Anything that you can deduce from some information is redundant and often less information. The deduction can be non-trivial, and having the conclusion explicitly written is of value. Compare with a collection of axioms in mathematics and theorems that follow from them. Every theorem is less ( \leq ) information than the axioms. Still often non-trivial to get to them and useful to have them explicitly.

2 Likes

Adding redundant information to the code as code comments is worse than useless. That information could instead be presented in a side bar. Adding the comments just risks it becoming out-of-date.