54

Don't be afraid to make a name long. A long descriptive name is better than a short enigmatic name. A long descriptive name is better than a long descriptive comment.

Robert C. Martin

Did I understand Clean Code right? You put the whole information that you would put into a comment into the class/method/... name. Wouldn't that lead to long names like:

PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorComments
PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorDescriptions
TomatenSalat
  • 732
  • 1
  • 5
  • 9
  • 19
    I suspect that a lot of the information of those variables would be encoded in their type, so in a realistic scenario you would only need to label the parts that distinguish them – Alexander Apr 29 '20 at 23:34
  • 49
    Argh! Ocular trauma. Think of it like writing a story. How often do you want to see `said Penny from over the road, born in the blue house, friend to Bob`. If you are in that context `Penny` is sufficient, or maybe `Penny White` if there are two possible Pennies around. Or may `Bob's friend Penny` when we are already talking about `Bob`. Chances are this class is already in the UI, therefore it is already graphical. Its probably in the namespace for the editor so how about: `CommentsReloader` and `DescriptionsReloader`? – Kain0_0 Apr 30 '20 at 00:14
  • Does this answer your question? [Self Documenting Code Vs. Commented Code](https://softwareengineering.stackexchange.com/questions/51307/self-documenting-code-vs-commented-code) – Martin Maat Apr 30 '20 at 05:36
  • See also this excellent answer to another duplicate of your already heavily debated question: https://softwareengineering.stackexchange.com/questions/350876/how-to-avoid-falling-into-the-trap-of-not-commenting-code/350895#350895 – Martin Maat Apr 30 '20 at 05:38
  • @MartinMaat I already read that thread. Thank you. In this thread the discussion should be specifically about the length of names, not comments in general. But thank you for noting it. – TomatenSalat Apr 30 '20 at 07:11
  • 20
    @TomatenSalat: The point is that ridiculously long names do not make up for good comments and documentation. "Do not be afraid to use a long name" is not the same as "try to avoid comments by making your names longer". – Martin Maat Apr 30 '20 at 07:44
  • @Kain0_0 that would not be sufficient, because it is not a CommentsRelaoder but a Page Reloader. Not the commets get relaoded by it but the Page is. CommentsReloader would imply another meaning. – TomatenSalat Apr 30 '20 at 09:52
  • 2
    Who's the human audience for your code? Your future self, for one. Your co-workers and future co-workers for another. Write the code for the audience. Matt Mullenweg (WordPress) likes to say "code is poetry." Sure, but don't write it so somebody needs a PhD in postmodern semiotics to understand it. Imitate Socrates, not Aquinas. – O. Jones Apr 30 '20 at 12:01
  • @O.Jones so are you saying that when the audience writes not understandable code to keep the truck factor high, I should do the same? – TomatenSalat Apr 30 '20 at 13:18
  • 3
    It's worth noting: even with absurdly over the top examples that long, they're *still better than too-short variable names.* Yeah, you're trying to make a point but... I know *exactly* what they're referring to, and would much rather have that silliness than 'PRComments' or something similarly vague. I agree that it's better to restructure so that level of detail is needed... but when in doubt, err on the side of a longer name. – Kevin May 01 '20 at 14:55
  • 3
    Be afraid! Reading code with those long names is a nightmare! Especially when several names have the same pattern and/or common words. I prefer reading a comment and keep in mind what that means, then being able to go through lines of code easily. A code has a spirit, people using those long names had never had to read other people's codes. – Alexis May 01 '20 at 23:20
  • 2
    @Alexis_FR_JP Exactly. I've actually worked with code that was written this way i.e. variable names looked a lot like those examples. I think it was because of a similar reading of Uncle Bob. If you've got any normal line limit standards, it should be obvious that this is unpleasant. The real problem is that it is very difficult to distinguish between these. You've got two names that are 74/78 characters and the first 66 are the same. It takes time to find the critical information. Proper scoping eliminates the need for this and comments as well. – JimmyJames May 05 '20 at 13:56
  • I'll offer a non-programming example of how this idea of sentence length variable names is bunk: when you first learned math, you didn't know what 'pi' means: But imagine if you had a math teacher that insisted on always using the phrase 'the ratio of a circle's circumference to its diameter' because 'pi' is an arbitrary term. Meaningful and readable should be the goal for variable names. Shorter variables (to a point) tend to be more readable, all else equal. – JimmyJames May 05 '20 at 14:26
  • @JimmyJames What about class names in projects, that will be written once and need changes once a year and are in a very specific domain context? – TomatenSalat May 05 '20 at 14:28
  • @TomatenSalat I not sure I totally understand the question but the concept of namespaces (or packages) exists so that we can use scope give context to names. Just like you don't need to qualify the city when you are talking about a local address, it's not necessary to refer to everything in program by its fully qualified name. – JimmyJames May 05 '20 at 15:06
  • I had to deal with some people at AMZN that would prefer names like this. Brain dead is what I call it. I agree with the other commenters that types and context can say a lot about a variable. – Steven Eckhoff May 05 '20 at 16:02

10 Answers10

161

Yes, you understand Clean Code right, but your examples are quite a bit over the top.

Here is what you start with:

PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorComments 
PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorDescriptions

In your system you probably don't have many kinds of reloaders, you probably only have page reloaders, so the first occurence of "Page" is redundant. This leaves you with:

ReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorComments 
ReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorDescriptions

And since a reloader always reloads pages, the second occurence of "Pages" is redundant, too. This leaves you with:

ReloaderForDisplayingVectorGraphicsThatAreUsedInTheEditorComments 
ReloaderForDisplayingVectorGraphicsThatAreUsedInTheEditorDescriptions

Pages are always displaying stuff, so the Displaying part is redundant, too. This leaves you with:

ReloaderForVectorGraphicsThatAreUsedInTheEditorComments 
ReloaderForVectorGraphicsThatAreUsedInTheEditorDescriptions

In English, constructs like this-that-is-used-in-that can be reworded as that-this. For example, coloring-that-is-used-for-food is food-coloring. Applying this rule to replace "Vector Graphics That Are Used In X" with "X Vector Graphics" leaves you with:

ReloaderForEditorCommentsVectorGraphics 
ReloaderForEditorDescriptionsVectorGraphics

Also in English, constructs like this-for-that can be reworded as that-this. For example, bottle-for-water can be reworded as water-bottle. Applying this rule to change "Reloader For X" to "X Reloader" leaves you with:

EditorCommentsVectorGraphicsReloader
EditorDescriptionsVectorGraphicsReloader

And then of course there may be other shortcuts you can apply, depending on your particular problem domain. For example, when you speak of 'vector' in your system, it may be fairly clear that you are speaking of 'vector graphics', so this would leave you with:

EditorCommentsVectorReloader
EditorDescriptionsVectorReloader

... and I think that these are some pretty good realistically long names.

Mike Nakis
  • 32,003
  • 7
  • 76
  • 111
  • 25
    Also, some of that information could be in the name of a shared `VectorReloader` base class, or perhaps `EditorCommentsReloader` is a variable of type `VectorReloader`. – Robin Bennett Apr 29 '20 at 11:32
  • 1
    *"constructs like this-that-is-used-in-that can be reworded as that-this"* - I'm afraid that from this point I lost my composure completely! – Steve Apr 29 '20 at 11:37
  • 1
    @Steve that's why I added an example immediately following that. – Mike Nakis Apr 29 '20 at 11:46
  • 6
    Mike, don't get me wrong, it's a great post with clear reasoning, it just became unintentionally comic for me at that point haha! – Steve Apr 29 '20 at 13:10
  • 15
    And now you have (relatively) short enigmatic names instead of long descriptive ones. – Jacob Raihle Apr 29 '20 at 13:33
  • 32
    @JacobRaihle Well, I think the alternative is something like `CRldr` and `DRldr`. _Those_ are short enigmatic names. With that in consideration, I think something like `EditorCommentsVectorReloader` is still reasonably descriptive. (Though to be fair, I have not read the book.) – David Z Apr 29 '20 at 20:53
  • 2
    there is a big difference between a VectorReloader and a VectorGraphicsReloader. If the name was only VectorReloader, there would be a comment needed that says, that it is about Vector Graphics. – TomatenSalat Apr 30 '20 at 06:21
  • 16
    @TomatenSalat That depends. If all throughout the codebase, everything is either `VectorThis` or `RasterThat`, it will be pretty understandable. If there is a vector algebra library included in the mix, then indeed `VectorGraphics` would be necessary. – Angew is no longer proud of SO Apr 30 '20 at 06:51
  • 1
    @AngewisnolongerproudofSO I think that Vector is not a descriptive name for VectorGraphics, no matter the scope. If I stumble upon it after a year, I would not mean what it meant. – TomatenSalat Apr 30 '20 at 07:02
  • The first sentence of this answer is a contradiction. If the examples are wrong, then the understand is wrong. Unless it's what the author really means. In any case, it doesn't actually matter if Martin advocates this style or not, but his book seems to spread it in practice (as proven by a lot of questions here on SE). – Christian Hackl Apr 30 '20 at 08:39
  • @TomatenSalat, you always have my alternative which was "VectGfx", which I think is totally unambiguous to anyone who understands the first thing about computer graphics. Is it possible you are speaking as a non-native English speaker? – Steve Apr 30 '20 at 09:57
  • 3
    @Steve https://www.psychologicalscience.org/observer/alienating-the-audience-how-abbreviations-hamper-scientific-communication I personally avoid all abbrevation, since they are never as good as the real thing. Just think of Graphic effects, Global effects, ... . Question whether your use of abbreviations is motivated by keeping other people out. – TomatenSalat Apr 30 '20 at 10:01
  • 8
    @TomatenSalat, once names reach over 70 characters and over 20 syllables, I'm quite sure that my motivation for contracting those names is to enhance readability and bringing people in, not keeping people out! The advice your link gives concerns prose within scientific papers, where the purpose is typically to explain at length something that is unfamiliar or contentious, and economy with characters or syllables would not be expected. If your program requires such detailed explanation, then it would be done in documentation, not in the naming scheme. – Steve Apr 30 '20 at 10:21
  • 1
    unfortunately there were no articles done yet on abbreviations concerning programming, but they might come to similar conclusions. the funny thing of our brains is that we do not read all the characters anyways. I tihnk you konw waht I'm tlainkg aoubt. So reading 71 character long names can go as easily as reading `int i` when you are trained and when you know what it stands for, you do not even have to read it anymore. look at traditional chinese characters with their up 50 strokes. – TomatenSalat Apr 30 '20 at 11:23
  • @TomatenSalat, I'm quite sure that any article on computer naming, will confirm my contention that 70 characters for a single identifier is unwieldy to the extreme. Your article is simply at cross purposes, dealing as it does with natural language prose, not with source code. If we were talking about *documentation*, I'd absolutely support the idea of writing at length. – Steve Apr 30 '20 at 13:18
  • To be frank I lost you on the 4th block. I agree up to the 3rd (included) – WoJ Apr 30 '20 at 15:08
  • 3
    Just to add in my bit: this is where underscore_case is better than CamelCase. Easier to read when using long names. – Pik' Apr 30 '20 at 15:15
  • 3
    As another step, you can use context. It annoys the hell out of me when variable names include duplicates of the name or class you're in. So, if the `Editor` type has an `EditorCommentsVectorReloader`, you can drop the prefix and just call it a `CommentsVectorReloader`. – anaximander Apr 30 '20 at 16:08
  • 1
    While I do agree on your points, in this example I don't really feel that `EditorCommentsVectorReloader` means "A reloader used to reload pages that contain vector graphics used for editor comments"; for one, I think that in this case "Graphics" is more important than "Vector", and as it is, the final name implies that it reloads just the graphics and not the whole page. – Josh Part Apr 30 '20 at 17:26
  • @JoshPart maybe there is another reloader for pixel graphics. – TomatenSalat May 04 '20 at 06:42
  • @TomatenSalat: _"I think that Vector is not a descriptive name for VectorGraphics, no matter the scope. If I stumble upon it after a year, I would not mean what it meant"_ If I only used my first name to identify myself to the government, it wouldn't work. Yet my wife always calls me by my first name alone and my friends all seem to know who she's talking about. If there's only one person in my circle of friends with that first name, I am identifiable in that scope by my first name. If all "vectors" in your codebase refer to graphics, then "vector" identifies "vector graphics". – Flater May 05 '20 at 09:56
  • 1
    @TomatenSalat "Vector" meaning "vector graphics" is not pedantically correct, but it significantly cuts down on the length of names without (unreasonably) reducing the legibility of the code. If you instead advocate pedantic precision at all times,do you then also expect everyone to call you by your full name at all times, or is the hassle of doing so not worth the pedantic precision in that case? – Flater May 05 '20 at 09:58
  • this answer totally changed the meaning of what the class does. (reloading pages containing vector graphics, but only then, when those vector graphics are also displayed in the descriptions of an editor) – TomatenSalat May 05 '20 at 13:45
  • @Flater There is a difference between a team of constantly changing developers and a wife. If you want only developers that you know as long as your wife to understand your code, then do it. Keep in mind that it keeps the truck factor high, though. – TomatenSalat May 15 '20 at 06:30
  • @TomatenSalat, that's why people don't change their wives frequently, because the costs would be extreme. The challenge of trying to treat developers like disposable cogs will not be met by elongating names - any more so than an elementary education in mathematics can be dispensed with by replacing each use of the plus sign with a fixed sentence such as 'TakeTheLeftNumberAndAddItToTheRight'. – Steve May 15 '20 at 10:14
  • @Steve I wish that mathematicians would name their operators in their papers like that when using them for a different thing than one would expect. I read a paper where the sigma sign didn't mean: "sum all elements up", but "sum up all elements of each vector and then sum all sums up". It took me half a month to understand it out of the context. – TomatenSalat May 18 '20 at 14:04
  • @TomatenSalat, yes, mathematical notation is sloppy in many ways because (like other natural language) it is primarily intended to be parsed and executed by humans, who have tacit knowledge and often a sense of purpose to resolve ambiguities. The problem is nobody can decide what should replace it, and things often become unwieldy if symbols and notations are not overloaded with many meanings which depend on context. – Steve May 18 '20 at 14:47
28

No, Uncle Bob is not saying that.

There is no part in his book saying that you have to put ALL COMMENTS in the class name, "the whole information" that you mentioned.

Probably you don't need a specific "PageReloader for Pages Displaying Vector Graphics etc etc" and should use the same PageReloader for all kind of pages.

In his book there are a lot of examples of what he exactly means with "replacing short enigmatic names by descriptive meaningful ones".

RubioRic
  • 397
  • 2
  • 9
  • 10
    Uncle Bob is not saying that, but it is the natural conclusion by some for the "some comments are bad; thus never ever write a comment" narrative. – Peter Mortensen Apr 29 '20 at 22:20
  • 3
    @PeterMortensen Natural conclusion? OP has mixed two recommendations in one: meaningful names and no comments. It doesn't come so natural to me such conclusion: Ey, let's kill two birds with one stone. Why not? – RubioRic Apr 30 '20 at 14:35
17

You have to take everything in Clean Code together. I've read the book more than once. I frequently lend it to new developers on my team.

Yes, Martin does say you should prefer long, descriptive names over comments. However, he also advocates for the Single Responsibility Principle.

I've seen SRP defined a few ways, usually "a class or method should only have one reason to change", or "a class or method should do only one thing".

So, I tell my developers to write very descriptive names. I also frequently tell them that if the name of the method is getting too long, it is probably doing too many things.

If the name of the method is becoming unmanageable, consider if something needs refactoring.

I also tell my team to avoid the Incredibles Pattern. As we learned from Syndrome, "when everybody's special, nobody's special."

If every property or method of you class starts or ends with the same word(s), you can probably omit that word.

Assuming these are both members of one class, would the following make sense?

It looks like you have many PageReloaders, so we make a base class for the things all PageReloaders do.

abstract class PageReloader {
    //page reloader code
}

Next, the name indicates that being "used in the editor" is significant, so there must be other kinds of VectorGraphicsReloaders.

abstract class VectorGraphicsReloader : PageReloader{
    //vector graphics code
}

Finally, we get to the EditorGraphicsReloader, which is a VectorGraphicsReloader that does something specifically for the editor.

class EditorGraphicsReloader : VectorGraphicsReloader{
    //editor code
}

Within one of these class we should have two properties:

public string Comments { get; set; }
public string Description { get; set; }

The class these properties belong to depends on whether they are unique to the editor, vector graphics, or common to all page reloaders.

SouthShoreAK
  • 340
  • 1
  • 4
  • The link between names and SRP is really important here I think! I often tell my colleagues (and myself) "if you're struggling to come up with a name for something, maybe it's not a single thing". – IMSoP May 01 '20 at 22:01
  • I think that this was a nice try to map the complexity to the class structure, but in your example you changed the meaning to a less complex one. I still think that yours is still the best solution, to refactor the class, instead of using a long name. – TomatenSalat May 06 '20 at 07:15
16

There is always a balance to be struck. Usually when software pundits speak, they are addressing a commonly understood problem of their time and place.

If names are so non-descript and enigmatic that they require explanation - like using f, g, and h, as the parameters of a method - then in the first place these should be elongated and made more descriptive.

There was a period when it was considered a significant problem for programmers to be habitually using overly-short names (often a random letter), and things would be radically improved simply by using a descriptive word or two.

Nowadays, the opposite problem is often observed. Programmers using unnecessarily verbose names, often a mangling of highly general terminology that is not especially descriptive of anything.

An example of the latter which most recently caught my eye was "ApplicationServices" - I couldn't immediately see how this was more descriptive than "ProgramTools", "CodeStuff" or even "AppSvcs".

"VectorGraphics" could arguably be reduced to "LineArt" without any loss of meaning, but even the abbreviation "VectGfx" would probably be quite enough.

So the principle of making names descriptive should not be read as meaning make names as long as possible. It's about using names that contain a high information density.

An element of that still involves being economical with syllables and characters, and relying on implied knowledge, such as a good command of the English language, and familiarity with general computer concepts.

Steve
  • 6,998
  • 1
  • 14
  • 24
  • 6
    what does Gfx stand for? Graphic effects? Global effects? Isn't that "cute"? – TomatenSalat Apr 30 '20 at 06:58
  • 8
    I think you'll be hard-pressed to find a programmer who would think Gfx stands for "global effects". – John Go-Soco Apr 30 '20 at 07:30
  • @TonatenSalat, it's a contraction of "graphics", with the "f" in place of "ph" and "x" in place of "cs". It's an abbreviation that most people seem to infer readily in contexts where graphics are concerned. And as I say there are many reasonable alternatives. – Steve Apr 30 '20 at 09:46
  • 7
    @Steve why invent new words that not all people would understand when there are already existing ones that describe the real thing with 100% certainty? Imagine it was your first day at work and you have never done anything with Graphics. Using abbreviations just burns money. – TomatenSalat Apr 30 '20 at 11:43
  • 3
    I didn't think it stood for "global effects" but I wouldn't have guessed "graphics" either – matt freake Apr 30 '20 at 12:12
  • 1
    @TomatenSalat, why invent new names? Because 70 characters is too long, it's as simple as that. – Steve Apr 30 '20 at 12:55
  • 1
    @MattFreake, it's not a question of whether you can guess it abstractly, it's a question of whether you can infer it both from an actual codebase where it is used and from a knowledge of computer graphics concepts, and then memorise and recall the abbreviation without difficulty. Bear in mind, this was only proposed as a means of shortening a name that would otherwise be over 70 characters. If the type name was "VectorGraphics" alone, then I would never shorten that type name further, although I might refer to a local variable of that type as "vg", provided the type name was also in scope. – Steve Apr 30 '20 at 13:03
  • @Steve "70 characters is too long" Too long for what? Who defined that arbitrary number? – TomatenSalat Apr 30 '20 at 13:13
  • 1
    @TomatenSalat, that's simply my judgment on the matter. If my identifiers were approaching even half that number, I'd be thinking about whether my code was properly organised, whether I was being excessively verbose, or whether the extreme subtleties meant it needed a system of supporting documentation. At 70 characters I'd regard that as simply untenable and engage in reanalysis. – Steve Apr 30 '20 at 13:48
  • 1
    My point was that gfx *to me" doesn't mean graphics, grfx would. And that's the problem with abbreviations, they are more specific to individuals. I think ApplicationServices isn't great, but AppSvcs made me think of VCS, the version-control system, so I'm not sure those saved characters are worth it – matt freake Apr 30 '20 at 14:06
  • @MattFreake, like I say, the question is not what these things make you think in the abstract (fwiw I agree that "gfx" is not something I'd associate naturally with "graphics", if I wasn't in a computing context dealing with something to do with graphics). The question is whether they amount to sensible abbreviations in their context. And why you've parsed "Svcs" as "VCS", apparently overlooking the significance of the capitalisation, I don't know. But perhaps it does reinforce that, in the absence of a dictionary with authority, nobody can agree on what is optimal. – Steve Apr 30 '20 at 14:21
  • Note that “graphics” is actually _shorter_ than “gfx”, when considering wetware processing time, in people to whom it is more familiar. Wetware can be trained to recognize “gfx” too, but training’s not free. Won’t anybody recognize the following word instantly, without having to actually read it? Supercalifragilisticexpialidocious. – Philippe-André Lorin Dec 02 '21 at 22:56
10

I agree with this answer https://softwareengineering.stackexchange.com/a/409460/262662 by Mike Nakis, but there's more.

Additionally, you can namespace and group some of this. such as

PageReloaders.EditorCommentsVector
PageReloaders.EditorDescriptionsVector

Then if you had more variables with equally long names, you could (only in short functions/blocks)...

Reloaders = Utilities.Reloaders.PageReloaders;
Reloaders.EdtiorCommentsVector.doSomething(); // small scope only.
// equivalent to...
Utilities.Reloaders.PageReloaders.EdtiorCommentsVector.doSomething();

// And with prettier, so long as the segments are within about 40 characters, it doesn't matter.  As it will look like this:
ReallyLongPath
  .filledWithLongStrings
  .JustToGetTo
  .Utilities
  .Reloaders
  .PageReloaders
  .EditorCommentsVector
  .doSomething();

Update

If I had to actually come up with my own names, based on the original, instead of Naki's answer, I would use the following.

PageReloaders.VectorGraphicsPages.EditorComments
PageReloaders.VectorGraphicsPages.EditorDescriptions

Or maybe

PageReloaders.EditorComments.WithVectorGraphics
PageReloaders.EditorDescriptions.WithVectorGraphics

But honestly, it depends on how much stuff you've got going on. If you really need a different pageReloader for editorComments vs editorDescriptions, or a different pageReloader for vectorGraphics pages vs normal? pages vs plainText pages, then you gotta do what you gotta do. If you don't have that much stuff, like if any page might or might not have vector graphics, just go with PageReloaders.EditorComments. Do NOT be afraid to change your variable names as a project grows. And Do NOT use stuff like pgrldr.VGraph.EtrCmnt to try to get shorter variable names. Just don't do it. The goal is to lower the amount of brain strain on future developers (including yourself) when trying to figure out what you did the first time around.

End Update

I believe what Robert C. Martin was actually referring to was the following:

<!-- We actually had this in our codebase -->
<button class="btn-submit pers pers_cp"></btnbutton

<!-- What it meant, using the Clean Code standards -->
<button class="btn-submit btn-personnel_module btn-copy_action"></button> 

This button got copied/pasted across all the modules and to actions that were not copy. When writing css, people did not know what the classes meant, so they used those classes for sizing, instead of just colors. It was hell to detangle it.

This also applies to for loops. What is better...? (again, actually pulled from our codebase)

for (let k=0; k < vehsAr.length; k++) {
  let vehs = vehsAr[k];
}
/*---- OR -----*/
for (let vehicleIndex=0; vehicleIndex < vehiclesArray.length; vehicleIndex++) {
  let vehicle = vehiclesArray[vehicleIndex];
}

With the for(i) loop, if I decided to change the nesting level, I would end up reusing i and then having to shift everything inside to k. If I instead actually used descriptive variables, there is less work to do. A little effort goes a long ways.

for (let r = 0; r < width; r++) {
  for (let c = 0; c < height; c++) {
    grid[r][c].doSomething();
    // I see immediately that rows is the first layer, and columns is the second layer.
    // "row" and "column" is better than "r" and "c", but "r" and "c" still go a long ways.
    invertedGrid[c][r].doSomething(); // If it goes in natural English reading order, I only have to check in one spot that r and c are backwards.
  }
}
// Invert the nesting order
for (let c = 0; c < height; c++) {
  for (let r = 0; r < width; r++) {
    grid[r][c].doSomething();
    invertedGrid[c][r].doSomething();
    // Notice how the inner formulas don't change?
    // If I used 'i' and 'k', convention is that 'i' is top layer, then 'j', then 'k', then 'l' which looks like '1'.  It get messy.
    // If I swapped height/width while using 'i' and 'k', I'd have to put in much more brain power to make sure height matched with the right letter and that letter matched with the right spot.

  }
}

Update Using i j and k in for loops is perfectly acceptable and is the most common way to write a loop. But the Clean Code standard, based on what little I've read of it, does not like it. At all. Just like Prettier 1.0 hated trailing commas and Prettier 2.0 loves trailing commas. It's a standard. It has a reason behind it. It's not the only way. But using longer/more descriptive variable names is the standards directive being examined here.

  • I *don't* object to vehicleIndex, but i, j, and k are widely accepted (tradition, from limitations in Fortran) - there is often the expectation of the loop variable named that way. There redundancy (3 times) in `let vehicle = vehiclesArray[vehicleIndex];`. If I index into an array and get a vehicle (`let vehicle = `) that should be sufficient. – Peter Mortensen Apr 29 '20 at 22:37
  • 2
    `PageReloaders.EditorCommentsVector` the information that it is about vector graphics would be lost there. Vector could also be understood in a mathematical sense as an array of numbers or in a C++ sense as an ArrayList. – TomatenSalat Apr 30 '20 at 06:30
  • @PeterMortensen It was the mathematical tradition of using i,j,k and sometimes l,m,n as throwaway indices (e.g. in Einstein notation) that is why Fortran is like that. Fortran merely popularized it. – richardb Apr 30 '20 at 06:30
  • I also agree that `i` as an iteration variable is an accepted pattern in simple loops. I might resort to `idx_vehicle` only if the logic within the loop is complex or if multiple indexes are in play. – Steve Apr 30 '20 at 14:09
  • `i` as an index is an acceptable pattern. I 100% agree. However, this question was about a different set of standards that has developed beyond what is merely "widely acceptable". Rather, this question is "what does this specific standard actually mean when it says this" – RoboticRenaissance May 01 '20 at 22:32
7

What I would take away from this is when you have items like:

PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorComments
PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorDescriptions

then what you're lacking is context, that you have too many top-level items that deserve to be grouped together in a logical way, and that that grouping provides context. While this is an extreme example, perhaps it could be refactored as:

Comments.Editor.Page.Reloader
Descriptions.Editor.Page.Reloader

(or maybe Page.Comments.Editor.Reloader, whatever!) where the information about whether the page displays vector graphics or not is part of the type of the page, or even the reloader.

Variable names don't exist in isolation, they sit within the context of other objects, and have types, all of these contribute to understanding.

If you have a name that is getting too long, consider whether the variable itself is carrying too much burden.

  • 1
    In a big project, I would have 20 Reloaders in a scope. Everytime I used one I would need to specify the correct namespace of the reloader. A lot of information was lost by your refactoring. Where should you put this now missing information then? Inside a comment? – TomatenSalat Apr 30 '20 at 08:46
  • 3
    I came to say something similar. Whenever a word is redundant *within the current context* it does not belong in a name. A frighteningly common example of this is putting the name of a system in names *inside* the system, where they are almost always redundant. – l0b0 Apr 30 '20 at 10:22
  • 3
    @TomatenSalat - well, that's a badly organized project. The principles of abstraction and information hiding don't just serve to insulate classes from each other, they help *you* work with your code without going into the specific details of everything. The information is not lost, it's just scoped and contextualized - you don't *need or want* to have all the information thrown in the same place. Instead, you'd have something like code that works with reloaders without knowing what specific reloaders they are. Then the names just need to express concepts relevant to that context/responsibility – Filip Milovanović Apr 30 '20 at 19:02
4

Don't forget that part of the audience of that book are older programmers who cut their teeth on old compilers that had very short name length limits. The first C language standard only required compilers to treat the first six characters of externally-visible identifiers as significant (C89 spec section 3.1.2). The functions and types in the C standard library have extremely terse names, sometimes to the point where they can confuse the unfamiliar.

I've always interpreted Martin's advice as more of a condemnation of the old habits that treat horizontal screen space as something that should be taken into consideration. Modern compilers don't really care about name lengths, and programmers (for the most part) aren't writing code on a console that's limited to 80 columns. The advantages of plainly readable names far outweighs any benefits that you get from short (or overly-long) names.

For example, the C standard library has a function called mbstowcs(). Can you tell what that function does? Me neither. Martin is saying that compressed names like that don't hold much value. If instead the function was named ConvertMultibyteStringToWchar(), you could probably make sense out of code that uses it without having to dig through documentation.

This is certainly not a replacement for comments. Comments record all sorts of additional information, like whether the caller has to free the memory returned by the function, what exceptions the function can throw, whether the function is thread-safe, etc. Comments also record things like why the function is implemented the way that it is. This is all information that you can't reasonably stuff into a name, regardless of how long you make it.

I think the only case where longer names can replace comments is in cases like this:

// tokenize a string
char *strtok(char *s1, const char *s2)
{
    ...
}

But if that's all the information that you're documenting about a function, names aren't your #1 problem.

bta
  • 1,003
  • 6
  • 12
  • A quality compiler will support external symbols of whatever length the linker supports. If a linker happens to use six-character symbols, any compiler targeting that linker will either have to limit programs to six characters or provide a means for programmers to specify a linker name separate from the C identifier name. Personally, I would have liked to see the Standard recommend a syntax for the latter to facilitate interop with languages whose rules for identifiers differ from those in C [e.g. that may require identifier that contain dollar signs or other such characters]. – supercat May 01 '20 at 21:20
  • @supercat I wasn't talking about quality compilers, I was talking about compilers from before C was standardized. But yes, I definitely agree that the desire for compatibility with those early compilers left some junk in the standard that could have been done much better. – bta May 03 '20 at 18:40
  • If the Standard had recognized the concepts of C implementations that run code directly, produce linkable object code, or produce executable code for use by some execution engine, then it could have allowed for the possibility that language constructs may be limited by the target linker or execution environment. As an example, on Classic Macintosh, many applications could support plug-ins written in C or Pascal, but such plug-ins were not allowed to use *any* objects of static duration. If the C Standard recognized the concept of execution environments, it could say that a conforming... – supercat May 03 '20 at 18:46
  • ...implementation for an environment that supports static objects should let programmers declare them, but an implementation may target a platform which can't support them if it rejects code containing such declarations. If some particular linker only supports five-character symbols, a C implementation that supports that linker but limits export symbols to five characters may be more useful than one that allows six-character symbols but can't support that linker. – supercat May 03 '20 at 18:48
2

Commenting is inherently dangerous.

  • Use it sparingly for // fixmes

Why dangerous?

  • Code comes and go, but comments are always left behind.
  • People fear deleting comments, because they assume it to be vital true information.
  • Try understanding code with vital FALSE information.

I consider bad commenting, one of the deepest layers in Programming hell.

A function name [for example] however, is less likely to become inaccurate as you change things within it, and if its functionality does change, you are naturally more likely to change the name of it as well.

This is one fundamental but important reason why a long name is preferable over commenting, and why it will lead to cleaner code.

Anon
  • 3,565
  • 3
  • 27
  • 45
  • 2
    I'm not convinced by the assertion that function names are more likely to keep track of reality than comments. I've seen plenty of functions whose behaviour is completely at odds with their name, because developers were too afraid of the impact of renaming. In some cases, you _can't_ rename a function, because it's part of a stable library contract, whereas I've yet to see a case where you _can't_ edit a comment once you realise it's wrong. – IMSoP May 15 '20 at 09:36
  • 1
    @IMSoP, I think to be fair to him, his emphasis is that comments will either be overlooked for maintenance, or that subsequent maintenance developers are often unsure how to evaluate their accuracy or truthfulness. Since the placement and conceptual content of comments often does not conform to any structure, and are not subject to tests, the *reliability* of comments may be highly questionable. – Steve May 15 '20 at 10:44
  • @Steve Everything you just said applies to function names too; they don't mean anything to the compiler or the testing framework, it needs a developer to think about what they mean in human language and decide if they're still correct or not. – IMSoP May 15 '20 at 11:30
  • @IMSoP, potentially so. It's a difficult issue because I don't agree with him that names should basically be turned into comments (so I don't agree with his proposed solution), but I do agree that comments are prone to be crufty (his description of the problem). If names are more likely to track reality, then in my view this is because they are short, and usually subject to considered design and review, whereas comments are often vague and unstructured expressions of individual developers' thoughts. – Steve May 15 '20 at 12:49
  • 1
    @Steve Yes, I think that's a reasonable way of putting it. As I commented under [another answer](https://softwareengineering.stackexchange.com/a/409486/96713), it's no good just converting your comment into a name and saying you're done, you've got to address why the code is so complex that you need a long name or comment in the first place. – IMSoP May 15 '20 at 13:16
1

I would like to ignore commenting classes and data structures, because I think that's fine and usually we are more concerned about comments in actual code.

One of the things Uncle Bob does is make his comments a horribly offensive bright red. Not the nice pleasant colors they usually are. This is because he feels that if you have to have a comment in the code it better be worth the horrendous color. If it's worth the offensiveness he leaves it if it isn't he deletes it.

So Uncle Bob does believe that comments should be avoided, but in my mind this is in conflict with another one of this clean coding rules. The rule that the length of a variable name should be proportional to it's scope. So global variables should have long names and local variables should have small names.

For example In one of my functions there was a variable name ip with a comment which shoved in to variable name and I got hostname_or_dotted_decimal_ip. So this eliminated a comment, but then it made the variable unnecessarily long.

I've asked Uncle Bob previously specifically about long variable names in local scopes and his comment was as follows "long variables names in small scopes is obnoxious." I personally think having a somewhat lengthy variable name to kill off a comment is an ok sacrifice given it doesn't make the code obnoxious. If that variable was used 10 times it would probably be obnoxious.

One thing that should be avoided at all cost is hiding the meaningful parts of things at the end of the line. I'm a C developer with zero namespacing and I've never had any function, data structure or variable that long.

PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorComments PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorDescriptions

But if by some force of nature I had to have an abomination like those two things in my code. I would move the difference to the front.

CommentsOfPageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditor DescriptionsOfPageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditor

This principle is covered by Kelvin Henney in Seven Ineffective Coding Habits of Many Programmers Of course if you are in a language that has namespaces you should be using them to avoid insanity such as this.

f3xy
  • 119
  • 4
  • 1
    Is this answer meant to be sarcastic? – Peter Mortensen Apr 29 '20 at 22:28
  • 2
    I was wondering that too. "I set up my IDE to play an air-horn noise whenever I type 'class', and now I agree that Java is too verbose" – Errorsatz Apr 29 '20 at 22:30
  • 2
    I've edited my answer. I'm not entirely sure what was originally sarcastic about it. Some feedback as to why you thought that would be nice. Hopefully this answer does not come off as sarcastic. I'm a fan of Dan Saks who says if you are arguing you're losing. – f3xy Apr 30 '20 at 02:04
  • Surely Rosa Parks was losing then... – kukis Apr 30 '20 at 08:06
  • 1
    Um, I think you're missing a concept here. You've got a variable that stores "either a dotted IP address or a hostname". And your objection is that you can't refer to that easily by a single variable name. Variables are supposed to hold one thing. What is that one thing? Is it "ServerToConnectTo", "ClientAddress", etc? Because if it's "hostname or a dotted IP address", you're either using one variable for two things or you're thinking of your variable the wrong way. – Kevin May 01 '20 at 14:49
  • The variable is passed to *getaddrinfo* so maybe it contains two things. My main concern is eliminating the comment first. If someone can provide the variable semantics later that's great. – f3xy May 01 '20 at 18:18
  • 1
    I agree with Kevin, all you've done is encoded the comment as a variable name, rather than actually trying to eliminate the need for it. Choosing a more meaningful name isn't a separate concern to put off until later, it's the whole aim of the exercise. Indeed, eliminating the comment might need more than a variable name - should the variable be a stricter type, or more clearly validating against its expected format before use? What previous changes led a variable called `ip` to not always be an IP address, and have those changes actually been followed through properly? – IMSoP May 01 '20 at 21:55
-1

Make everything as simple as possible, but not simpler.

For a specific class in a big project, long names like these are perfectly fine as long as there is no easier way to express it:

PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorComments
PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorDescriptions

Just keep it stupid simple. Keep the name so obvious that everybody understands it.

Do not scarify descriptiveness for a short name!

If there was a maximum length for variable names, the compiler or IDE would not allow these. Nowadays most developers have 16:9 to 32:9 screens and modern computers have enough memory, so it is possible to choose class names that are much longer and more descriptive than the typical int i, VctGfx gf or VctrGfx vgf abbreviations. Short names like that stem from the old days or from physicists, mathematicians or Fortran developers, but this coding style has many disadvantages in the modern programming world. Object oriented programming is more like using a language than using maths. (Learning computer programming uses similar brain activations to learning a foreign language.) So what applies to language should also apply to programming: neologisms need to be defined when used.

When new developers come into a team, it is much easier for them to understand what a class does, when they do not have to debug through the code to learn that Vector is defined as VectorGraphics in that scope. Also if you have to edit the code after a year, you will find it much easier to understand, when you haven't invented new scope specific vocabulary whose definition is more implied than declared.

If the class has a very specific task, you force each developer to read it, which is annoying at first, but it pays out in the long run.

TomatenSalat
  • 732
  • 1
  • 5
  • 9
  • 9
    *"Modern computers ... can handle a long name"* - the problem is that *programmers* cannot work efficiently with names of 70 characters or more, and 20 or so syllables. They defy fast pronunciation (so they are inefficient for talking), and they defy visual shape recognition (so they are inefficient for reading). Remember the challenge here is to *name* things - even 'War and Peace' had a snappy name! – Steve Apr 30 '20 at 10:09
  • @Steve "talking about code". The most efficient way to talk about code is with the viewer sitting next to you or by sharing your screen. Talking about what the code looks like in your head is just a "map" of the reality and you could come to conclusions that are not possible or too complicated to implement. Talking about architecture is something different. – TomatenSalat Apr 30 '20 at 11:34
  • @Steve Your brain is capable of more things than you might expect. Yuo're Albe to Raed Tihs. When you know what the class does you do not even have to read its whole name anymore. You just see it, similar as a Chinese character, that can have up to 50 strokes, as what it stands for. So much about visual shape recognition. I would go even further and say when all class names have a similar length, it is harder to distinguish them quickly. – TomatenSalat Apr 30 '20 at 11:35
  • 3
    *"When you know what the class does you do not even have to read its whole name anymore."* - I'm afraid I'm inclined to disagree. Not only do names obviously have to be re-read, but they also form part of the visual clutter that has to be navigated overall. I think even you'd accept that a 1,000 character name was too long - that at some point, length manifests itself as a problem. Offhand, I'd say that the limit is around 20 chars. Perhaps 30 or 40 chars max if a justifiable system of prefixes and underscores to separate words is employed. Never 70. – Steve Apr 30 '20 at 12:53
  • Who says that a certain number is too long? I cannot agree on setting an arbitrary limit. The only limit is the file size of the OS. When the Project has a complexity that requires a long name, then even a ridiculously long name is fine for me. Also have a look at Unit Tests naming conventions. They are often much longer than 70 characters. – TomatenSalat Apr 30 '20 at 13:16
  • 2
    the limit does not need to be arbitrary in the sense of being a diktat that a programmer can never override for good reason. But if the length of the names arises from the inherent complexity, I'd be questioning whether that complexity can't be managed in any other way, or whether the project itself is too complex to be commercially sensible. Unit tests are a different beast I will agree. – Steve Apr 30 '20 at 13:59
  • 2
    @TomatenSalat "When the Project has a complexity that requires a long name, then even a ridiculously long name is fine". If you have a variable / function / class for which the purpose is so complex that you need an excessively long name, then it's probably a candidate for refactoring. Personally I find the two examples you've given in this answer to be utterly unreadable. I'd have to pause and read and re-read it a couple of times to figure out what is going on. – Jon Bentley May 01 '20 at 09:38
  • @JonBentley " I'd have to pause and read and re-read it a couple of times to figure out what is going on" That is exactly what it is supposed to do, so you can understand the complexity. – TomatenSalat May 04 '20 at 06:39
  • @TomatenSalat As I said, if you have such complexity, then you should reduce the complexity by refactoring. Complexity resulting in names that scroll off the edge of the screen is nearly always a code smell. – Jon Bentley May 04 '20 at 06:42
  • @JonBentley Not for all refactoring exists enough time. Especially in legacy code. The right question to ask would than be: Which code smell is worse, too long or too generic variable names. – TomatenSalat May 04 '20 at 06:44
  • @TomatenSalat When we discuss clean code concepts, we are not talking about legacy code for obvious reasons (unless refactoring it), so it's a moot point. As for fresh code, my point about refactoring was just to illustrate. In reality you would never write such badly factored code in the first place. The first refactoring takes place in your head before you touch the keyboard. If your 1st thought is "I need a function called PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorComments" then your 2nd thought is "surely there is a better way". – Jon Bentley May 04 '20 at 06:49
  • @JonBentley also with fresh code, when a class that does a specific thing has only a few lines of code. then it is not reasonable to split it up into even more classes, just to reduce the name length, since it would decrease comprehensibility. – TomatenSalat May 05 '20 at 08:30
  • @JonBentley "surely there is a better way" can you define, what you mean by better? shorter and less descriptive? – TomatenSalat May 12 '20 at 09:19
  • @TomatenSalat Better as in refactored so that you don't have such complexity residing in a single variable/function/class – Jon Bentley May 12 '20 at 09:22
  • @TomatenSalat For example PageReloader(VectorGraphics = true, EditorComments = true), or subclassing, etc. – Jon Bentley May 12 '20 at 09:24
  • a clear text description would be: reloading pages containing vector graphics, but only then, when those vector graphics are also displayed in the descriptions of an editor. any reordering of the class so that the read text would not change the meaning and it would be still understandable i think would be better for non legacy code, if the complexity of the class structure would not make it less descriptive. – TomatenSalat May 12 '20 at 11:25