No offense, but functionally like that shows up in school assignments and billion dollar companies back ends. However, it’s easy for even that simple idea to end up being something like: Item.FinalPrice = Item.BasePrice * CalculateModifier(Item.ItemCode, Item.OrderContext); Which sacrificed understanding for elegance.
Sure, the functionality to find that SalesTax number might take tens of thousands of hours to create and cover a multitude of egde cases. Still with proper context, structure, naming conventions, etc the why’s should be clear. If your thinking “The exceptions function adjusts for tax holidays. So of course it needs to get exceptions based on location and the order date, and then it needs each items metadata etc” then that’s a great sign.
Elegant code is elegant when it encapsulates the why’s not just the how’s.
>However, it’s easy for even that simple idea to end up being something like: Item.FinalPrice = Item.BasePrice * CalculateModifier(Item.ItemCode, Item.OrderContext); Which sacrificed understanding for elegance.
Sure, and I'd call that bad code unless it exists because there are far more considerations than sales tax. Either way I don't see how that is an example of when to or not to leave a comment.
>Sure, the functionality to find that SalesTax number might take tens of thousands of hours to create and cover a multitude of egde cases. Still with proper context, structure, naming conventions, etc the why’s should be clear.
Again, that's just not true. I have a hard time imaging that you're a professional engineer with real world experience if you've never found yourself in a situation where variable names alone could not express the _why_ behind a piece of code.
>Elegant code is elegant when it encapsulates the why’s not just the how’s
Great, not always possible. For example:
// We have a longer than normal backoff period on
// timeouts here because device XYZ is a piece of junk
// and randonly stops responding for minutes at a time
or
// version 2 of the spec switched to an XML format and
// allows the header to be anywhere above the root
// element of the document (as a processing
// instruction). We cannot define a reasonable min
// header position/length. Just read the whole file.
const size_t MinHeaderLength = std::numeric_limits<size_t>::max();
or
// Workaround issue caused by .NET 4.6.1 upgrade which
// has more restrictive certificate checks for secure
// connections. This is currently affecting SignalR
// Scaleout connections to Azure Service Bus.
AppContext.SetSwitch("Switch.System.IdentityModel.DisableMultipleDNSEntriesInSANCertificate", true);
Of course you could suss out the reasoning on your own eventually, but why force people to do that? What variable naming scheme would you use to convey those reasons?
You’re missing my point of course we sometimes need comments. It’s a question of design tradeoffs. CalculateModifier could be part of a great design or a terrible one, but the need for comments based on the near meaningless name is an obvious issue that would need to be balanced by something else. Consider these projects:
Several years ago I was updating this ancient Object Pascal program. OS X had just showed up and they finally decided to do a full rewrite, but they wanted to do this is stages. Anyway, this thing was still using Apple Talk networking not TCP/IP and I was rewriting the network stack so we could replace each system individually. Surprisingly, the code was very easy to read, but was also filled with a long legacy of past issues. Comments on 68000 processor issues could safely be ignored for example. So yes lots of comments, but most of them had become useless.
More recently, I was redeveloping a .NET website that had been built by someone in love with XML. Unfortunately, the mismatch between the way the code operated and the way the system operated meant that you needed to carefully read each comment. It had slightly fewer, but far more nessisary comments which was one sign among many that it was a horrible design.
Which is why I am talking about nessisary comments. Many comments can safely sit in source control or automated tests. Their context quickly becoming outdated. However, when a systems design nessitates a great many important comments that’s a bad sign.
Many coders will argue that these comments are the type of information that should be captured by the version control system, not in the code itself.
The biggest problem with comments is they are not part of the tested integrity of the system. In other words, they are never tested for correctness.
How many times have you come across a comment that appears to have no bearing on what the code is doing? In heavily commented code, this happens all the time because a developer (not necessarily the original developer) makes a change and does not update the comment. It could be that the developer was in a hurry and sloppy, or that the change was upstream and made the comment irrelevant, or maybe the code was copied and pasted into a context that doesn't match the comment, or whatever. The point is that comments can become stale, and a stale comment is worse than no comment at all.
Sure, the functionality to find that SalesTax number might take tens of thousands of hours to create and cover a multitude of egde cases. Still with proper context, structure, naming conventions, etc the why’s should be clear. If your thinking “The exceptions function adjusts for tax holidays. So of course it needs to get exceptions based on location and the order date, and then it needs each items metadata etc” then that’s a great sign.
Elegant code is elegant when it encapsulates the why’s not just the how’s.