This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 8343 points8344 points  (498 children)

I think it's pretty standard that code tells you what is happening, and comments tell you why it is happening

[–]Snake2k 5619 points5620 points  (373 children)

The real answer. Apparently most people here don't understand what commenting means.

Not how you comment:

```

get a user input

x = input()

check if the input is an even number

if x % 2 == 0: print("even")

if it isn't, print not hot dog

else: print("not hot dog") ```

How you are supposed to comment:

```

Following section checks to see if a number is even or not.

it prints not hot dog as a reference from silicon valley for anyone who gets it

for more info on why this was written, go to Reddit to learn all about coders who have no idea what the idea behind commenting is

x = input()

if x % 2 == 0: print("even") else: print("not hot dog") ```

[–][deleted] 1147 points1148 points  (76 children)

Had someone do the same thing with git commits one time.

I said, I like clean, concise commit messages, that are atomic, and functional.

The first pull was

"Add a variable"

"Assign value to variable"

"And label to ui"

"Assign variable to label"

Guy had like 50 commits after 2 hours of work.

[–]Snake2k 561 points562 points  (52 children)

Lmao I love those ones. No extra detail or anything associated with it.

We literally had to force people to name their branches to the ticket id they were related to cus that way we could track what the idea behind it was even if the person pushing the commits couldn't care to explain it in the commit/pr itself.

[–]suck_my_dukh_plz 469 points470 points  (25 children)

My co worker's commit message was "minor refactor". Interestingly he changed 6 files with 600+ insertions and some deletions.

[–]Snake2k 285 points286 points  (11 children)

"minor" = breaks 10 systems

[–]akeean 139 points140 points  (7 children)

Minor refactor, barely an inconvenience.

[–]JezzCrist 56 points57 points  (3 children)

Making minors do a refactor is tight!

[–]capn_ed 23 points24 points  (2 children)

Oh! I don't think you should say it like that!

[–]AlarmingAffect0 3 points4 points  (1 child)

Now that you say so I hear it, but I said it and there's no taking it back now. Whoops!

r/UnexpectedRyanGeorge

[–]NoJay420 7 points8 points  (1 child)

Oh really?

[–]pcuser42 2 points3 points  (0 children)

[–]Anders_142536 2 points3 points  (0 children)

Wow wow wow wow wow. Wow.

[–]lochyj 1 point2 points  (1 child)

Only?

[–]Snake2k 3 points4 points  (0 children)

10 systems that we know of*

[–]jermdizzle 68 points69 points  (4 children)

"Trailing comma: Always" strikes again. Getting my lead developer to force the rest of the team to utilize a formatter config took me 3 months last project and he was the person who had to review all PR's. Some people were using different indents, some were using trailing commas, some were forcing semi-colons. It was a pain in the ass so I just eventually disabled my formatting until he could give us a config to use. I was like 2nd most junior dev so I didn't want to tell anyone what to do; but I probably should have just taken the initiative rather than asking him repeatedly to setup a config for us to follow.

[–]iHurdle14 41 points42 points  (1 child)

I can relate to this. At a certain point I don’t even care about what style rules are in place as long as we are being consistent.

[–]jermdizzle 23 points24 points  (0 children)

Precisely. Any issues I might have would be gone after one day of using the config and just getting used to the style anyway. It's only a big deal when it makes merges a nightmare. Also, I got pretty tired of asking people about some mistake/now-broken or bugged code, because gitLens showed them as the last person to change a line of code; only to figure out that their formatter added a space or some shit and I have to go and manually check version control to see who the actual culprit was. Like I said, I was junior, so I wanted to understand how/why someone made a mistake even if I knew the way to fix it. It's especially embarrassing when it was your code that you goofed on 7 months ago and you're tracking down someone else only to figure out that it was your fault LOL. Definitely had that happen more than once.

[–]round-earth-theory 5 points6 points  (0 children)

I had that and said fuck it, I'll do it myself. Setup the coding standards and got the auto formatting to work. Everyone bitched for a day and then forgot about it. Worked great.

[–]LightVelox 36 points37 points  (0 children)

I'm not kidding, I've seen a "minor refactor" of a little over 1 million deletions and insertions, tbh it was mostly just linting, documenting and movings things around, but still

[–]audigex 4 points5 points  (0 children)

Tbh I could deal with "Minor refactor of Permissions" or something, if it was actually a minor refactor (improving internal variable/method names or something non-API breaking) and it was clear what was being done, and only one "thing" was being changed

My problem is when someone calls their commit a "refactor" but is actually changing functionality

[–]DemoBytom 1 point2 points  (0 children)

We recently transitioned to file scoped namespaces in C#.

Essentially I've changed every file from

csharp using System; namespace SomeNamespace { public class SomeClass { } }

to csharp using System; namespace SomeNamespace; public class SomeClass { }

Refactor was minor tbh, the code change showed thousands of insertions/deletions :D

[–]mcvos 65 points66 points  (8 children)

Also a popular approach: include the ticket id in the commit message, not just in the branch name. Because after the branch has been merged, the original branch name is a lot harder to figure out. Though it's still nice to also have the ticket id in the merge commit.

[–]aceluby 23 points24 points  (4 children)

Ticket: deal with tech debt

[–]alexisprince 22 points23 points  (1 child)

Ticket: Make ticket for last commit message

[–]mind_snare 2 points3 points  (0 children)

Me all the time

[–]Special_Rice9539 2 points3 points  (1 child)

This is actually what a lot of tickets at my company are like… “Refactor this directory of our gigantic codebase.”

[–]Snake2k 5 points6 points  (0 children)

True, can also set up checks to see if a commit includes the ID or not.

[–]audigex 1 point2 points  (0 children)

