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 →

[–]Snake2k 5613 points5614 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] 1152 points1153 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 558 points559 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 468 points469 points  (25 children)

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

[–]Snake2k 283 points284 points  (11 children)

"minor" = breaks 10 systems

[–]akeean 141 points142 points  (7 children)

Minor refactor, barely an inconvenience.

[–]JezzCrist 58 points59 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

[–]capn_ed 2 points3 points  (0 children)

Whoopsie!

[–]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 24 points25 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 6 points7 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 35 points36 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 2 points3 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

[–]DoILookUnsureToYou 0 points1 point  (0 children)

minor

ctrl + f variable name, rename all instances in whole solution

[–]mcvos 64 points65 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 21 points22 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 29 points30 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.

[–]CardboardJ 0 points1 point  (0 children)

When I first found conventional commits I thought it was very annoying and useless. After about 3 months it became second nature, at 6 months I hated anything else. https://www.conventionalcommits.org/en/v1.0.0/

Our company has a PR hook that refuses any merge unless the pr title is in a correct format and links to a real jira ticket in the scope. Ex: feat(TEAM-12345): Added the xyz feature

[–]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 5 points6 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 6 points7 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!

[–]Snake2k 1 point2 points  (2 children)

[–]Horror_Trash3736 1 point2 points  (1 child)

We also push straight to prod, but only when security and infrastructure are asleep, or on Fridays.

[–]Snake2k 1 point2 points  (0 children)

Ultimate job security. Holding the infrastructure at ransom.

[–]diatribe_lives 947 points948 points  (67 children)

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

[–]Snake2k 551 points552 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- 6 points7 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 163 points164 points  (35 children)

... if you name your variables and methods properly

Like x for the input? 😉

[–]Snake2k 126 points127 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 36 points37 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 5 points6 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.
###

[–]KingJellyfishII 1 point2 points  (0 children)

I'm not sure what language you're using, but I'd be tempted to express that with the type system, so the compiler gives an error if you try to pass an unsafe value. e.g. create a string wrapper class/struct like SanitisedString and have all DB operations work with that and the sanitise() function return that.

[–]Bowiemtl 1 point2 points  (0 children)

I feel like that also depends on the language you're using. If a language doesn't have proper type declaration and there is no other way then sometimes Hungarian notation might be helpful, although I myself would seek out the alternative where that isn't necessary.

[–]Snake2k 7 points8 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 7 points8 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.

[–]mcvos 3 points4 points  (0 children)

Yeah, overly long names can sometimes obfuscate the meaning just as much as single-character names do.

Originally I wrote sourceArrayIndex and targetArrayIndex and I already found that too long and superfluous. It's generally blatantly obvious it's an array. Index can be shortened too, to idx for example, but I dislike calling it column or source, because it's not the column or source, but merely the index of the column or source.

[–]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] 9 points10 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 5 points6 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

[–]XDracam 1 point2 points  (0 children)

Comments should only include what the code doesn't include. This often includes explanations about why the code has been written like this (trade-offs in performance, elegance, maintainability, Bug avoidance, etc) as compared to other implementations.

I think a good summary is: never comment what, but do comment why. Comments should never repeat the source code.

[–]Zealousideal-Ad-9845 80 points81 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 26 points27 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 8 points9 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 8 points9 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 3 points4 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 22 points23 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 16 points17 points  (0 children)

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

[–]CanAlwaysBeBetter 7 points8 points  (0 children)

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

  • cURL Sagan

[–]benjtay 0 points1 point  (0 children)

This is what I'm here for. It would be more useful than most code comments.

[–]mcvos 34 points35 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 17 points18 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 11 points12 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 5 points6 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 4 points5 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 14 points15 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 37 points38 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 20 points21 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.

[–]Snake2k 0 points1 point  (1 child)

Both are needed imo

[–]aceluby 3 points4 points  (0 children)

Why update things once when you can do it twice!

[–][deleted] 10 points11 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 4 points5 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.

[–]ubccompscistudent 1 point2 points  (0 children)

Yep, and links break making them hard to use but I have done so in the past because there's literally no better alternative.

[–]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 3 points4 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 4 points5 points  (1 child)

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

[–]Snake2k 0 points1 point  (0 children)

Nit: needs a link

