15 ms·
How to Write Unmaintainable Code (2017)
- newsbinator 8y ago> Consider this real world example: a_crszkvc30LastNameCol. > It took a team of maintenance engineers nearly 3 days to figure out that this whopper variable name described a const, reference, function argument that was holding information from a database column of type Varchar[30] named "LastName" which was part of the table's primary key.
- vntok 8y agoThat's insane, what could those 3 engineers possibly be doing for 3 days? - const, reference and function argument should be pretty obvious from the code context - LastNameCol seems like self-describing... of course you would have to know that you're debugging an application that talks to databases, but eh
- marcinzm 8y agoMost likely tracking down what originally populated the variable and how it's used. I'm assuming the code base was large and spaghetti like. I'd say it's somewhat akin to proving a negative. Sure you get that it's a const, reference and function argument which likely refers to the Last Name Column. However is that all it is? Or is there more meaning in the name? Meaning that could be crucial to understanding how the application functions? Does one of the characters mean function reference or does it refer to something else? Apparently not in this case but how can you know without investigating?
- wild_preference 8y agoSpending time to understand the author’s intent of some code is one of the hardest parts of reading code. It’s like when you find a nil-guard in a function. You can’t truly refactor it until you know whether it was added defensively just-in-case or whether nils can still exist in the system at the function’s callsite, calling for further upstream examination. There’s a certain hell in trying to follow a code base where every function is infected with ‘if (!arg) return’.
- AgentME 8y agoAfter dealing with code absolutely plagued with that pattern, languages with non-nullable types are amazing (Flow, Typescript in strict mode, Kotlin, Rust, ...) and I don't think I'm ever going to voluntarily switch away from them now.
- ppeetteerr 8y agoc30 appears to identify the size of the column. If you put structure in your variable name, your PR is not going through. ;)
- retSava 8y agoWell, since the repo more or less took the contents verbatim from the original author (unless they are the same), and here presents it _more_ clearly than the original, I'd say the repo owner failed. At the very least it should be presented in a more unmaintainable way. Edit, apparently repo owner already checked with author: https://github.com/Droogans/unmaintainable-code/issues/3 https://github.com/Droogans/unmaintainable-code/issues/3 :+1:
- detaro 8y agoInteresting, I find the one long document less clear then the original that's categorized in subpages.
- jaclaz 8y agoAs a side note, the "opening" quote attributed to Napoleon, seemingly isn't: https://quoteinvestigator.com/2016/12/30/not-malice/ https://quoteinvestigator.com/2016/12/30/not-malice/ I can offer as corollary to the article a couple of unmaintainable simple batches: http://reboot.pro/topic/2986-yacbfc-dec2hexcmd-and-hex2deccmd/?p=204425 http://reboot.pro/topic/2986-yacbfc-dec2hexcmd-and-hex2deccm...
- jacobush 8y agoJust another level of obfuscation
- baud147258 8y ago> Quidquid latine dictum sit, altum sonatur. - Whatever is said in Latin sounds profound. This one is good and there's no attribution problem.
- tegansnyder 8y agoNow whenever someone criticizes my old code I can point them to this and say it could be worse.
- hashrate 8y agoThis is suppose to be funny , unfortunately this is the sad reality of what you'll find in 90% of Enterprise / Startups environment as well as THE majority of open source repositories of popular open source projects. I've noticed this especially true for JavaScript and Go. In JavaScript , because the language is still evolving and there is no real standard about how to architect code with this language unless you are using a entire "platform" like Angular / Vue / React witch will highly influence your coding style. In Go because Go developers are performances obsessed , coming from C/C++ background and do believe that naming their variable with one letter will save 1GB of memory allocation , 1000 CPU Cycles and make their code "Clear and Concise" Ultimately , because there is very little standard in this industry in terms of code governance and a large percentage of projects are outsourced to other companies , we end up with what is described in this repository.
- kthejoker2 8y agoAgree. But as a postscript this is really funny and well written.
- deleted 8y ago[deleted]
- dawkins 8y agoIn Go single letter variables are used when they are short lived (3 or 4 lines) and in this cases I find it way more readable than long names.
- deleted 8y ago[deleted]
- hhmc 8y agoIt's also perfectly acceptable (and preferred) if the code maps cleanly onto some existing mathematical terminology. 'v' is more readable than 'velocity' in the correct context.
- nerdponx 8y agoHow is this any "easier to share"?
- davemp 8y agoThis version is certainly much more readable for me than the older intrusive ad ridden, click farming version.
- roland35 8y agoFor embedded C work I do like to mark global variables with a Hungarian g_, all other prefixes are generally handled pretty well by the IDE's type hinting. Other than that I agree Hungarian can go!
- joeblau 8y agoI had a funny now/frustrating then story where I worked with his guy who named five variables in a class a, aa, aaa, aaaa, aaaaa. I was trying to refactor his code and I had no idea what anything did. The company is out of business now, but it was definitely unmaintainable.
- jgh 8y agohahah so glad Hungarian notation was included.
- bausshf 8y ago"Hungarian Notation is the tactical nuclear weapon of source code obfuscation techniques; use it!" - I'm laughing so hard. This whole article is genius.
- bausshf 8y agoAlso "Be polite, Never Assert Avoid the assert() mechanism, because it could turn a three-day debug fest into a ten minute one."
- tribesman 8y ago"Hungarian Notation is the tactical flesh light of source code obfuscation offering max pleasure; use it!"
- zbentley 8y ago> In C, functions are supposed to be idempotent, (without side effects). What is meant by that statement? Is "idempotent" a mistype/mistakenly selected word? If the author meant "pure" instead, should I file a PR, or consider this some sort of meta-meta-obfuscation? If the author meant "pure", is that actually true of C specifically, or just generally good programming advice (localize side effects to known locations, the fewer the better, don't sprinkle them all over and document where they occur)?
- badlukk 8y agoC functions shouldn't change behavior based on state, they do the same thing every time. Instead of changing a particular global variable, any variable of that type should be passed in and changed, then returned. It's good programming advice for functional languages. In OO it makes sense to make state changes in object methods, but not usually the best functional approach.
- marcosdumay 8y agoI think the author meant something like "they are supposed to be pure, so make them not idempotent".
- jokerx 8y agoCode tells "how." Comments tell "why."
- rofo1 8y agoIdempotent is concept borrowed from mathematics. It just means: f(f(x))=x assuming f is a function (binary operators are just functions (maps) in mathematics, too, e.g. +:NxN->N (read: "plus" is a map from the Cartesian product of N by N to N))
- ape4 8y agoI inherited some code with m_ prefixes on parameters to a function. eg theFunction(int m_param1) That should be a lint error.
- sseth 8y agoI had a colleague who used to use variable names from his local language in India (we were working in Europe at the time). So hwndParent would become hwndBaap. This combines both the hungarian and the local language strategies for job security. Fortunately, he stopped programming and became very successful in agriculture. Good outcome for both fields.
- magicnubs 8y ago> Good outcome for both fields. Well that is what agriculture is all about.
- nathell 8y agoThis is much older than 2017; the version at http://mindprod.com/jgloss/unmain.html http://mindprod.com/jgloss/unmain.html dates back to 2000.
- ppeetteerr 8y agoAny time I read C/C++ code, I am under the impression it was written to be illegible. I realize that with time, functions like `malloc` become second nature, but why not call it `allocate_memory`? (bash suffers from this too) It's even worse when reading the source code of old video games due to the abstract nature of the operations being performed on virtual representations of visual elements. The argument of time constraints when authoring doesn't hold much value. Java is verbose AF but it's also one of the most used languages. Second, most code is read, not written and should be written to be read by others, not just the author. There may be a reason to be terse due to time constraints and lack of IDEs/autocomplete or memory constraints or w/e, but the need to shorten variables names and functions today only serves the whims of the author, not the 10+ future readers. tinyrant :D
- jghn 8y agoThere was a time where visual and actual compactness was important. So for instance things like `malloc` date to that era. I'd argue that changing it to `allocate_memory` now would be even more confusing than leaving it as `malloc`
- ppeetteerr 8y agoI fully agree. This reminds me of how some text books will teach people to write `a = 10` rather than `age = 10` for the sake of brevity. From that moment on, it becomes a habit to write code in a terse manner. It took me a few years and some good IDEs to no longer be afraid of names like `ageOfUser`/`age_of_user`.
- jghn 8y agoHopefully not modern textbooks. I know when I was in my CS program in the early 90s it seemed like that was transitioning. The older profs would teach us every trick in the book to reduce the actual file size & visual noise in our code. The younger profs would beat in our head to not do that.
- hinkley 8y ago
- bausshf 8y agoI have an addition to writing unmaintainable code. Only have one struct with a member of every type. That one struct will be the type of every variable you have. If the language you use support implicit operator overload abuse them to make sure all types can be implicitly converted to each other. Ex. struct Variable { byte a; short c; int d; long e; ... } This will make it impossible to know what type a variable is until you find its assignment, which of course isn't on the same line as the declaration and even better reuse the same variable for multiple values.
- evozer 8y agoIf you want to be more efficient, you can also use a union for this. typedef union { int i; float f; double d; long l; char c; void *p; ... } var; Now you might also get some nice float-interpreted-as-int bugs if you forget the type! You can also kind of pretend that you have C#-style type inference: var x = { .i = 10 }; var y = { .f = 2.0f };
- bausshf 8y agoBut you don't want to be efficient lmfao
- scarface74 8y agoYou’ve just describe the variant type in COM....
- wolfgang42 8y ago> The design doc should break the algorithm down into a hierarchy of structured steps, described in a hierarchy of auto-numbered individual paragraphs in the document. > then... (and this is the kicker) when you write the code, for each of these paragraphs you write a corresponding global function named: > Act1_2_4_6_3_13() > Do not document these functions. After all, that's what the design document is for! Ideally, your company will also have several file shares into which old and unidentifiable documents are filed, in nested layers of folders named things like "Old documents", "John's Code", "Please Clean Up", and "Maybe Delete". However, for maximum effectiveness do not file your design documents here! Instead, put various old drafts (not identified as such, of course) in a folder on the server where your code used to run, somewhere like C:\backups\aurdbcl1\C\Documents and Settings\users\jdoe\Desktop\ (where aurdbcl1 is the name of the server where your program ran 20 years ago). This will ensure that they will spend as long of a time as possible hunting for something that could be useful. If possible, also ensure that there are some multi-Gigabyte zip files scattered about which have to be unpacked just in case there's something useful inside. A related technique for compiled languages is to arrange for various copies of the source code to be copied into similarly diverse locations. Do not use version control under any circumstances; if you must, check in at most once a month with the comment "changed code". This works best for a program which is maintained very rarely. Anyone attempting to fix it will first have to identify which copy of the source code is the right one. Make sure you also have some copies that never made it to production, where you started changing things and never finished. If possible, the production version should also be subtly different from all copies of the source code that can be found. (The above is, unfortunately, from experience. I have many other rants which similarly belong in this document, particularly around exception handling and copy-pating, but I feel that this comment is becoming too long already.)
- jackhack 8y agoAn approach from one of my early employment experiences (1980s): 1. Write a CAD system. User-facing code in BASIC. Rendering engine written in assembly. 2. Run the interpreted BASIC code through an optimizer, which condensed all variable and function names to be as short as possible (one or two characters) and moved frequently-used routines to the top of the module before compiling it all into one executable chunk (no more interpreter). This optimized code is almost unreadable but executes a lot faster (25%-50%) than the human-readable interpreted code. Hurray! 3. Lose the original source code. Build machine's hard drive died. The backups weren't. No version control -- only occasional snapshots. Source code that was on various floppy disks lying around the office was incomplete and badly outdated (like the "Old Documents/John's Code example, above). 4. Team panics and spends a month trying to piece "Humpty Dumpty" (the software) back together again. No luck. 5. Spend the next year trying to reconstruct function and variable names from "AA423()" and "aa_237" to such gems as "customerListIThink", "doesSomethingToInventory()", "NoIdea()", "BreaksWhenIChangeIt()" while struggling to add new features at 1/10th the rate before the loss. 6. Try to rewrite the whole thing in C. 7. Go out of business. True story.
- mirekrusin 8y agoOne of the longest jokes I've seen.
- Yokohiii 8y agoI actually like using short variable names. Using "i" as an index variable has been widely accepted. It saves a lot of typing, the use case is clear and it is usually tied the a block which is visually identifiable. I carry over the same principles to functions/methods. Functions are usually less than a screen which makes it rather easy to pick up the context and understand the program flow and the use of variables. I use "list" if there is there is a single list. The context usually defines what is in there. Maybe the function name, the type declarations or the fact that we are in a part of code handling lists of customers. How hard is it to guess what countCustomers(list) or incrementCustomersScore(list, n) is doing? Writing incrementCustomersScore(goodCustomerList, customerScoreDelta) is just redundant. Variable names just need to be descriptive enough to define their role within it's context. If the function is very small, the variable names can be very short. Local variables are the smallest named things in our systems, whith a very small scope, there shouldn't be an excessive naming cult around it. Give advice how to properly name projects, packages, namespaces and classes and I start listening. We are really bad at this.
- Huggernaut 8y agoI'd suggest that `count(customers)` or `incrementScore(goodCustomers, delta)` are shorter, more readable, don't embed type information in the variable name (e.g. what happens if you realise your customers are actually a set, not a list), and don't end up embedding type information in your function name (e.g. what if I want to count employees). Also, by not including semantic information in the variable, it also requires this to be conveyed everywhere else e.g. your function names. You rightly point out that hopefully there's tight context around this thing (e.g. it's only about customers) and maybe you can leave that out, but over time as code changes and grows in weird ways, this may not always hold. What do you think?
- Yokohiii 8y agoEmbedding types in the method names is a habit of using dynamically typed languages. If the method is private it can be shorter, if it is public it should be a bit more descriptive. With statically typed languages I'd agree with your suggestion, but i'd likely would remove the type info from variables as well.
- phakding 8y agoWhat incenses me is this recent notion that because programmers fail to change comment with the code change, they shouldn't even write comments. They should instead write the self-documenting code. This doesn't make sense on so many levels. Only a recluse sitting in some dungeon who never dealt with people can come up with something so inane. Edit: I understand that that every developer should aspire to become someone who writes code that reads like a children's book, and they should. However, actively discouraging writing comments is so wrong on so many levels. At the last place I worked, we used to have a small at-home coding test before interview and none of the young developers who successfully completed the test did any sort of code documentation or commenting. When I asked why, they would tell me that their code is self-documenting, which was utter nonsense.
- emodendroket 8y agoObviously code is never entirely self-documenting, but I think the idea is that, given the choice between something obscure with comments and something obvious on its face, you should prefer the latter unless there is some compelling rationale not to.
- phakding 8y agoI understand that that every developer should aspire to become someone who writes code that reads like a children's book, and they should. However, actively discouraging writing comments is so wrong on so many levels. At the last place I worked, we used to have a small at-home coding test before interview and none of the young developers who successfully completed the test did any sort of code documentation or commenting. When I asked why, they would tell me that their code is self-documenting, which was utter nonsense.
- emodendroket 8y agoWell, this is a classic problem with people taking a guideline and applying an extreme version without understanding the rationale. I had a meeting one time where someone suggested that a code review went much easier when the submitter used remarks on the PR to explain what it did, and I suggested that if they were helpful during review they'd be helpful later, so just using comments would be better. He replied to me that that didn't make sense because comments are a code smell (a term I've kind of come to detest).
- rajadigopula 8y agoA much novel way - use functional programming and create higher order functions and purely mathematical combinatoric functions and compose them in a complex way. A normal day developer must go to college again to even getting closer to understand it. This way the code is highly functional and there won't be a compromise in the quality of the output!
- FrozenVoid 8y agoThats what i actually use with C macros, except its intentional and saves lots of typing: however you must know some macro trickery to understand how it even works.
- a_imho 8y agoSurprisingly light on multithreading and version control best practices.
- coolaliasbro 8y agoAs a creative process, and in the interest of compassion, I tend to name everything as humanly readable as possible, and provide voluminous documentation in production systems. Even quick-and-dirty things tend to get moved to production if they work, so I increasingly apply the same approach to them, as the "this will be tossed after x" sentiment has bitten me on the ass more than once.
- cessor 8y agoCould you elaborate what criteria you apply to decide whether something is "as humanly readable as possible"? I am asking out of genuine interest, I am researching readability and I am interested in how you make decisions and what criteria you apply. What means "readable" to you?
- emodendroket 8y agoThe comment section is particularly trenchant because I recently worked on a project that had hundreds of instances of the comment "// do this here"
- S-E-P 8y agoMy personal trick: Write a basic (not turing complete) brainfk compiler into your application and feed your business logic through that.
- bausshf 8y agoThe brainfk compiler should have reversed symbols. Ex. > will decrement the pointer, < will increment the pointer, + will subtract, - will add, . will read, , will read, ] start loop, [ end loop
- paulddraper 8y ago> a naming convention from the world of C++ is the use of m_ in front of members. This is supposed to help you tell them apart from methods, so long as you forget that "method" also starts with the letter "m". C++ has member variables (which this refers to) and member functions. "Method" is not part of the vernacular.
- gerdesj 8y agoDon't bother with all that documentation, get straight into the Stackoverflow example: https://github.com/Droogans/unmaintainable-code#a-real-life-example https://github.com/Droogans/unmaintainable-code#a-real-life-...
- ajss 8y agoAlong a similar line, I love Stuart Halloway's talk on Narcissistic Design - https://www.youtube.com/watch?v=LEZv-kQUSi4 https://www.youtube.com/watch?v=LEZv-kQUSi4 Prefer APIs over data. Start with DSLs. Always connect (and never enqueue). Create abstractions for information. Use static typing across subsystem boundaries. Put language semantics on the wire. Write lots of unit tests. Leverage context. Update information in place.
- Mc_Big_G 8y agoJust use perl.
- lizmat 8y agoDo you have any data to back up that claim? Or are you just propagating prejudice?
- Mc_Big_G 8y agoIt was a joke, take it easy. With that said, perl has a multitude of ways to shoot yourself in the foot and future maintainers in the face. Notably, the obscure tricks perl allows you to write that are difficult to read in the future but seem clever when you write them. I've written enough perl to know they exist but thankfully forgotten all of them so I can't give a good example. I just remember something about $_ being interesting at times.
- vgy7ujm 8y agoThen you don’t know enough about it.. now you are the joke.
- alexeiz 8y agoRecently I came across some code that checks quite a few boxes in this guide. Check it out: https://github.com/KxSystems/kdb/blob/master/c/c/k.h https://github.com/KxSystems/kdb/blob/master/c/c/k.h https://github.com/KxSystems/kdb/blob/master/c/c/odbc.c https://github.com/KxSystems/kdb/blob/master/c/c/odbc.c
- notamy 8y agoIt's written like it's APL (I think? iirc k is an APL-style language), so it actually makes some sense. To the way that the authors actually write code, I think it's perfectly legible, just not to outsiders.
- alexeiz 8y agoIsn't making code ineligible to outsiders an essential requirement for job security? And how much sense does it make to you? What can you tell about this code except for "it's written like APL?" Can you tell what it does? How it does that? What all those one letter functions/macros mean? No, you can't tell shit.
- pure-awesome 8y ago> Since global variables are "evil", define a structure to hold all the things you'd put in globals. Call it something clever like EverythingYoullEverNeed. Make all functions take a pointer to this structure (call it handle to confuse things more). This gives the impression that you're not using global variables, you're accessing everything through a "handle". Then declare one statically so that all the code is using the same copy anyway. I see this in practice WAY too often... Heck, I've been somewhat guilty of it myself before. (Bonus points if it's in a functional language :P )
- kevin_thibedeau 8y agoAnd it's perfectly valid on constrained systems where you don't have or want to make heavy use of malloc() and don't have namespaces. Provided the structs stay reasonably focused on one domain.
- pure-awesome 8y agoEmphasis on the "reasonably focused on one domain" part - it's when you're passing through your entire program state in one gigantic state object that things get messy. Also, I've been led to believe that design of constrained / embedded systems follow different rules. Your code can be unreadably complex if you have to squeeze out that extra performance (however, even then, it should probably be well-commented or well-documented), and generally (though not alway) such programs will be smaller and made by smaller teams. It's when these kind of practices are applied in enterprise software with large number of programmers, where maintainability is more important than performance, that this is an issue.
- schindlabua 8y agoOk so sometimes I have no concept of what american and british variants of a word are because I'm from mainland europe and so I will just use whatever. Sorry maintainers! Grey/Gray gets me every time.
- pluto9 8y ago> Grey/Gray gets me every time. GrEy for England, grAy for America.
- schindlabua 8y agoOh! That's a nice way to memorize it, thanks!
- pandler 8y agoThat’s honestly a tough one if you’re working on an inter-cultural team. I (American) was working previously on a project with a British-spelling team for a British-spelling client. It was fine when they had named a variable and I could follow their lead, but there are so many random words with spelling differences that I’d never think of that there was invariably a bit of mix-and-matching between spelling conventions. It’s not like I’m going to look up every word in a British English dictionary to see if I’m spelling it the British way.
- jjuhl 8y agoThere are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors.
- maerF0x0 8y agoDisclaimer: This comment is mostly in jest. For a second there I thought i was reading about golang[1]. * Single letter var names[2] / [3] * Underscores [4] / [5] * extended ascii code [6] / [7] [1]https://golang.org/doc/effective_go.html https://golang.org/doc/effective_go.html [2] https://github.com/Droogans/unmaintainable-code#single-letter-variable-names https://github.com/Droogans/unmaintainable-code#single-lette... [3] https://github.com/golang/go/wiki/CodeReviewComments#variable-names https://github.com/golang/go/wiki/CodeReviewComments#variabl... [4] https://github.com/Droogans/unmaintainable-code#underscore-a-friend-indeed https://github.com/Droogans/unmaintainable-code#underscore-a... [5] https://golang.org/doc/effective_go.html#blank https://golang.org/doc/effective_go.html#blank [6] https://github.com/Droogans/unmaintainable-code#extended-ascii https://github.com/Droogans/unmaintainable-code#extended-asc... [7] https://golang.org/ref/spec#Source_code_representation https://golang.org/ref/spec#Source_code_representation
- marcosdumay 8y ago> Single letter var names They are also a Haskellers favorite. There's a non-sarcastic paper running on the internet named something like "descriptive variable names considered harmful". Most of the community agrees with it, including me.
- Hirak 8y ago> Single letter var names There are tons of those in Android framework code as well
- therealdrag0 8y agoWhy are they harmful?
- ppeetteerr 8y agoOh man, any time I read example Go code it always reminds me of code from the 80s/90s. Probably written by the same crowd too.
- cessor 8y agoMany people are pointing out that short identifier names are ok, and that i is perfectly fine as an identifier name. It likely is, and I believe the rule to be true that short identifier names are ok for short scope / context. However, there are several issues: i for an index is ok, but this is a red herring: You only ever need an i for imperative iteration and in a sufficiently high level language you are better of with selection and projection, (iteration for that matter), where you just foreach over each element and don't actually need to ask for things by index. Sure, y'all be hacking C, nothing wrong with that, it depends on what you str doing, but for comprehension, the mere existence of i is a red flag, because most of the time you want something to happen to a collection if things and foreach is perfect for that (or map, fold, filter, pick your poison). Still, a better example than `i` for short identifier names would be x,y,z, or r,g,b These are so common and conventional that I would expect them to have semantics of their own, still they could be chunked to types such as Coordniate, Location, or Point, or Paint, or Color, respectively. But comming up for better names than x,y,z is really difficult, will bloat your code and make it hard to understand what is going on. I am pointing this all out, because many of you seem to favor such very short identifier names - and I am with you: sometimes they make sense, see above - but empirical evidence suggests that very short identifier names, and single-letter identifier names in particular significantly worsen comprehension of code. The same is true for abbreviations (depending on how strongly you abbreviate). [1] https://ieeexplore.ieee.org/document/7884623/ https://ieeexplore.ieee.org/document/7884623/ (disclosure: author) [2] https://doi.org/10.1007/s11334-007-0031-2 https://doi.org/10.1007/s11334-007-0031-2 [3] http://compscinet.dcs.kcl.ac.uk/JP/jp040302.abs.html http://compscinet.dcs.kcl.ac.uk/JP/jp040302.abs.html [4] https://dl.acm.org/citation.cfm?doid=382080.382628 https://dl.acm.org/citation.cfm?doid=382080.382628 [5] https://link.springer.com/article/10.1007%2Fs10664-018-9621-x https://link.springer.com/article/10.1007%2Fs10664-018-9621-... Preprint for [1] here: https://brains-on-code.github.io/shorter-identifier-names.pdf https://brains-on-code.github.io/shorter-identifier-names.pd... [5] is the extended Version of [1] including discussion of how attention is shifted during the experiment. It turns out that, when code uses words as identifier names people don't need to read the comments as much.
- Sohcahtoa82 8y agoI'd add something about breaking common conventions like moving the verb to the end of the function name. For example, I'd change GetPageFromServer() to PageFromServerGet() Also, use synonyms for common function verbs. Like Grab instead of Get. GrabPageFromServer() In a code base I dealt with, a developer did exactly those. Most "get" functions had "get" at the end of the function name. Some functions had it at the beginning, but replaced with "grab". Also, he misspelled a class name and just went with it.