12 ms·
My mission to (almost) eliminate code comments
- lultimouomo 6y agoPretty much the opposite advice than http://number-none.com/blow/john_carmack_on_inlined_code.html http://number-none.com/blow/john_carmack_on_inlined_code.htm...
- saagarjha 6y agoI’m curious if anyone has tried some sort of editor plugin that, instead of doing something like “go to function” when you encounter a call, instead temporarily inlines the code into what you’re reading so you’re not jumping around. Seems like this might be the best of both worlds, with abstractions hidden but instantly available to scrutinize when necessary?
- lentil 6y agoVisual Studio Code has a "peek" operation that does something like this. It is indeed quite handy. https://code.visualstudio.com/docs/editor/editingevolved#_peek https://code.visualstudio.com/docs/editor/editingevolved#_pe...
- LandR 6y agoAvailable in the full blown Visual Studio as well.
- Quenty 6y agoVSCode effectively has this feature.
- jl2718 6y agoI would like to see this in a debugger especially. One continuous scroll of code with no separation of stack frames. I would also like to see unit tests unrolled like this for code reviews so others can actually follow the code. This would fight the tendency to accept highly abstract code just because nobody understands it.
- davethedevguy 6y agoBlog post author here. I'm certainly not qualified to disagree with John Carmack! I can speak for my own experience, however. I understand the argument that moving small sections of code into methods/functions hides the details. However, I probably spend more time reading code than writing it. When I'm in 'reading mode', I really just want to understand the control flow; I want the details to be hidden from me. If I'm debugging code, or looking for performance improvements, then I do need to see that complexity. More function/method calls will make this slightly harder for me, but it's a trade-off I'm willing to make for the more common case, I think.
- baby 6y agoI too spend more time reading code than writing, if you have to click through X layers of abstractions to understand something you’re doomed. Clarity must stem from the code, and comments are here to support it.
- lultimouomo 6y agoI think the main argument is the same as other comments pointed out: by factoring out code to separate functions, either they're functionally pure (and this is often hard to do, so much that none of your example functions were) or they're mutating state, which is something you want to have very clearly under your eyes, especially when you're in 'reading mode'.
- cjfd 6y agoWell, John Carmack is in game programming. That is quite a different field where performance is of supreme importance. I might imagine that things are different there, although I cannot claim to know because I do not work in game programming. For 'normal' programming where performance is not the thing one should primarily be worrying about the OP is correct. He is also not the first one to make this observation. E.g., many years ago I read https://blogs.agilefaqs.com/2009/08/19/are-comments-evil/ https://blogs.agilefaqs.com/2009/08/19/are-comments-evil/ . What is written in the OP really should be common knowledge with the provision that perhaps it might not apply in game programming.
- anonred 6y agoFrom the linked article: >In no way, shape, or form am I making a case that avoiding function calls alone directly helps performance. Carmack argues that inlining (small) functions can reduce bugs in handling state by making the logic easier to follow and eliminating any possibility of others calling intermediary functions.
- johncolanduoni 6y agoHe even argues for taking minor performance hints if it reduces variations in execution paths.
- smabie 6y agoCarmack isn't saying you should do it for performance reasons, he's saying you should inline code and eschew abstractions because it makes code better. I tend to agree. I personally think that almost all the abstractions we use are totally unnecessary and we should instead just code the solution top to bottom. This works especially well in array languages, when the name of a user defined function might very well be 2 times longer than the function itself. For example, no need to ever define a function called "flatten" to flatten a list if I can instead just write ",/". Moreover, function definitions are bad because they wipe your working memory. It's better if everything is packed together, ideally as densely as possible. If we did things differently, it would entirely be possible for an entire 5 man team's code output for the year be 1-10 pages of code. And it would do 10000x what the blub languages we use today do.
- lifthrasiir 6y agoI believe that John Carmack's argument considers both the semantics of code and reality of programming languages (here, C/C++), while the OP only considers the former. Ideally naming things without any additional problem (for example, as others noted, extracting a block of code into the global scope violates referential transparency) should be easy, but many languages don't. Carmack is using a comment as a means to give a name without introducing unwanted abstractions.
- nesarkvechnep 6y agoI like how the code in (almost) all the examples can lead to horrible side-effects.
- saagarjha 6y agoOnly if your function has side effects that the name doesn’t imply.
- eeh 6y agoThis is the approach advocated for in https://www.goodreads.com/book/show/3735293-clean-code https://www.goodreads.com/book/show/3735293-clean-code . I like it, but I know some language communities don't.
- baby 6y agoUrg, I strongly disagree with this take. First, comment your damn code if you work with others so that they don’t waste time reverse engineering your code. Sure use better variable and function names but do not create a function that can be inlined just to replace a comment... You’re adding abstraction and making your code less clear (which is not what you intended).
- sime2009 6y agoThe big take-home point here is that comments may be symptom of the code itself not being as clear as it could be. First priority is to make the code itself clearer, that will eliminate the need for a comment to "make it understandable".
- rootlocus 6y agoCompilers can inline functions. Functions can be tested, reused and composed. Comments usually rot.
- baby 6y agoIt’s about code clarity not optimizations.
- axegon_ 6y agoI have mixed feelings about this. I think it depends on the project you are working on. If your codebase can be packed into a few hundred lines of code, with nothing fancy or complicated and no code is being injected from elsewhere, then the author is absolutely right. Documenting what a function or a method does should be sufficient and imo you should do that in all cases, just for the sake of making it easier for new developers to jump into the project if they prefer using some fancy IDE. However if your codebase is composed of several million lines of code(like a lot of the ones I work on), things change. Using readable names is a perfect general advice but eventually you end up with complex logic, which is not necessarily the result of some developer who just wanted to get a task out of their way but could be as well a result of "business needs this by Monday, 3 weeks ago" or simply some mind boggling edge case which needs to be handled. In which case, adding some inline comment with an explanation as to why something is there and ideally a link to your ticketing system can be a life savior. I'm far not a fan of things like: // Increment counter by 1. counter++; You should never do that unless you are studying programming and you have been required to explain every line of code along the way(though I don't know why a professor would ever want that, certainly no one ever asked me to do stuff like that).
- galacticdessert 6y agoI think your point is in line with the article. Comment WHY you are doing something, rather than commenting HOW. And, if you are in a hurry and the logic/naming is somewhat unclear, leave a comment to clarify. In a future refactor, the logic might be made more clear and comments removed.
- davethedevguy 6y agoI agree entirely. As far as code that handles bizarre edge-cases, I tried to cover that in "Comments that explain why". Perhaps I missed the mark a little, but I think I was intending to agree with the point you made. "Often, it’s because I’ve profiled it and found it to be significantly faster, or because it catches an edge-case that a more intuitive method of doing the same thing might not .. Comments like this get to stay." To your point about "business needs this by Monday, 3 weeks ago". Under those circumstances, I write comments to explain my rushed code all the time. In my personal case though, I'd consider this to be "Comments as an excuse not to refactor". It might be a good excuse (maybe the business need trumps readability in the short-term), but I know it's still an excuse and not something I should be doing all the time. I'm trying to get better at going back and refactoring those things later.
- gremlinsinc 6y agoDoes this include doc blocks? I mean a lot of ide's have addon info they glean from those, as well as some api-generators use annotations to generate them, and same w/ phpunit.
- tralarpa 6y agoConcerning the example with the outstanding orders, I think the main problem in practice is not so much the poor naming of the variable, but the lack of documentation of the called function ("Process" in this case). I could live with the variable name "outstanding", but the IDE should better show me a good explanation of what the function "Process" is doing when I point with my mouse on it. The example is also a good example why type declarations are so helpful. Just by looking at the lines "var outstanding = GetOutstandingOrders()" or "var allOutstandingOrders = GetOutstandingOrders()", I could not tell whether the function is returning a list of outstanding orders or whether it has a side effect (reading the outstanding orders into a buffer) and returning a boolean indicating that there are outstanding orders.
- smabie 6y agoThis isn't a good idea. And his functions, well... they're gross. You're going to replace orderCost = orderCost - shipping; with ApplyFreeShipping(); Now you've violated referential transparency, introduced some unnecessary global and mutable state, and not really made anything clearer. Let's take his other example: var outstanding = GetOutstandingOrders(); Into var allOutstandingOrders = GetOutstandingOrders(); Please for the love of god, no. Variable names should be short, and in my controversial opinion, as short as possible. Long variable names actually make code more difficult to understand, not easier. Rob Pike talks about it in the Practice of Programming, and it's a common tenant among APL/J/K programmers as well. Here's how I wish programs were structured: 1) Make your code as terse and dense as possible so you can see as much of it at one time as possible (see code written by Arthur Whitney). 2) Make your variable names abbrevations or acronyms, like instead of 'convertInt', call it 'ci'. 3) Comment every function and keep each function to only a couple lines. 4) Because your functions are so small and dense, you'll never need to modify them, only throw them away. 5) Bam, your comments and never out of date because the functions you're writing never need to be modified, only deleted. Unfortunately, most programming languages don't give you sufficient power to do anything in a couple lines. Which brings up the question, why don't we switch to those that do? Honestly, J or K would be totally usable for the vast majority of programming problems.
- davethedevguy 6y agoI agree that the examples aren't great. I struggled to come up with terse examples to illustrate the point, but I stand by the general premise of the post. I'm afraid I can't agree with making variable names as short as possible as a general rule, though. I think that the length of the variable name should be linked to a) how long it lives for and b) the distance between the declaration and the usage. For example, I'm personally OK with using 'i' for the index in a 'for' loop, but stand by longer names such as 'allOutstandingOrders' for variables that are used throughout a function, where the declaration isn't within a few lines of the usage.
- chimprich 6y agoI agree that variables names should be short, but not "as short as possible". They should be as short as possible while remaining unambiguous and avoiding loading short-term memory. "allOutstandingOrders" does not look to me like a long variable name. > Make your code as terse and dense as possible I really hope I never get to work with any code you've written. > Make your variable names abbrevations or acronyms, like instead of 'convertInt', call it 'ci' I'm starting to think this comment is satire now. If I have to read the comments on a function or variable to figure out what it does then my productivity is going to be absolutely kneecapped if I'm a newcomer to your project.
- Supermancho 6y agoorderCost = orderCost - shipping; // Apply free shipping Now it explains why.
- nailer 6y agoThe author addresses this in the article.
- Jallal 6y agoActually, there are many cases for wich I believe the comments are useful: - When you have some "complex" technical code. Using natural language is sometimes the most effective way to explain what is done by the related code. - When you deal with some business logic that can become weird an one point (process all these things in some ways, excepts these ones, weird edge cases, etc.). From a developer perspective, it does not always make sense, but it's always useful to have some background explaining why the code has been written in such way. - When you have to consider history on a large code base. I know that people on HN mostly work on new shiny projects, but with legacy applications, you have to deal with all the bad/incorrect choices that were made before, and refactoring is not straightforward and is costly. I'm not saying it should not be done, but sometimes, you can work on it only in an incremental way. Comments allow you to add some perspective on the code (explaining the reverse engineering you've done, the initial assumptions, why they turned out to be incorrect, what should be done to improve the situation, etc). Also, I disagree with the facts that comments are born out lazyness. "Lazy" developers don't bother writing comments. Actually, there don't care, and most of them do not even realise that at some point in time, someone will have to browse, read and understand their code. The only kind of comments I've seen from such people are "commented code", because "it might be useful" (it never does). I see comments as a way to engage a (one way) conversation and provide useful and meaningful information to a future code maintainer. Sure, such comments should not clutter the code, be relevant and meaningful, stay up-to-date but it's - as many other things - a skill that require time to get it right. Looking to eliminate all of those is not an approach that I think should be followed (but it's just my opinion). Focusing on allowing the code to be understandable by an hypothetical maintainer in the future is more relevant. If extra comments have to be added, so be it. These are tools, not ends.
- nailer 6y ago> When you have some "complex" technical code. Using natural language is sometimes the most effective way to explain what is done by the related code. Totally agreed here. There's some code in underscore that recursively copies strings as a way of writing '' because it happens to be fast. You'd think it was really weird if it wasn't marked as a performance optimisation. > When you deal with some business logic that can become weird at one point (process all these things in some ways, excepts these ones, weird edge cases, etc.). From a developer perspective, it does not always make sense, but it's always useful to have some background explaining why the code has been written in such way. That's the 'why' addressed explicitly in the article. > Also, I disagree with the facts that comments are born out lazyness. "Lazy" developers don't bother writing comments. Actually, there don't care, and most of them do not even realise that at some point in time, someone will have to browse, read and understand their code. > The only kind of comments I've seen from such people are "commented code", because "it might be useful" (it never does). It sounds like you largely agree with the article. Save comments for 'why', you want to eliminate meaningless comments.
- TedDoesntTalk 6y ago> The majority of comments I write are a born out of lazy coding Then you're doing it wrong. Comments can be used to describe your thinking process, an algorithm, or explain esoteric code. I write comments with the target audience being people who inherit my code 5 years after I've left the project. I'd argue that lack of comments on large projects may be an indication of an immature developer.
- boffinism 6y ago> Then you're doing it wrong. I... I think he knows that. I don't think he was ever going to say "The majority of comments I write are born out of lazy coding, so that's perfect."
- davethedevguy 6y agoYes, exactly this. The reason for writing this article is that I know I often do it wrong. I'm trying hard to make sure that the comments I do write add value to future readers of the code (including me), and are not just be a by-product of another deficiency in my coding style (such as poor variable naming, to use one example).
- pydry 6y agoI'd say that's doing it right. There are typically more effective ways of documenting code - i.e. better abstractions, naming and tests. The problem is that they are more expensive than comments. Comments are cheap and often better than nothing.
- LandR 6y agoIf you don't like to see the comments hide them in your IDE. Most decent IDES let you set the background and foreground colours based on the code. i.e. I have comments for type /* */ and // set to be grey on a slighgly darker grey so they are pretty much hidden (as they are useless most of the time).
- goto11 6y agoIMHO this is the worst of both worlds. Comments very easily get out of sync with the code then. I prefer the comments to stand out more than the code. Also helps eliminating useless filler comments since they are so noticeable. If you have comments, they should be important and helpful.
- kelnos 6y agoI don't think this really makes much sense. In my experience people who heavily comment their code don't put much effort into making the code itself all that readable. People who eschew comments are more likely to focus on writing self-documenting code. (Yes, there are people in both camps that go the other way, but I find those less common.) Hiding the comments will just make the difficult-to-read code harder to understand, and will make it more likely that changes to the code will ignore the comments, and they'll become out of date.
- LandR 6y agoI worked in a place where if you commented your code you would fail the code-review. I had a mate who worked at a place where the code once it was checked in was ran through a processor that deleted comments!
- davethedevguy 6y agoWow! I'm not sure I'd go as far as to eliminate comments entirely! My aim is just to write _less_ comments, so the ones I do write mean something and aren't just noise.
- wastedhours 6y agoHow strange - I've always found comments useful. As I'm not a developer but sometimes have to edit different files in the code just to enable/add in new parameters (so engineering resource isn't needed to be planned in), it's always been helpful to have explicit guidance in the code as to what I'm reading is doing. Still get a code review afterwards anyway, but minimises risk. If you're expecting non-developers to sometimes interact with your code or to help with troubleshooting, in-line comments will always be appreciated.
- biddlesby 6y agoThis is a great point. You might take a different approach depending on when you expect your reader to already be proficient in the language or the framework, compared to whether a non-developer might be reading the code. One argument against these kind of comments is that they aren't the right place to teach somebody a programming language. However I can definitely see cases where they are justified.
- partyboat1586 6y agoTerse variable names are easier to read if you're doing anything non trivial. I only need to understand what it is once, not every time the symbol appears. If the abbreviation isn't clear then add a comment when it's declared. The comment is just as likely to go out of date as the variable name itself so there is no cost to the comment.
- tluyben2 6y agoTo give some 'yes, that's maybe great, but is it practical?' feedback; I often work with (bigger) companies where code reviews fail if you don't have: - comments, the more the better - design patterns, the more the better Even if absolutely useless; the over-architecting just for over-architecting sake is quite... Not only does it take a lot of time to actually reuse the code (a lot/all of those patterns are conceived for reusing code in the first place but in reality it takes people a long time to get into them and the gains are not convincing aka I see people just plonking together a little microservice in a fraction of the time with Node and (virtually) no design patterns to replace (parts of) the java/c# monster that does the same thing just to make the deadline or to skip diving into the sea of blackness), but the comments really do not help at all; they are just there to have comments. And the design patterns (+ the way they are used) are considered standard (they are, but not for young people who have no degree and no experience applying them, or maybe even knowing they exist). Still, without all that, the merge requests are being declined until you pop in random drivel 'for best practice'. I am a fan of terse but readable code these days (it changes somewhat); the design patterns are more and time wasting (to me), especially when enforced in this way (but I think everyone will agree with that anyway).
- AdrianB1 6y agoJust my 2c: - the theme is to move the comments in the code by using variable names and function names that tell a story. Not a bad idea by itself, but nothing special there either. - moving a simple one-liner arithmetic operation to a function that is stored somewhere else is a complexity increase that is hard to justify. Every line of code can be hidden behind a function, is that productive, acceptable and lean? - not trying to be picky, but for free shipping I would prefer to do shippingCharge = 0 instead of that because that is what you want to do. And a question: if the comments are out of the code (where they are mostly contextual), what kind of documentation is left behind for the support team? In my world the support team has encounters with code written 10 years ago by people no longer around, they know high-level what the code is doing, but the devil (bugs) is in the details.
- davethedevguy 6y agoI agree entirely that this isn't anything new, I hope I didn't imply it was. This is simply my own reflection on how to improve my coding style. > "Every line of code can be hidden behind a function, is that productive, acceptable and lean?" I've seen some advocate for that exact thing, but I certainly wouldn't go that far. I don't think we have to have one or the other, there's a middle ground in my opinion. If the code requires a comment to explain it, then maybe a well-named method/function is a better option. If the code is obvious in its own right (looping over a collection to add 1 to everything, to use a dumb example) then I don't think abstracting it is justified. I certainly don't have any objection to single-line functions to add readability per-se. (with the caveat that a compiler would produce the same result either way, or otherwise the performance of another function call isn't an concern. I'm talking purely about readability here)
- seanwilson 6y agoTo counter the negativity, this was a good post and I agree with it. The example with the unneeded comments for conditionals and the one that explains "what" a function does is something I see even senior devs do all the time. I think a lot of replies here aren't reading the article or are focusing on nitpicky examples. "Comment your code!" is a deeply ingrained piece of advice people throw around without the warning that a lot of coders write comments in place of good function names and variable names.
- zwaps 6y agoThe author has a point that comments may be superfluous when going through a code line by line. However, that's not the only sort of code-reading. Comments can sometimes be better to get an overview of a complex program. Not if it is your own code, sure, or even in a code-base you work in. But faced with a huge amount of foreign code, over-commenting can be very useful (at least for me). This should not be an excuse to write bad code - here I agree with the author. But given that, I see little downside in good comments. It's an extremely challenging task to think about how others would perceive our coding. Perhaps the reader isn't familiar with a technique or function that seems obvious to you? It's the same as trying to give a lecture on a subject. Pedagogically, it's preferable to have more comments than less.
- tuananh 6y agoi like the idea in general but the example is quite awful.
- l0b0 6y agoA useful way to think about it is that names are basically comments, but only names can be looked up by an IDE. When looking for a frobnicator I can find it trivially if there is something named "frobnicator" or anything similar. If there is a docstring mentioning frobnication (maybe with some "alternative" spelling or other word form like a verb when I'm looking for the noun), on the other hand, that's much harder to find. And once I find it, I still have to locate the actual frobnicator somewhere near the comment. Even this is the ideal case, where only one comment mentions frobnication. What if it's a common word? Now the chance of finding the right thing in a reasonable time goes way down if it's not named properly.
- sgt101 6y agoEvery programmer comes to believe that comments are the symptoms of bad code at some point in their development. Many, but not all, of them realize that they are wrong quite quickly afterwards. Comments aren't a crutch to be used because of an impairment , they are helpful support in the face of the challenges of diverse technologies, poor documentation and difficult communication over time and space. Importantly they are integrated into the code base and are aimed at a very specific consumer - future programmers. Future programmers who may include you!
- thiht 6y agoI'm not so sure about converting if (customersFirstOrder) { // Apply free shipping orderCost = orderCost - shipping; } to if (customersFirstOrder) { ApplyFreeShipping(); } Does `ApplyFreeShipping` work on global state? How do we test it? At the very least it should be something like: orderCost = ApplyFreeShipping(orderCost, shipping); which has advantages over the first version but is not necessarily better. The suggested version is just awful though.
- alfiedotwtf 6y agoAfter seeing Damian Conway‘s training courses teach this, I’ve tried to shoot for this style ever since. It definitely lowers cognitive load and “feels” better, but I still feel bad when adding function call overhead just for style (maybe the compiler is actually that smart and there’s no hit)
- spderosso 6y agoRelated article (published in 2017): https://testing.googleblog.com/2017/07/code-health-to-comment-or-not-to-comment.html https://testing.googleblog.com/2017/07/code-health-to-commen...
- ykevinator 6y agoComments are great for teams and your future self but your point is well taken
- taylodl 6y agoThere I was all ready to get my pitchfork out and then I read the article and damn! These are good points!