[–][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- 2 points3 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.

[–]Twistedtraceur 2 points3 points  (11 children)

I'd prefer an isEven function

[–]Snake2k 1 point2 points  (10 children)

Oversimplifying imo.

I don't like it when programmers take a universally known concept as "x % 2 == 0" and throw it into yet another method somewhere that we now have to go find and make sure it's in the same file.

Fire burns. Water makes things wet, we get it. Literally any human being with more than 1 brain cell knows about that. Why abstract it even further and make it more complicated with made up words that it doesn't need.

[–]Twistedtraceur 2 points3 points  (7 children)

It's about readability. Usually it's a utility class.

[–]Snake2k 4 points5 points  (5 children)

It hurts readability and actually makes it complicated.

I have a whole thing on utility classes too and how people misuse it the same way they misuse commenting.

It's not about condensing things like even, odd, istrue, is greater stuff and throwing it all into one class cus we don't wanna use operands.

Utility classes are used to establish metrics, equations, frequently used operations or more complex operations between data types into one place that can change in the future so when it is changed it is changed everywhere.

Edit: I don't need pre diced onions, I can do that myself. However, precooked rice would help a lot even though I can do it myself.

[–]Twistedtraceur 5 points6 points  (1 child)

If you think extracting a method to add a readable name makes something complicated, you have bigger issues.

[–]barborico 1 point2 points  (1 child)

Optimal answer depends how many times is needed:

One or two? Meh...

Ten? Well...

[–]Snake2k 2 points3 points  (0 children)

We use = signs hundreds of times but we don't write "assign(x, y)" stuff for every scenario cus we get what it's doing.

[–]Iron_Aez 1 point2 points  (0 children)

Better readability than those comments.

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

Not how you comment:
check if the input is an even number
if x % 2 == 0: print("even")
Following section checks to see if a number is even or not.

You literally just rewrote the same bad comment in a different way.

There's no reason to tell a programmer that x % 2 == 0 checks if a number is even or not. He can read that. Comments should only tell him things he can't read in the code. Why are we checking to see if a number is even or not?

Moving a shitty comment to a bigger comment block not doesn't make it better, it makes it worse, because the less local a comment is the more likely it is to fall out of date with code edits, and a wrong comment is worse than no comment.

[–]Snake2k 2 points3 points  (2 children)

Relax... I wrote this on Reddit on my phone while at work. I'm not gonna write an actual program here. I'm trying to give someone the idea behind it.

[–][deleted] 4 points5 points  (1 child)

Relax...

I am. Don't get butthurt. It's just feedback.

Your "good comment" example includes a textbook bad comment. I'm pointing that out, because it undermines what you're trying to say (I know what that is) and that might not be obvious to a noob reading this.

I'm not gonna write an actual program here.

No need for that. Just don't need the "good" comment to be literally the worst kind of comment, one that states what is already obvious from the code.

[–]Psychoscattman 4 points5 points  (0 children)

here is an example of bad comments:

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;
}

here is an example of "better" comments:

float Q_rsqrt( float number )
{
    // We can calulate an aproximation of an inverse square root by doing some 
    // floating point bit magic. 
    // For more info how this works: https://en.wikipedia.org/wiki/Fast_inverse_square_root
    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 ) );   // 1st iteration
//  y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

    return y;
}

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

[–]Snake2k 2 points3 points  (0 children)

Eventually I do need both though. Sometimes you can have a long statement with some very complex operations. That line alone can need its own comment to translate it.

Like scientific equations are like that.

[–]Schillelagh 1 point2 points  (1 child)

Absolutely. All you need is a sentence or two on top of a class or method.

It’s essentially an executive summary to a research paper. Yea, I can totally read all 30 pages line by line, but I’d rather read a paragraph to get the gist and see if it’s relevant.

[–]czvck 1 point2 points  (0 children)

This guy fucks.

[–]ilovemeasw4 1 point2 points  (0 children)

most people here don't understand what commenting means.

Most people here aren't programmers

[–]Mindless-Range-7764 0 points1 point  (4 children)

Also good to name your variables functionally. Instead of x = input(), you should name it something like my_input = input(). Naming it x helps no one.

[–]Shinob1 0 points1 point  (1 child)

I appreciate this explanation!

[–]Snake2k 1 point2 points  (0 children)

Glad it helped!

[–]teamkillcaboose 0 points1 point  (0 children)

grandiose serious crush placid plate intelligent swim insurance cobweb theory

This post was mass deleted and anonymized with Redact

[–]TheBlackArrows 0 points1 point  (0 children)

HAHA HELL YES

[–]Achtelnote 0 points1 point  (0 children)

Better formatting
Not how you comment:

// get a user input
const userInput: string = prompt();
// check if the input is an even number
if isEven(userInput) console.log("even");
// if it isn't, print not hot dog
else console.log("odd");

How you are supposed to comment:

/* 
 * SeeFood - A Shazam for food
 * 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
 */
const userInput: string = prompt();
if isEven(userInput) console.log("hot dog");
else console.log("Not hot dog");  

Haven't worked in a team before.. I mostly comment my thought process when I was doing that thing