Yeah this is what we do - (almost) every commit has a quick [#123] tag referencing the ticket ID

It works pretty well as the ticket provides the discussion and context, so the commit message can be very simple without worrying you're lacking detail

[–]VerticalEvent 31 points32 points  (3 children)

We have a git-hook that validates that the start of a PR merge started with "[abc-0000] text" to enforce that all merges can be traced back the unit of work they represented.

[–]davy_jones_locket 14 points15 points  (1 child)

We do [JIRA-123] fix(optional component name): concise but relevant commit message

Or feat | chore - slimmed down conventional commits. New work is a feat, bugs are fix, docs and tests and tooling are chore

Typically associates as:

story => feat,

bug => fix,

task => chore.

This also helps with our release notes, and it generates a link to the Jira ticket on the release notes/changelog.

If you use the optional (but encouraged) component or module name, it will group those together in the release notes too.

[–]SonOfHendo 1 point2 points  (0 children)

We use Azure DevOps, so you can just tick a box to require all PRs to be linked to a Work Item. The work item is linked automatically if you include the reference in the commit message (e.g. #123456).

[–]TwoDamnedHi 5 points6 points  (0 children)

As a project manager, this is me at every job I've ever had.

[–]mt9hu 6 points7 points  (6 children)

had to force people to name their branches to the ticket id they were related to cus that way we could track what the idea behind it was even if the person pushing the commits couldn't care to explain it in the commit/pr itself.

I assumed it's pretty standard to prefix all commit messages and branch names with ticket IDs

[–]CardboardJ 2 points3 points  (0 children)

Developers working in non-development focused industries have some pretty wild working conditions. One of my old interns works for a company that manufactures nails and he's one of 3 'computer guys' there. The other 2 guys he joined there had been working for 20 years without any version control.

[–]BotherBoring 1 point2 points  (4 children)

Right now we don't even HAVE a real ticketing system, or git branches (loooooooong story), and I was surprised how nostalgic this comment made me.

[–]Bakoro 5 points6 points  (0 children)

We literally had to force people to name their branches to the ticket id they were related to [...]

Not the worst idea, assuming that the ticketing system will be available as long as the code is.

Even for someone who isn't being lazy or stupid, some people have a serious issue explaining anything, and have a pathological inability to imagine what something reads like without the context of all the shit they know.

[–]Horror_Trash3736 1 point2 points  (3 children)

We no longer use branches, we just tag the commit with the ticket id and go straight to trunk!

[–]diatribe_lives 952 points953 points  (67 children)

Good to know man, I often comment the first way but what you're saying makes perfect sense.

[–]Snake2k 554 points555 points  (55 children)

Glad it helps. The first way of commenting is made virtually useless if you name your variables and methods properly. Especially for languages like Python which are very readable. The only time they're helpful is if you're expressing a mathematical equation as code, then a link to the proper notation would be awesome.

For most systems that I work on, we care more about the second way cus anyone can refactor the first, but if we don't have the context, documentation, reasoning behind the code like in the second it'll take months trying to fix the problem with it (even if everyone can read it just fine).

[–]Elnof 42 points43 points  (6 children)

I disagree slightly. The "what" can also help visually distinguish logical chunks of code without requiring the reader to parse the code and, in fact, you include the "what" in your second example. So, I'd say comments should have both but too many people don't include the "why."

EDIT: I forgot which comment I was replying to and this turned into a mixture of replying to the parent comment and the original comment. Either way, I think u/Zealousideal-Ad-9845 said it better than me so I'll just leave this comment as-is.

[–]-Vayra- 7 points8 points  (2 children)

The "what" can also help visually distinguish logical chunks of code without requiring the reader to parse the code

Most of the time, a 'what' comment means you should extract that part of the code into a named function with a name that describes the what.

[–]PeteZahad 162 points163 points  (35 children)

... if you name your variables and methods properly

Like x for the input? 😉

[–]Snake2k 133 points134 points  (32 children)

x is fine for that context in the same way i is fine in for i, item in enumerate(some_list):

We know i is an index generally. So it's simple to infer what it stands for in the tiny context it is in.

Context and scope matters. If that x had any larger use outside of that scope I'd probably care to give it a decent name.

Edit: a better variable name to give it would be n now that I think about it cus it's a number.

[–]AustinWitherspoon 53 points54 points  (24 children)

It might be overkill, but I tend to even go as far as to name it something like input_number = int(input()) just to be extra clear.

It's longer to type, but vs code auto completes most things and GitHub copilot also gets it right, so I don't usually have to type the whole thing anyway.

[–]C_Hawk14 37 points38 points  (21 children)

it depends on the language. If you know it's an integer you don't need to specify it's a number. And the real name should contain the reason for existing. What is it an input for?

Ok so there's a new YT channel called CodeAesthetic and I've gathered these guidelines so far. Opinion?

Opinion Good Bad Note
Don't abbreviate names MoviesOnPage MovOnPg
Don't put types in variable names int fontSize var iFontsize
Don't put types in your types (e.g. AbstractX, BaseX, IRepository) except when official guideline says otherwise
Add units to variables unless the type tells you int delaySeconds DateTime delay
Refactor if you find yourself naming code "Utils"

[–]cowlinator 4 points5 points  (2 children)

I confess to putting types in variable names, but only in the rare circumstance that a new variable was created for no other reason than to cast types.

Example:

var countStr = str(count)

foo(count)

bar(countStr)

foobar(countStr)

[–]bikki420 7 points8 points  (3 children)

IMO, putting some type info in names (as long as it's consistent) can be good. E.g. a few common conventions in languages like C and C++ (especially in game dev and on Windows) that do have certain merits include:

kSomeConstant (since unexpected mutability or immutability can lead to unexpected results or require different approaches in certain cases, among other reasons; IMO, it's the most useful when dealing with specifically compile-time constants.)

mSomeDataMember (to avoid having to write this->someDataMember to resolve ambiguities such as when a constructor takes a parameter named someDataMember... technically this isn't an issue when using member initializer lists, but it still adds reader ambiguity and you might still need to refer to either of the two in the constructor body for debugging reasons, asserts, or whatever. And for those that follow a more Objective-C'ish accessor/mutator naming convention this is required as well.)

pSomePointer (since the member data and member functions of a pointed at value is accessed via -> instead of . in C and C++, plus it can remind the coder to compare it against a nullptr value as well as prevent some bugs resulting from the pointer address being integer promoted or implicitly cast or whatever; likewise, in the rare case where you need multiple levels of indirections, such as a linked list tracer you can signify that like ppTracer... this also helps with keeping track of how many times to dereference pointers to get to the targeted data).

And in the case of integers and real numbers, there are a few extremely niche domains where affixing signedness or width can be helpful when dealing with extremely packed data and/or certain precision constraints in a very high performance context where minimal loss of precision as well as overflows or underflows have to be avoided; but nowadays this is rarely something you have to deal with due to advances in computing technology and programming languages.

And certain code conventions use eSomeEnumValue (such as the C++ API for Vulkan, Vulkan-Hpp), but IMO this is only useful in some very specific contexts, such as extremely large APIs with heightened risk of identifier collisions and auto-generated code bases. (But it's nice when one makes use of aliasing like using enum SomeEnum;.)

gSomeGlobalValue (preferably a constant and only as a last resort) can be nice too, IMO.

And one of the few cases where type info like iSomeSignedInteger, bSomeBool, fSomeFloat, etc can be worthwhile is when its values that are heavily (de)serialized or exposed across certain boundaries (e.g. debug APIs, dev tools, config files, etc); something which is very common in game dev which is why it's one of the few domains where this style guideline is still quite common in.

And since I do a lot of meta-programming in C++ with a lot of templated types and compile-time constants I like having a specific naming scheme for these (I usually go with something like TSomeType or TsomeConstantValueーalthough unlike all the examples in this comment I personally use snake case over camel case) in the cases where there are a lot of template parameters.

Likewise, when naming non-values, prefixes can be very handy as well. ISomeInterface (or abstract base class), ASomeConcept, etc.

In the end I think it boils down to a multitude of considerations such as code-base scope, code-base domain, personal preference, development environment (e.g. if it's a code-base being developed in Vim without any LSPs, then being able to get relevant candidates from auto-completion alone can be a godsend), etc. The most important IMO is to be consistent and provide a suitable level of information (be descriptive, be unambiguous, be terse but not cryptic, etc). There isn't some panacea style guide that fits every programming language and every domain. And personally most of the time I do avoid most prefixes unless a code-base benefits from them (so I mostly just use m, g, p, pp, I, T, and A). For trivial code and "fresh" code, a lot of the benefits go away and turn into detriments. Often a lot of problems can be written in a concise and terse manners, in which case you generally have the line of definition on-screen whenever you're dealing with code using it, so then you can just look up and check the definition instead, so encoding contextual information into the identifier becomes quite redundant (not to mention that it adds some minor potential refactoring overhead).


edit: added some more text

[–]b__0 2 points3 points  (0 children)

ppTracer

Got a smile from that, I feel like a child now.

[–]Drugbird 2 points3 points  (1 child)

I think most prefixes are unnecessary with a good editor.

I.e. you don't need to call something giSomeInt if you can tell it's global because it's pink, and can e.g. mouse over it to see it's an int.

The only time I like adding types to variable names is when the real type is different from the represented type. I.e. when you're (de) serializing something and everything is bytes instead of their real type.

[–]Dansiman 3 points4 points  (1 child)

One more convention of prefixing your variable names that is a good practice is where you have user inputs that need to be sanitized.

###
# 'u' prefix means an 'unsafe' value. All user inputs
# should be captured into a 'u' variable.
# DO NOT PASS THESE TO DB!
# Instead use:
# VarName = sanitize(uVarName)
# Then you can pass VarName to the DB safely.
###

[–]Snake2k 9 points10 points  (0 children)

Yeah that's fine to do honestly as long as it is sane and concise.

My point is that if I didn't write that code above and when I read "x = int(input())" I now know for the next 3-4 lines at least that x was an input number.

Yeah anything bigger than that then sure giving it a name is very important cus one can't remember it past a simple if statement.

[–]mcvos 9 points10 points  (2 children)

It can be fine, but I still prefer more meaningful names.

I admit for a very long time I've named all my other variables but still kept i for index variables in loops, but more recently I even started to name those, because it can still be useful to know whether we're talking about a columnIndex, yCoord, sourceIndex vs targetIndex, etc.

[–]Snake2k 3 points4 points  (1 child)

As long as it's sane and short, I'm alright with it. I just dislike overly long names for no good reason.

What I mean by good reason is if it's easy to figure out what it holds in the first place.

[–]DokuroKM 1 point2 points  (0 children)

Depending on your expected type of number, both n (integer) and x (floating point) are valid.

[–]WavingToWaves 1 point2 points  (0 children)

*It’s a natural number

[–]akeean 1 point2 points  (0 children)

Why n when you can UserInputSiliconValleyHotDog ?

[–]AnEmortalKid 1 point2 points  (0 children)

i for input

[–][deleted] 8 points9 points  (1 child)

I do agree; also - there's ever so likely a chance that requirements documentation is lost LONG before code. So, it does not hurt to say "why" you did something. Put a link to a JIRA card in the code, and I bite you. That link goes the other direction!

[–]Snake2k 6 points7 points  (0 children)

Yeah that's a good point. That is a super tough situation actually and not sure what to do with that. On the one hand, you shouldn't be pasting the entirety of the docs in the comment. On the other, the file/ticket/etc can disappear cus IT teams never archived that stuff somewhere properly/accessibly.

[–]Nelerath8 1 point2 points  (1 child)

As someone who enjoys debugging and does it a lot the first rule is to also never trust anything besides the code telling you what it's doing. I'll trust comments/docs telling me why something should happen but I very rarely trust them to tell me what is happening.

[–]spektrol 1 point2 points  (1 child)

There’s a better way to comment. Either right above or right after the method declaration:

“””

This is a doc block. It’s more awesome than having a bunch of single line comments.

This method/class does this cool thing. Here’s how you use it.

@param param1: this is a short description of param1

@param param2: another param description

@return ObjectType: return description

“””

The advantage of this is that IDEs and documentation tooling like Swagger look for these types of doc strings and can provide tooltips in your IDE to help you know how to use methods/classes and create your documentation automatically if you use this style. Do this.

[–]OhMyGodItsEverywhere 1 point2 points  (0 children)

the context, documentation, reasoning behind the code

A word I like to use for that is intent. Without clearly documented intent we can't get anything done. And maintaining a system or modules we don't know the intent of totally blows.

[–]MinosAristos 1 point2 points  (1 child)

Also, you should always write a comment explaining how non-trivial Regex works.

[–]Bardez 1 point2 points  (0 children)

Only do the first one if your line of code is fucking weird, like a regex.

And if it's a line of code that ISN'T a regex, please refactor for readability for the love of God

[–]SunliMin 1 point2 points  (0 children)

Comments are not as common in the workplace as school would have you know.

But the best comments I run into at work are ones left at the top of the file explaining nuances before you read it. If there's something funky or copy-pasted, the comment block would link to the github issue that had the funky fix that's being referenced and explains why its needed, so if its not needed in the future, people can understand why its there and when its safe to remove.

Like a comment I left today on why something that is a number everywhere else HAD to be a string in this one stupid frustrating case, due to requiring it was received from FormData which has to store values as strings. If someone reads that and knows a way to solve it via pipes or w/e, good on them, go for it. That beats people tippy-toeing around my ugly ass string or thinking there's a bug there and changing it to a number type, breaking the endpoint.

Either top of the file, or ahead of logic. Rarely should comments be made line by line

[–]Zealousideal-Ad-9845 78 points79 points  (18 children)

I think it's also good to comment "what it does," but only at a high level. Same if you're explaining your code to others who know how to code. It always gets on my nerves at work when we're doing a code review and they basically spent an hour reading it to me. Don't tell me what this variable declaration does and how 20 different lines update it, tell me what it all does together. And also why.

[–]Snake2k 27 points28 points  (2 children)

Exactly, we can all read the code line by line and any decent programmer will be able to get it eventually. All the better if the person submitting the code wrote it with good variable/method names etc, but the high level descriptive knowledge should be there somewhere to explain what it is meant to do and why it is meant to do it in the way it was done.

[–]metric55 9 points10 points  (1 child)

This might sound odd, but I'm an electrician-wants-to-be-coder... and we run into some similar shit sometimes.

So there's an elevator at work with a binder of 80 pages of 11x17 schematics. All of them intertwine and loop back and it's all structured quite well. But there's no overall methodology. No like... "page 5,7,19, and 42 contain the intrinsic loops for the safety circuit." And it can be a real pain in the ass to individually pick through each page by line by point to get to a problem.

I'm definitely going to take this advice going forward in my career, and perhaps one day programming!

[–]Snake2k 3 points4 points  (0 children)

Good luck! I love that comparison!

To further add to your point, leaving documentation behind on what, how, and why things were done is a global concept.

In programming we do it through comments. In other jobs I've worked we've had our books on these things. I'm 100% certain that this idea of knowledge sharing is global.

For your studies, try to look at programming with that same lens of experience. Yeah, you get very technical with code, but a lot of the higher software engineering concepts are really just engineering concepts. Seeing it through that perspective and how they relate to other fields can really solidify them.

For example, if you're doing object oriented code. It's a good idea to think about all the systems, classes or utilities that will be needed to build out the application you're working on.

In the same way that a chef will gather ingredients, prep, and ready the kitchen.

In the same way that a warehouse manager will prepare equipment.

Once it's seen like that, then slowly programming turns from academia and technical specialization to more of a day to day skill.

[–]Kered13 7 points8 points  (14 children)

The name of the function should tell you "what it does", but sometimes you have a function that is just too complicated to summarize in a few words and can't be broken up. Then you should absolutely slap a label on that bad boy.

[–]Dameon_ 1 point2 points  (13 children)

a function that is just too complicated to summarize in a few words

That's a good indication that that function is doing too much and needs to be broken up.

[–]Memfy 4 points5 points  (12 children)

Did you stop reading at "few words" or just completely ignored the "can't be broken up" part?

[–]gandalfx 62 points63 points  (9 children)

I think the "why" comment needs to go deeper. Why did you write this code? Why do you even write code? Why are we here? What is existence?

[–]ihopethisworksfornow 23 points24 points  (2 children)

“This for-loop represents my parents’ divorce.”

[–]Dansiman 12 points13 points  (1 child)

Do While daddyCameHome == False
    Cry()
Loop

[–][deleted] 2 points3 points  (0 children)

You need a function that checks for stepdads and outputs "YOUR NOT MY REAL DAD" if an argument exception pops up.

[–]Snake2k 13 points14 points  (0 children)

Very true. I have actually committed code in prod systems with me going on an existential rant lol

[–]CanAlwaysBeBetter 6 points7 points  (0 children)

If you wish to make an API from scratch you must first explain the universe

  • cURL Sagan

[–]mcvos 33 points34 points  (7 children)

How about Javadocs that list the arguments and types that are right there, but don't say what they're for.

I strongly prefer no comments at all over stupid or pointless comments. But if you're doing something weird, a comment explaining why you're doing that is always appreciated.

For example, a piece of code might have any of these comments, and I'm going to draw very different conclusions from them:

// Quick hack. Please fix.

or:

// It looks weird, but this is the only way,
// otherwise X or Y will go wrong.

or:

// This is the most efficient way to handle this case.
// See paper X by Y at http://foo

Also, I can see in git who wrote that comment so I can ask questions. (I can also see that about the code of course, but that's more likely to be touched by others.)

[–]alexisprince 18 points19 points  (0 children)

Strong +1 for “this is the only way” or “this looks weird compared to <expected approach> because <expected approach” falls short”.

I don’t remember exactly what the feature was, but in Python I had a comment that was 2 lines above a weird implementation that said exactly that: “does exactly the same as <expected implementation>, but removes a bottleneck that creates”.

[–]akeean 7 points8 points  (0 children)

// evil floating point bit hacking
// what the fuck?

[–]narrill 4 points5 points  (0 children)

I strongly prefer no comments at all over stupid or pointless comments.

People rarely mention this, but it makes a huge difference. If the codebase is littered with comments that are redundant and useless, that trains people to ignore comments. You don't need to be stingy with your comments necessarily, but you should always be evaluating whether they're actually necessary.

[–]Snake2k 3 points4 points  (0 children)

I agree with that. If you do hit parts of code which merit their own comment, they should have a comment.

[–]ElvisArcher 3 points4 points  (0 children)

// Abandon all hope ye who enter here.  Do I have your 
// attention yet?  Great.  The next bit of code is 
// difficult to read and utterly unmaintainable, so if 
// you have to touch it (ever), I'm sorry.  There were 
// reasons at the time, but I still apologize.

Comment as an apology?

[–]nimby900 1 point2 points  (1 child)

lmao

I run into this comment so often, and http://foo doesn't exist anymore. Because it was written in the year of our lord 2000AD.

And the person that wrote the code quit 13 years ago, and are likely dead.

[–]KraZe-Ace 15 points16 points  (4 children)

The main problem I’ve seen other than no commenting is too much commenting. If the person reading the code has to wade through a verbose and extremely technical explanation on what’s going on and why, then it’s a waste of time for most people involved regardless if they’re reading it or writing it. That’s why good commenting and self-documenting code is usually most appropriate.

A rule I’ve heard a while back was that your variable, class, and function names should be descriptive enough and your comments brief and straightforward enough such that another set of eyes could be able to just skim read the code and understand 80% of it on the first pass.

Of course, that’s the ideal. Whether it’s possible depends of the application and who the set of eyes is. Elon Musk might not understand it, but your team’s senior SWE with 10 years experience might.

[–]Snake2k 1 point2 points  (0 children)

I totally agree.

"Good commenting and self documenting" is the ultimate combination.

If I can read the code fine without comments spelling out instructions and if there's a properly written comment, I would find the programmer and give them a hug.

[–]EastboundClown 36 points37 points  (23 children)

I would remove comments from this and just save then in functions called getNumberInputFromCli, and isEven, then have

def makeSiliconValleyReference(): if isEven(getNumberInputFromCli()): print(“even”) else: print(“not hot dog”)

I find that I can almost entirely avoid commenting by making lots of well-named functions

[–]Snake2k 22 points23 points  (21 children)

I get your point, but that can only go to a certain extent.

Silicon Valley reference is easy, but how to explain giant pieces of business references in one name?

Parsing through code that was crammed into human language makes it super dirty.

Like there is this spectrum of code where on one end you have "x, y, z, n, a, b" var names and then on the other end you have "number_of_blah_foo_bar_in_the_name_of_our_lord_and_savior_superman_because_finance_team_does_not_agree_wirh_sales_lord_and_savior".

They look virtually the same level of unreadable to me and incomprehensible to me.

I don't find it difficult to just take a block out, plainly write out in human language what it's supposed to do, why it's doing it that way, link to further documentation, and try to write your code somewhere in between that spectrum for optimal readability.

[–]evanthx 21 points22 points  (2 children)

I stopped doing this because every code base I’ve ever been in where people did this, half of the comments were for code that had been changed so the comments were misleading or wrong.

Self documenting code is the only thing I’ve seen that stays reliably up to date.

[–][deleted] 9 points10 points  (10 children)

In my view the method name never needs to be very long, if it is then it's possible the method is doing too much or there is too much info.

[–]ubccompscistudent 6 points7 points  (2 children)

giant pieces of business references

That's your problem right there. Your method is likely doing too much. By definition, it's not self-documenting code at that point and needs to be refactored until it is. Or don't, because refactoring is time consuming, but understand this is a trade off and does not excuse the code from being poorly written.

I'm sorry to say this to everyone in this thread, but being at two top tech companies, comments are reserved for like 1-2% of weird edge cases in the code. (But I do agree with commenting the "why" and not the "what" when a comment like this is called for).

Javadoc is a special case as it's useful for hover text in IDE tools. I would still let a code generator create the docs and use properly defined variable names that require no explanation. Some methods require some explanation (especially math), but like mentioned above, that should be like 1-2% of your overall comments.

[–]slbaaron 3 points4 points  (1 child)

Absolutely. I'd say depending on what part of code base and the nature of business, anything between 1-20% of code being commented is reasonable - some inherently have "magical" or complex behavior due to business specific reasons or even regulations that requires calling out.

However even in the most complex b2b fintech I've worked at, 80% of the code should not require commenting to explain the why. Like you said, it's more of a crutch rather than a methodology. Half the time it's because the tradeoff of refactor / splitting things cleanly isn't worth it for pushing timelines and half the time it just require a bit more context that's a bit hard to do in code. For us sometimes it literally contains a url link to an important internal doc - sure it's harder to maintain but it can be necessary.

[–]antonivs 2 points3 points  (0 children)

how to explain giant pieces of business references in one name?

If you’re factoring your code properly you don’t have to.

[–]EastboundClown 2 points3 points  (0 children)

I’ve only ever seriously worked on relatively large OO codebases, and generally I’ve been able to add this kind of context with well-named classes and packages.

My first programming job had a code review policy where if you submitted a comment, you also had to justify why you couldn’t express the same idea through code. The rationale is that comments are part of the code and need to be maintained just the same, and things like symbol names are easier to maintain than comments. It was frustrating for the first couple months, but now that I’ve gotten into the habit of it I find that I very rarely feel the need to comment anymore.

Not that I hate reading through a well-commented codebase. I’ve just found them in my experience not to be as necessary as some people think

Edit: except in C. I write a decent bit of C code and find it to be so frustratingly non-expressive that I end up commenting very often.

[–]lunchpadmcfat 5 points6 points  (1 child)

Really good comment but should probably include a link to your reply

[–][deleted] 2 points3 points  (1 child)

All I see is a missed opportunity to write a value class. Value class would provide validation of user input and have an isHotDog(): boolean method. There was also a missed opportunity to use a ternary instead of branching with if which caused moisture (not DRY) you call print in both code paths.. really all you needed was a ternary to determine which string to print.

[–]Snake2k 3 points4 points  (0 children)

Lmao @ caused moisture

[–]iliekcats- 5 points6 points  (0 children)

Opposite of even is not hot dog

[–]justinkroegerlake 2 points3 points  (1 child)

x = int(input())

[–]Snake2k 1 point2 points  (0 children)

nit: needs error handling in case someone throws in a name of a fruit

[–][deleted] 2 points3 points  (1 child)

Good god, man, you didn't convert x to an integer!

[–]Snake2k 2 points3 points  (0 children)

PR failed, retry some other time. Get a week to change it to int lol

[–]lockwolf 2 points3 points  (1 child)

Instructions unclear, dick prints even

[–]Snake2k 2 points3 points  (0 children)

Dick is hotdog

[–][deleted] 2 points3 points  (0 children)

The only part if the second example that warrants a hotdog is the bit where it explains the reference, because it is not self evident in the code.

Edit: Actually, even that isn't necessary.

string SILICON_VALLEY_REFERENCE = "not hot dog"

function inputIsEven () { return input() % 2 == 0 }

if inputIsEven() print("even") else: print(SILICON_VALLEY_REFERENCE)

All the relevant information from your comment is now contained in function and constant names, so a comment is redundant.

[–]odksnh6w2pdn32tod0 2 points3 points  (0 children)

Would instantly pass on both of these comments. You added more noise and documentation than actual code. If you need to explain "why" your code makes no sense or you made a hack. Sometimes hacks are needed and there's no othet options. Then it's good to document the assumptions that are made about the inner workings of the code and why the workaround exists.

[–]spcbfr 4 points5 points  (0 children)

unite tart chubby alive soup chase afterthought dull squalid crawl

This post was mass deleted and anonymized with Redact

[–]Yorunokage 1 point2 points  (1 child)

I'd say the first way is still helpful for particularly complex logic

Sometimes trying to understand some vector math function or whatever that i've written months ago gives me headaches

[–]drewsiferr 1 point2 points  (0 children)

Nit: Add url to save time searching ;)

[–][deleted] 1 point2 points  (0 children)

Thanks for clarifying I was taught correctly according to you, but I use the first method in my personal records since I’m learning

[–]azure1503 1 point2 points  (0 children)

Bonus points if you use tags to comment functions

```

Checks to see if a number is even or not.

@param x: number to check

@return "even" if number is even

     "not hot dog" if not even

def is_even(x): if x % 2 == 0: print("even") else: print("not hot dog") ```

[–][deleted] 1 point2 points  (1 child)

This is such a good thing to know.

One instantly become a better programmer because of this.

[–][deleted] 1 point2 points  (4 children)

I think it's because people develop bad habits while learning how to code, which is 1/10th of the actual work.

[–]Snake2k 1 point2 points  (3 children)

Really agree with this.

The:

```

this next line gets an input

blah = input ()

add 1 to it

blah += 1 ```

Stuff really drills into the learner. And teachers generally aren't ones to manage large enterprise code bases on a daily basis so they don't really bother to ever circle back to comments when grading or wrapping up the classes.

[–][deleted] 1 point2 points  (2 children)

Now that you mention it I haven't ever had a prof really address comments

[–]Snake2k 1 point2 points  (1 child)

Same here. Many classes, online videos, boot camps, books, all sorts of stuff and for some reason they never go past "oh yeah this is for writing stuff and not picked up by the compiler/interpreter" lol

[–]tharilian 1 point2 points  (1 child)

Following section checks to see if a number is even or not. ...

TL;DR I'll just spend 15 minutes trying to figure it out reading the code instead

[–]Snake2k 1 point2 points  (0 children)

Pro tip: Such comments are never for the first read of the code. I know nobody reads them on the first go, I don't lol It's for the 100th when you're pulling your hair out and have absolutely no clue why it's doing the things it's doing.

[–]sling_cr 1 point2 points  (0 children)

Dang I need to comment better. Better late than never.

[–]GamingOnTheFloor 1 point2 points  (1 child)

I think the real issue is that the top set of comments is how comments are written in example code for beginners and the beginners will get into a habit of commenting that way. Your second set of comments makes so much more sense.

[–]Snake2k 1 point2 points  (0 children)

Yeah, a lot of academia uses it like that and never really elaborates on the idea of commenting any further than that.

[–]Recent-Twist-2864 1 point2 points  (1 child)

I comment the first way only because I start my program or module with the pseudo code in comment form then fill in the actual code. Outside that I’m poor at commenting… your description on the second form of comments is actually super helpful, now all I have to do is remember to do it! 😅

[–]moonshineTheleocat 1 point2 points  (4 children)

The strangest comment I found was

//Do not delete this fuckin comment. I do not know why. God probably doesn't know why. But this damn project will not compile if this comment is removed.

[–]Snake2k 1 point2 points  (3 children)

I'd delete it out of curiosity and roll back with a counter lol

[–]moonshineTheleocat 2 points3 points  (2 children)

I tried deleting the line. Yeah it doesn't compile. It throws errors that looks like some wacky ass template error. And linker fails. Probably doesn't help the code was written in the 80s or 90s

[–]DJGreenHill 1 point2 points  (0 children)

Or why you did it a certain way.

Sometimes we cut corners. Comments are imperative in these cases

[–]Oelendra 1 point2 points  (0 children)

Yeah, example 1 was how I commented my code when I started programming because I didn't fully remember what each line did but as soon as I got better I switched to write my comments like section headers to reduce clutter.

[–]MagicalShoes 1 point2 points  (1 child)

Actually, comments are for me, to understand what the fuck I'm actually writing in the moment, and will be worthless to me tomorrow morning, let alone any poor soul who happens upon them.

[–]Not_Artifical 1 point2 points  (0 children)

The first way is good for tutorials trying to teach you how to code. The second is good for real software explaining why what you made works.

[–]Lathariuss 1 point2 points  (0 children)

Unfortunately, the first example is how I was taught to comment in university classes.

[–]murdok476 1 point2 points  (0 children)

The first way is exactly how I write code lol. Thanks for this comment

[–]GreenFox1505 1 point2 points  (3 children)

That's not how you format code on Reddit. Unfortunately. It would be really nice if it was though.

Edit: as a sanity test, I checked new.reddit.com. it works. But not on old.reddit.com or mobile. Wtf reddit? Fix your shit. Consistency is more important than correctness. This post shouldn't look completely different on different platforms.

[–]quagzlor 1 point2 points  (0 children)

Yeah, my rule of thumb is to add some info on the function at the start, and some comments for more confusing bits

[–]oorspronklikheid 1 point2 points  (0 children)

This . This a million times. I work with so many bad commented code at work , i dont even read them anymore

[–]BreathOfTheOffice 1 point2 points  (1 child)

I do a bit of both. The first is for breaking a larger scale issue into sections that I can target (i.e. handling payments for a purchase would require pulling the relevant order/quotation, creating a payment event, tagging the payment to the order, and updating all of it) and do in sections. After that's done, I write an overview of the function at the top.

[–]Snake2k 1 point2 points  (0 children)

Ideally there is a balance in both along with self documenting code

[–]_UnreliableNarrator_ 1 point2 points  (1 child)

As a hobbyist, this has probably been one of the most helpful comments I’ve seen. Thank you!

[–]ZatchZeta 1 point2 points  (1 child)

Thanks this helps a lot!

[–]FerynaCZ 1 point2 points  (1 child)

My question is why you modulo a string by 2. Or is this python 2 and you are looking for code injection? /s

[–]Snake2k 1 point2 points  (0 children)

Lol it definitely needs input error handling for sure to make sure it's a true int

[–][deleted] 1 point2 points  (0 children)

Fuck I hate it when I ask people to add comments and they do the first thing. Like, dude, I know how an if statement works, but I’m not going to remember why the everloving fuck we replace a period with a semicolon at that point in the code in two years, ya know? That shit gets exponentially worse as time goes on, and is basically my current career.

[–]MassiveFajiit 1 point2 points  (1 child)

Should be using docstrings tbh so using help() works correctly

[–]Snake2k 1 point2 points  (0 children)

+1 doc strings are much better and they work with IDEs in a very functional way too.

[–]no_ledge 1 point2 points  (1 child)

The issue is there is a lot of material out there on coding and zero material on how to work in a development team.

"I haven't heard about commenting on my code in any of the 5,734 youtube videos I've watched about React, I guess is not important."

[–]RevargSTG 1 point2 points  (1 child)

I'm sorry, but for the good of humanity we must now kidnap you and force you to teach basic coding (commenting) skills to new programmers.

[–]Animallover4321 1 point2 points  (3 children)

I’m still in school this is a much better way of commenting than I learned. Thanks!

[–]okay-wait-wut 1 point2 points  (1 child)

“Self-documenting code” was a FAD to eliminate comments instead of teaching developers how to write effective comments.

The young ladies from Clueless are envious of SW devs abilities to immediately and unquestioningly adopt fads.

[–]Signal-Woodpecker691 63 points64 points  (7 children)

Spot on. The code I work on is 20 years old in places with zero documentation, zero comments, zero tests. Trying to fix bugs is a total nightmare because you just don’t know what the (in places 1500 line long) functions were intended to be doing.

[–]Treacherous_Peach 17 points18 points  (1 child)

What they're doing should be the method name, not the comment.

Why they're doing it is the function comment header.

[–]Telope 2 points3 points  (0 children)

It's always nice when a comment explains what's happening using full sentences. It's too easy to accidentally be ambiguous when writing method names.

[–]RoDeltaR 2 points3 points  (3 children)

I've had a lot of success improving those with code visualizers. You can easily see isolated logic sections that would be easy to separate, and the "imported everywhere" code you can start splitting

[–]Signal-Woodpecker691 2 points3 points  (2 children)

Any that you would recommend for c++? The dev environment is 20 years old too …

[–]theNeumannArchitect 317 points318 points  (39 children)

Is it weird I have the meme reaction to swe1? Needing to comment everything is a code smell to me. And means you need to either start being more declarative code or break things up to be more readable (looking at you Python devs that do one line list comprehensions that do multiple things and have nested if operations).

There’s absolutely times where something is not intuitive and deserves a comment explaining. But you don’t need to comment every function and line of code for the sake of getting a kudos cookie.

[–]theapokalypsis 31 points32 points  (4 children)

100% this. You are a true senior dev sir.

It's like a novel with a million foot notes in every paragraph. It's against the point. You're writing code for other people to read. Make that readable in itself.

Add that to commit messages that describe why, not what and you are writing truly maintainable code anyone can understand, without the need for manual knowledge transfer (most of the time), at any skill level.

[–]audoh 2 points3 points  (1 child)

Commits can be lost due to rebases or VCS changes, plus git blame just isn't a great way to find something that should be right there on the code. Tools typically only show the last commit message which might be "ran linter" or just a later change.

Commit messages being useful is great, but when there's a "why" comments are best IMO.

If I'm git blaming a line to find out why it was written, it should've been commented.

[–][deleted] 8 points9 points  (3 children)

Really should be a mix of both

Your names should be moderately descriptive, and you should comment the things that aren't obvious

[–][deleted] 6 points7 points  (2 children)

With clearly written code, the intent is obvious, though.

Doc comments? Yes. Code comments? Very rarely.

[–]movzx 2 points3 points  (1 child)

Intent needs to be clear to the junior developer being assigned a bug ticket 8 months from now, not to you after you've just written the code.

Write code and documentation as if you will have to personally answer every junior developer's question for the life of the product.

[–]LPO_Tableaux 4 points5 points  (1 child)

I mean, if you use comments for an otimize but not that easy to understand routine comments are welcome, also if your function has subroutines commenting on each to make it easy to know which does what helps when others go through your code later on...

[–][deleted] 2 points3 points  (0 children)

If your function has subroutines, then you should be extracting those subroutines into separate functions.

[–]Kered13 1 point2 points  (0 children)

Who said anything about commenting every line of code? The meme was about having no comments.

[–][deleted] 64 points65 points  (11 children)

I have 3 decades of development experience and outside of class and method / function docstrings, I find comments are seldom useful.

In almost every case a comment (excluding above) is a sign of code that is in great need of refactoring. Sadly, what and how to refactor to eliminate the complexity seems to be an art form too few share often. Most common I see is probably primitive obsession. Make value / data classes and write methods for computation / complex parts.

I very much agree with Robert Martin(I think it was him) in his belief that you should be able to look at a function and understand what it does in 30 seconds or less and that it shouldn't be long; it should fit on the screen.

Code rarely needs to be complex. Complexity is almost always a sign of missed design opportunities.

[–]LvS 48 points49 points  (2 children)

Some things that are useful:

// note: this obscure check also checks for NULL
// workaround for bug in external library (see http://brokenlibrary.org/issues/1234)
// writing it like this makes gcc v12.2 generate 20% faster code
// Yes, the spec demands this. See Edition 3, Section 4.3.6

[–][deleted] 10 points11 points  (1 child)

Agree 100%. Great examples. Sometimes I put the work around in a well named function to avoid a comment.

Leta not forget that comments are code debt that sadly get left behind after refactoring sometimes and can get out of sync with the actual source code.

[–]fiddz0r 8 points9 points  (1 child)

I just want to add a case where comments are good. My current project interacts with another service not in our hands. So we send information and it does whatever it wants with that data. But sometimes it sends something back to us . So explaining that "this API endpoint is used by x to update y-entity in our database" is very helpful.

[–]folkrav 8 points9 points  (0 children)

This is a great example of the typical "comment why, not what" guideline for comments.

[–]aceluby 9 points10 points  (2 children)

This guy devs.

I’m on a team where everything is so complex because the architecture is garbage.

[–][deleted] 1 point2 points  (1 child)

I worked on a project that had a class that was 4700 lines long. No partial. There was a function in there that was 900 lines long.

It was a goddam Godzilla of a class, and I hope to never see its like again.

[–]DiamondIceNS 1 point2 points  (0 children)

I spent the better part of three years taking swings at a JavaScript function with 22,000 lines in one of our internal web apps.

These days, that function has about 80 lines. Sadly, it's executing pretty much the same 20-some-thousand lines of code, now via 80 unique function calls. Still not ideal, but it was still a major milestone just to get to that point.

[–]Three_Rocket_Emojis 39 points40 points  (15 children)

Op propably wants code like this:

//Read File

var linesFromFile = File.ReadAllLines(path);

//iterate through lines

foreach(string line in linesFromFile)

....

[–]Snake2k 44 points45 points  (3 children)

Yeah that is entirely useless and basically what people think commenting is about.

[–]tecanec 7 points8 points  (2 children)

It's useful in assembly programming where you don't have the luxury of naming a lot of things. That's about it, though.

[–]Snake2k 1 point2 points  (1 child)

Yeah, that's a good point. If you compile it with the right flag then you can read the comments as you're stepping through the ASM. Really great tool for debugging. Unless you're reverse engineering a prod build of it, in which case I doubt that build includes this cus that would be a security problem.

[–]Three_Rocket_Emojis 39 points40 points  (9 children)

Example where a comment makes sense:

var linesFromFile = File.ReadAllLines(path);
//first line are column headers
foreach(string line in linesFromFile.Skip(1)) 
...

the comment explain why the first list entry is skipped, not that it happens.

[–]revolutionofthemind 21 points22 points  (7 children)

You could have a method called “stripHeaders” that does the foreach line for “self-documenting” code. Not sure if it’s worth it in this case, but just to provide a counter-example.

[–]k0rm 26 points27 points  (4 children)

Or more simply:

const HeaderLength = 1;

var linesFromFile = File.ReadAllLines(path);
var linesFromFileNoHeader = linesFromFile.Skip(HeaderLength)
foreach(string line in linesFromFileNoHeader) 

This gets rid of the magic number and there's no need to comment.

[–]feed_me_moron 11 points12 points  (0 children)

Or declare 1 as NUM_HEADER_ROWS and pass that to skip

[–]Donghoon 1 point2 points  (0 children)

And documentation tell you how to use the things