From ab9b19ccde038befebea3eb1ede967070258ceb4 Mon Sep 17 00:00:00 2001 From: Thom Castermans Date: Fri, 29 Jul 2016 16:25:34 +0200 Subject: [PATCH 01/18] Add missing colon Added a colon that was missing in a ternary if statement. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a591d6..6b6f5f0 100644 --- a/README.md +++ b/README.md @@ -772,7 +772,7 @@ title says it all. Follow the language lawyer discussions in the newsgroups about what various bits of tricky code should do e.g. `a=a++;` or `f(a++,a++);` then sprinkle your code liberally with the examples. In C, the effects of pre/post decrement code such as ```c -*++b ? (*++b + *(b-1)) 0 +*++b ? (*++b + *(b-1)) : 0 ``` are not defined by the language spec. Every compiler is free to evaluate in a different order. This makes them doubly deadly. Similarly, take advantage of the complex tokenising rules of C and Java by removing all spaces. From 1b2256546afc95302a5342de1277ae0969959dbe Mon Sep 17 00:00:00 2001 From: Joost Veen Date: Tue, 2 Aug 2016 15:04:44 +0200 Subject: [PATCH 02/18] Added an a --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 58896e9..b4e9d2e 100644 --- a/README.md +++ b/README.md @@ -1315,7 +1315,7 @@ i = i; It almost goes without saying that the larger a function is, the better it is. And the more jumps and GOTOs the better. That way, any change must be analysed through many scenarios. It snarls the maintenance programmer in the spaghettiness of it all. And if the function is truly gargantuan, it becomes the Godzilla of the maintenance programmers, stomping them mercilessly to the ground before they have an idea of what's happened. -#### A Picture is a 1000 Words; A Function is 1000 Lines +#### A Picture is a 1000 Words; A Function is a 1000 Lines Make the body of every method as long as possible - hopefully you never write any methods or functions with fewer than a thousand lines of code, deeply nested, of course. From e23d90f3f80b6b35abcd2d2d288a0d8ce8ce692b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Noss?= Date: Wed, 10 Aug 2016 22:59:20 +0200 Subject: [PATCH 03/18] Fix URLs --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b4e9d2e..f4bd883 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ To break the boredom, use a thesaurus to look up as much alternate vocabulary as #### Use Plural Forms From Other Languages -A VMS script kept track of the "statii" returned from various "Vaxen". Esperanto , [Klingon](http://www.kli.org/) and [Hobbitese](http://www.chriswetherell.com/hobbit/default.asp target=) qualify as languages for these purposes. For pseudo-Esperanto pluraloj, add oj. You will be doing your part toward world peace. +A VMS script kept track of the "statii" returned from various "Vaxen". Esperanto , [Klingon](http://www.kli.org/) and [Hobbitese](http://www.chriswetherell.com/hobbit) qualify as languages for these purposes. For pseudo-Esperanto pluraloj, add oj. You will be doing your part toward world peace. #### CapiTaliSaTion @@ -131,7 +131,7 @@ Never use `i` for the innermost loop variable. Use anything but. Use `i` liberal #### Conventions Schmentions -Ignore the [Sun Java Coding Conventions](http://java.sun.com/docs/codeconv/), after all, Sun does. Fortunately, the compiler won't tattle when you violate them. The goal is to come up with names that differ subtlely only in case. If you are forced to use the capitalisation conventions, you can still subvert wherever the choice is ambigous, e.g. use *both* _input**F**ile**n**ame_ and _input**f**ile**N**ame_. Invent your own hopelessly complex naming conventions, then berate everyone else for not following them. +Ignore the [Sun Java Coding Conventions](http://web.archive.org/web/20091003224540/http://java.sun.com/docs/codeconv/), after all, Sun does. Fortunately, the compiler won't tattle when you violate them. The goal is to come up with names that differ subtlely only in case. If you are forced to use the capitalisation conventions, you can still subvert wherever the choice is ambigous, e.g. use *both* _input**F**ile**n**ame_ and _input**f**ile**N**ame_. Invent your own hopelessly complex naming conventions, then berate everyone else for not following them. #### Lower Case l Looks a Lot Like the Digit 1 From 08f1d6487d3324781ad30fadaba220e5656ff456 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 15 Dec 2016 15:33:30 +0100 Subject: [PATCH 04/18] Remove duplicated title --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index f4bd883..673892f 100644 --- a/README.md +++ b/README.md @@ -263,8 +263,6 @@ Hide macro definitions in amongst rubbish comments. The programmer will get bore #### Look Busy -Look Busy - use `define` statements to make made up functions that simply comment out their arguments, e.g.: ```c From 7c6dfc33598bce4accbbbc24a9bb38037193106a Mon Sep 17 00:00:00 2001 From: David Date: Fri, 16 Dec 2016 10:22:07 +0100 Subject: [PATCH 05/18] Capitalize next line --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 673892f..773c5a1 100644 --- a/README.md +++ b/README.md @@ -263,7 +263,7 @@ Hide macro definitions in amongst rubbish comments. The programmer will get bore #### Look Busy -use `define` statements to make made up functions that simply comment out their arguments, e.g.: +Use `define` statements to make made up functions that simply comment out their arguments, e.g.: ```c #define fastcopy(x,y,z) /*xyz*/ From 9ca79e59fad56493094eb43eb7212ebf36c91a23 Mon Sep 17 00:00:00 2001 From: Jens Timmerman Date: Tue, 16 May 2017 16:26:19 +0200 Subject: [PATCH 06/18] Remove redundant text this paragraph already appeared earlier on in the text. --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 773c5a1..d8a9b8f 100644 --- a/README.md +++ b/README.md @@ -619,10 +619,6 @@ Within the body of a loop, assume that the loop action is successful and immedia Never use local variables. Whenever you feel the temptation to use one, make it into an instance or static variable instead to unselfishly share it with all the other methods of the class. This will save you work later when other methods need similar declarations. C++ programmers can go a step further by making all variables global. -#### Reduce, Reuse, Recycle - -If you have to define a structure to hold data for callbacks, always call the structure `PRIVDATA`. Every module can define its own `PRIVDATA`. In VC++, this has the advantage of confusing the debugger so that if you have a `PRIVDATA` variable and try to expand it in the watch window, it doesn't know which `PRIVDATA` you mean, so it just picks one. - #### Configuration Files These usually have the form keyword=value. The values are loaded into Java variables at load time. The most obvious obfuscation technique is to use slightly different names for the keywords and the Java variables. Use configuration files even for constants that never change at run time. Parameter file variables require at least five times as much code to maintain as a simple variable would. From 5ef0f12d6c09761120967358333ae9c0e0ef5e4f Mon Sep 17 00:00:00 2001 From: Jens Timmerman Date: Tue, 16 May 2017 16:29:20 +0200 Subject: [PATCH 07/18] markdown escape fix `"\"` displays as `""` in markdown. Fix this by changing double quotes to backticks. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 773c5a1..fe5e56a 100644 --- a/README.md +++ b/README.md @@ -286,7 +286,7 @@ break up `xy_z` onto two lines: _z // local_var OK ``` -That way a global search for `xy_z` will come up with nothing for that file. To the C preprocessor, the "\" at the end of the line means glue this line to the next one. +That way a global search for `xy_z` will come up with nothing for that file. To the C preprocessor, the `\` at the end of the line means glue this line to the next one. #### Arbitrary Names That Masquerade as Keywords From 2f40f35a2606ff363f8c395390cbed9d357b8c48 Mon Sep 17 00:00:00 2001 From: Karl Tarvas Date: Fri, 17 Aug 2018 21:31:39 +0300 Subject: [PATCH 08/18] Ameliorate dinky capitalization scrape --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 49222d1..2010a54 100644 --- a/README.md +++ b/README.md @@ -759,7 +759,7 @@ Use exceptions for non-exceptional conditions. Routinely terminate loops with an #### Use threads With Abandon -title says it all. +Title says it all. #### Lawyer Code From 75cbe911e597e1acceb4e58d33d1cfde83a67060 Mon Sep 17 00:00:00 2001 From: Karl Tarvas Date: Fri, 17 Aug 2018 21:39:14 +0300 Subject: [PATCH 09/18] Introduce supplementary expansion --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2010a54..76d57be 100644 --- a/README.md +++ b/README.md @@ -807,7 +807,7 @@ It offers great opportunities for obfuscation. The key technique is to nest macr #### Exploit Schizophrenia -Java is schizophrenic about array declarations. You can do them the old C, way `String x[]`, (which uses mixed pre-postfix notation) or the new way `String[] x`, which uses pure prefix notation. If you want to really confuse people, mix the notationse.g. +Java is schizophrenic about array declarations. You can do them the old C, way `String x[]`, (which uses mixed pre-postfix notation) or the new way `String[] x`, which uses pure prefix notation. If you want to really confuse people, mix the notations e.g. ```java byte[ ] rowvector, colvector , matrix[ ]; From cba7e6d829bd874beab51a6cbe3c86b82af0ea39 Mon Sep 17 00:00:00 2001 From: Mohammad Faisal Date: Wed, 22 Aug 2018 03:20:18 +0600 Subject: [PATCH 10/18] Format code snippets --- README.md | 73 ++++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 76d57be..3e5e87d 100644 --- a/README.md +++ b/README.md @@ -221,16 +221,15 @@ Much of the skill in writing unmaintainable code is the art of camouflage, hidin Include sections of code that are commented out but at first glance do not appear to be. ```js -for(j=0; j. */ -class clever_SSInc - { +class clever_SSInc { .. . - } +} ``` If possible, put insulting stuff in syntactically significant parts of the code, as well as just the comments so that management will probably break the code if they try to sanitise it before sending it out for maintenance. @@ -515,10 +513,9 @@ Go wild with encapsulation and oo. For example: ```java myPanel.add( getMyButton() ); -private JButton getMyButton() - { +private JButton getMyButton() { return myButton; - } +} ``` That one probably did not even seem funny. Don't worry. It will some day. @@ -653,18 +650,17 @@ Always look for the most obscure way to do common tasks. For example, instead of ```c char *p; -switch (n) -{ -case 1: - p = "one"; - if (0) -case 2: - p = "two"; - if (0) -case 3: - p = "three"; - printf("%s", p); - break; +switch (n) { + case 1: + p = "one"; + if (0) + case 2: + p = "two"; + if (0) + case 3: + p = "three"; + printf("%s", p); + break; } ``` @@ -707,12 +703,11 @@ d = c; Smuggle octal literals into a list of decimal numbers like this: ```java -array = new int [] -{ -111, -120, -013, -121, +array = new int [] { + 111, + 120, + 013, + 121, }; ``` From 500de1bd49e9bade0507d025e4a26e6d98d51a54 Mon Sep 17 00:00:00 2001 From: lawonga Date: Sun, 30 Sep 2018 18:58:35 -0700 Subject: [PATCH 11/18] Update inconsistent capitalization in README.md `On the Proper Use of Documentation Templates` was written as `On the Proper Use of Documentation Templates'. This corrects the inconsistent use of capitalization. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e5e87d..ad831e5 100644 --- a/README.md +++ b/README.md @@ -396,7 +396,7 @@ Document only the details of what a program does, not what it is attempting to a If, for example, you were writing an airline reservation system, make sure there are at least 25 places in the code that need to be modified if you were to add another airline. Never document where they are. People who come after you have no business modifying your code without thoroughly understanding every line of it. -#### On the Proper Use Of Documentation Templates +#### On the Proper Use of Documentation Templates Consider function documentation prototypes used to allow automated documentation of the code. These prototypes should be copied from one function (or method or class) to another, but never fill in the fields. If for some reason you are forced to fill in the fields make sure that all parameters are named the same for all functions, and all cautions are the same but of course not related to the current function at all. From 9ebbc475972d50a0f69cb50d593226efcf49a3b1 Mon Sep 17 00:00:00 2001 From: Riley Martine Date: Wed, 3 Oct 2018 20:21:04 +0800 Subject: [PATCH 12/18] Fix spelling errors --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index ad831e5..3ad4217 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ Never use `i` for the innermost loop variable. Use anything but. Use `i` liberal #### Conventions Schmentions -Ignore the [Sun Java Coding Conventions](http://web.archive.org/web/20091003224540/http://java.sun.com/docs/codeconv/), after all, Sun does. Fortunately, the compiler won't tattle when you violate them. The goal is to come up with names that differ subtlely only in case. If you are forced to use the capitalisation conventions, you can still subvert wherever the choice is ambigous, e.g. use *both* _input**F**ile**n**ame_ and _input**f**ile**N**ame_. Invent your own hopelessly complex naming conventions, then berate everyone else for not following them. +Ignore the [Sun Java Coding Conventions](http://web.archive.org/web/20091003224540/http://java.sun.com/docs/codeconv/), after all, Sun does. Fortunately, the compiler won't tattle when you violate them. The goal is to come up with names that differ subtly only in case. If you are forced to use the capitalisation conventions, you can still subvert wherever the choice is ambiguous, e.g. use *both* _input**F**ile**n**ame_ and _input**f**ile**N**ame_. Invent your own hopelessly complex naming conventions, then berate everyone else for not following them. #### Lower Case l Looks a Lot Like the Digit 1 @@ -188,7 +188,7 @@ Hungarian Notation is the tactical nuclear weapon of source code obfuscation tec #### Hungarian Notation Revisited -One followon trick in the Hungarian notation is "change the type of a variable but leave the variable name unchanged". This is almost invariably done in windows apps with the migration from Win16: +One follow-on trick in the Hungarian notation is "change the type of a variable but leave the variable name unchanged". This is almost invariably done in windows apps with the migration from Win16: ```c WndProc(HWND hW, WORD wMsg, WORD wParam, LONG lParam) @@ -313,7 +313,7 @@ Maintenance programmers, in order to see if they'll be any cascading effects to #define local_var xy_z // in file ..\codestd\inst.h ``` -These defs should be scattered through different include-files. They are especially effective if the include-files are located in different directories. The other technique is to reuse a name in every scope. The compiler can tell them apart, but a simple minded text searcher cannot. Unfortunately SCIDs in the coming decade will make this simple technique impossible. since the editor understands the scope rules just as well as the compiler. +These defs should be scattered through different include-files. They are especially effective if the include-files are located in different directories. The other technique is to reuse a name in every scope. The compiler can tell them apart, but a simple minded text searcher cannot. Unfortunately SCIDs in the coming decade will make this simple technique impossible, since the editor understands the scope rules just as well as the compiler. #### Long Similar Variable Names @@ -370,7 +370,7 @@ This one gets fun when passing `g()` a `char*`, because a different version of ` #### Compiler Directives -Compiler directives were designed with the express purpose of making the same code behave completely differently. Turn the boolean short-circuiting directive on and off repeatedly and vigourously, as well as the long strings directive. +Compiler directives were designed with the express purpose of making the same code behave completely differently. Turn the boolean short-circuiting directive on and off repeatedly and vigorously, as well as the long strings directive. ## Documentation @@ -386,7 +386,7 @@ You don't have to actively lie, just fail to keep comments as up to date with th #### Document the obvious -Pepper the code with comments like `/* add 1 to i */` however, never document wooly stuff like the overall purpose of the package or method. +Pepper the code with comments like `/* add 1 to i */` however, never document woolly stuff like the overall purpose of the package or method. #### Document How Not Why @@ -530,7 +530,7 @@ Lots of them. Move data between the arrays in convoluted ways, say, filling the #### Mix and Match -Use both accessor methods and public variables. That way, you can change an object's variable without the overhead of calling the accessor, but still claim that the class is a "Java Bean". This has the additional advantage of frustrating the maintenence programmer who adds a logging function to try to figure out who is changing the value. +Use both accessor methods and public variables. That way, you can change an object's variable without the overhead of calling the accessor, but still claim that the class is a "Java Bean". This has the additional advantage of frustrating the maintenance programmer who adds a logging function to try to figure out who is changing the value. #### Wrap, wrap, wrap @@ -560,7 +560,7 @@ Instead of using a parameter to a single method, create as many separate methods Make as many of your variables as possible static. If _you_ don't need more than one instance of the class in this program, no one else ever will either. Again, if other coders in the project complain, tell them about the execution speed improvement you're getting. -#### Cargill's Quandry +#### Cargill's Quandary Take advantage of Cargill's quandary (I think this was his) "any design problem can be solved by adding an additional level of indirection, except for too many levels of indirection." Decompose OO programs until it becomes nearly impossible to find a method which actually updates program state. Better yet, arrange all such occurrences to be activated as callbacks from by traversing pointer forests which are known to contain every function pointer used within the entire system. Arrange for the forest traversals to be activated as side-effects from releasing reference counted objects previously created via deep copies which aren't really all that deep. @@ -721,7 +721,7 @@ Nest as deeply as you can. Good coders can get up to 10 levels of `( )` on a sin #### Numeric Literals -If you have an array with 100 elements in it, hard code the literal 100 in as many places in the program as possible. Never use a static final named constant for the 100, or refer to it as `myArray.length`. To make changing this constant even more difficult, use the literal 50 instead of 100/2, or 99 instead of 100-1. You can futher disguise the 100 by checking for `a == 101` instead of `a > 100`, or `a > 99` instead of `a >= 100`. +If you have an array with 100 elements in it, hard code the literal 100 in as many places in the program as possible. Never use a static final named constant for the 100, or refer to it as `myArray.length`. To make changing this constant even more difficult, use the literal 50 instead of 100/2, or 99 instead of 100-1. You can further disguise the 100 by checking for `a == 101` instead of `a > 100`, or `a > 99` instead of `a >= 100`. Consider things like page sizes, where the lines consisting of x header, y body, and z footer lines, you can apply the obfuscations independently to each of these and to their partial or total sums. These time-honoured techniques are especially effective in a program with two unrelated arrays that just accidentally happen to both have 100 elements. If the maintenance programmer has to change the length of one of them, he will have to decipher every use of the literal 100 in the program to determine which array it applies to. He is almost sure to make at least one error, hopefully one that won't show up for years later. @@ -1209,7 +1209,7 @@ Make it so elaborate that no maintainer could ever get any of his or her fixes t #### More Fun With Make -Have the makefile-generated-batch-file copy source files from multiple directories with undocumented overrwrite rules. This permits code branching without the need for any fancy source code control system, and stops your successors ever finding out which version of `DoUsefulWork()` is the one they should edit. +Have the makefile-generated-batch-file copy source files from multiple directories with undocumented overwrite rules. This permits code branching without the need for any fancy source code control system, and stops your successors ever finding out which version of `DoUsefulWork()` is the one they should edit. #### Collect Coding Standards @@ -1332,7 +1332,7 @@ At least one variable should be set everywhere and used almost nowhere. Unfortun The people who design languages are the people who write the compilers and system classes. Quite naturally they design to make their work easy and mathematically elegant. However, there are 10,000 maintenance programmers to every compiler writer. The grunt maintenance programmers have absolutely no say in the design of languages. Yet the total amount of code they write dwarfs the code in the compilers. -An example of the result of this sort of elitist thinking is the JDBC interface. It makes life easy for the JDBC implementor, but a nightmare for the maintenance programmer. It is far **clumsier** than the FORTRAN interface that came out with SQL three decades ago. +An example of the result of this sort of elitist thinking is the JDBC interface. It makes life easy for the JDBC implementer, but a nightmare for the maintenance programmer. It is far **clumsier** than the FORTRAN interface that came out with SQL three decades ago. Maintenance programmers, if somebody ever consulted them, would demand ways to hide the housekeeping details so they could see the forest for the trees. They would demand all sorts of shortcuts so they would not have to type so much and so they could see more of the program at once on the screen. They would complain loudly about the myriad petty time-wasting tasks the compilers demand of them. From 18abde295b9a1ac18e2a172307aa10c219436a9d Mon Sep 17 00:00:00 2001 From: excal04 Date: Wed, 5 Jun 2019 22:40:08 +0800 Subject: [PATCH 13/18] fix incomplete sentence on when to use `i` --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ad4217..fef7123 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ This trick works especially well in Ada, a language immune to many of the standa #### When To Use i -Never use `i` for the innermost loop variable. Use anything but. Use `i` liberally for any other purpose especially for non-int variables. Similarly use `n` as a loop index. +Never use `i` for the innermost loop variable. Use anything but `i`. Use `i` liberally for any other purpose especially for non-int variables. Similarly use `n` as a loop index. #### Conventions Schmentions From aeb5f6f5e0816f279edde36a977f5980692dc0d6 Mon Sep 17 00:00:00 2001 From: "Robert J. Armstrong" Date: Tue, 6 Aug 2019 15:58:25 -0700 Subject: [PATCH 14/18] Fixed broken link The link to the "Square Box Suggestions" got moved some time in 2005. It used to have a redirect, but the redirect gives you a 404 now, even though the page is still there. I went ahead and found the page's current location and updated the text to reflect that. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fef7123..b153021 100644 --- a/README.md +++ b/README.md @@ -1213,7 +1213,7 @@ Have the makefile-generated-batch-file copy source files from multiple directori #### Collect Coding Standards -Find all the tips you can on writing maintainable code such as the [Square Box Suggestions](http://www.squarebox.co.uk/javatips.html) and flagrantly violate them. +Find all the tips you can on writing maintainable code such as the [Square Box Suggestions](http://www.squarebox.co.uk/download/javatips.html) and flagrantly violate them. #### IDE, Not Me! From b9aa42132e1f84cbde8b8ffd25ee50dd855ebc99 Mon Sep 17 00:00:00 2001 From: Adrian Hernandez Lopez <16022257+AdrianHL@users.noreply.github.com> Date: Thu, 1 Oct 2020 09:08:32 +0100 Subject: [PATCH 15/18] Remove broken link Remove broken link - http://www.chriswetherell.com/hobbit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b153021..5d46499 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ To break the boredom, use a thesaurus to look up as much alternate vocabulary as #### Use Plural Forms From Other Languages -A VMS script kept track of the "statii" returned from various "Vaxen". Esperanto , [Klingon](http://www.kli.org/) and [Hobbitese](http://www.chriswetherell.com/hobbit) qualify as languages for these purposes. For pseudo-Esperanto pluraloj, add oj. You will be doing your part toward world peace. +A VMS script kept track of the "statii" returned from various "Vaxen". Esperanto , [Klingon](http://www.kli.org/) and Hobbitese qualify as languages for these purposes. For pseudo-Esperanto pluraloj, add oj. You will be doing your part toward world peace. #### CapiTaliSaTion From 53840b59dbdc1dc3e74ac2457035da4da65f2743 Mon Sep 17 00:00:00 2001 From: Droogans Date: Wed, 4 Nov 2020 18:50:56 -0500 Subject: [PATCH 16/18] docs(copyright): Reference author permission from #3 in headings Closes #46 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b153021..6df6ea3 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ **Roedy Green** [**Canadian Mind Products**](http://mindprod.com/jgloss/unmain.html) +Reproduced [with permission from the author](https://github.com/Droogans/unmaintainable-code/issues/3#issuecomment-235317722), circa 2015 + * * * ## Introduction From 809c328dfda0822b663497f66e6b5c8148d3d2f6 Mon Sep 17 00:00:00 2001 From: Elisha Hollander Date: Mon, 17 May 2021 23:20:14 +0300 Subject: [PATCH 17/18] Grammar and spelling fixes --- README.md | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 250dfd7..38253be 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ Hungarian Notation is the tactical nuclear weapon of source code obfuscation tec - Insist on using "c" for const in C++ and other languages that directly enforce the const-ness of a variable. - - Seek out and use Hungarian warts that have meaning in languages other than your current language. For example insist on the PowerBuilder `l_` and `a_` {local and argument} scoping prefixes and always use the VB-esque style of having a Hungarian wart for every control type when coding to C++. Try to stay ignorant of the fact that megs of plainly visible MFC source code does not use Hungarian warts for control types. + - Seek out and use Hungarian warts that have meaning in languages other than your current language. For example, insist on the PowerBuilder `l_` and `a_` {local and argument} scoping prefixes and always use the VB-esque style of having a Hungarian wart for every control type when coding to C++. Try to stay ignorant of the fact that megs of plainly visible MFC source code do not use Hungarian warts for control types. - Always violate the Hungarian principle that the most commonly used variables should carry the least extra information around with them. Achieve this end through the techniques outlined above and by insisting that each class type have a custom wart prefix. Never allow anyone to remind you that **no** wart tells you that something **is** a class. The importance of this rule cannot be overstated if you fail to adhere to its principles the source code may become flooded with shorter variable names that have a higher vowel/consonant ratio. In the worst case scenario this can lead to a full collapse of obfuscation and the spontaneous reappearance of English Notation in code! @@ -183,8 +183,8 @@ Hungarian Notation is the tactical nuclear weapon of source code obfuscation tec - Use to your advantage the principle that the human brain can only hold 7 pieces of information concurrently. For example code written to the above standard has the following properties: - * a single assignment statement carries 14 pieces of type and name information. - * a single function call that passes three parameters and assigns a result carries 29 pieces of type and name information. + * A single assignment statement carries 14 pieces of type and name information. + * A single function call that passes three parameters and assigns a result carries 29 pieces of type and name information. * Seek to improve this excellent, but far too concise, standard. Impress management and coworkers by recommending a 5 letter day of the week prefix to help isolate code written on `Monam` and `FriPM`. * It is easy to overwhelm the short term memory with even a moderately complex nesting structure, **especially** when the maintenance programmer can't see the start and end of each block on screen simultaneously. @@ -210,7 +210,7 @@ If you have to define a structure to hold data for callbacks, always call the st #### Obscure film references -Use constant names like `LancelotsFavouriteColour` instead of `blue` and assign it hex value of `$0204FB`. The color looks identical to pure blue on the screen, and a maintenance programmer would have to work out `0204FB` (or use some graphic tool) to know what it looks like. Only someone intimately familiar with Monty Python and the Holy Grail would know that Lancelot's favorite color was blue. If a maintenance programmer can't quote entire Monty Python movies from memory, he or she has no business being a programmer. +Use constant names like `LancelotsFavouriteColour` instead of `blue` and assign it a hex value of `$0204FB`. The color looks identical to pure blue on the screen, and a maintenance programmer would have to work out `0204FB` (or use some graphic tool) to know what it looks like. Only someone intimately familiar with Monty Python and the Holy Grail would know that Lancelot's favorite color was blue. If a maintenance programmer can't quote entire Monty Python movies from memory, he or she has no business being a programmer. ## Camouflage @@ -435,7 +435,7 @@ Never document gotchas in the code. If you suspect there may be a bug in a class #### Disparage In the Comments -Discourage any attempt to use external maintenance contractors by peppering your code with insulting references to other leading software companies, especial anyone who might be contracted to do the work. e.g.: +Discourage any attempt to use external maintenance contractors by peppering your code with insulting references to other leading software companies, especially anyone who might be contracted to do the work. e.g.: ```c /* The optimised inner loop. @@ -461,11 +461,11 @@ On a method called makeSnafucated insert only the JavaDoc `/* make snafucated */ > _The cardinal rule of writing unmaintainable code is to specify each fact in as many places as possible and in as many ways as possible._ - Roedy Green -The key to writing maintainable code is to specify each fact about the application in only one place. To change your mind, you need change it in only one place, and you are guaranteed the entire program will still work. Therefore, the key to writing unmaintainable code is to specify a fact over and over, in as many places as possible, in as many variant ways as possible. Happily, languages like Java go out of their way to make writing this sort of unmaintainable code easy. For example, it is almost impossible to change the type of a widely used variable because all the casts and conversion functions will no longer work, and the types of the associated temporary variables will no longer be appropriate. Further, if the variable is displayed on the screen, all the associated display and data entry code has to be tracked down and manually modified. The Algol family of languages which include C and Java treat storing data in an array, Hashtable, flat file and database with **totally** different syntax. In languages like Abundance, and to some extent Smalltalk, the syntax is identical; just the declaration changes. Take advantage of Java's ineptitude. Put data you know will grow too large for RAM, for now into an array. That way the maintenance programmer will have a horrendous task converting from array to file access later. Similarly place tiny files in databases so the maintenance programmer can have the fun of converting them to array access when it comes time to performance tune. +The key to writing maintainable code is to specify each fact about the application in only one place. To change your mind, you need to change it in only one place, and you are guaranteed the entire program will still work. Therefore, the key to writing unmaintainable code is to specify a fact over and over, in as many places as possible, in as many variant ways as possible. Happily, languages like Java go out of their way to make writing this sort of unmaintainable code easy. For example, it is almost impossible to change the type of a widely used variable because all the casts and conversion functions will no longer work, and the types of the associated temporary variables will no longer be appropriate. Further, if the variable is displayed on the screen, all the associated display and data entry code has to be tracked down and manually modified. The Algol family of languages which include C and Java treat storing data in an array, Hashtable, flat file and database with **totally** different syntax. In languages like Abundance, and to some extent Smalltalk, the syntax is identical; just the declaration changes. Take advantage of Java's ineptitude. Put data you know will grow too large for RAM, for now into an array. That way the maintenance programmer will have a horrendous task converting from array to file access later. Similarly place tiny files in databases so the maintenance programmer can have the fun of converting them to array access when it comes time to performance tune. #### Java Casts -Java's casting scheme is a gift from the Gods. You can use it without guilt since the language requires it. Every time you retrieve an object from a Collection you must cast it back to its original type. Thus the type of the variable may be specified in dozens of places. If the type later changes, all the casts must be changed to match. The compiler may or may not detect if the hapless maintenance programmer fails to catch them all (or changes one too many). In a similar way, all matching casts to `(short)` need to be changed to `(int)` if the type of a variable changes from `short` to `int`. There is a movement afoot in invent a generic cast operator `(cast)` and a generic conversion operator `(convert)` that would require no maintenance when the type of variable changes. Make sure this heresy never makes it into the language specification. Vote no on RFE 114691 and on genericity which would eliminate the need for many casts. +Java's casting scheme is a gift from the Gods. You can use it without guilt since the language requires it. Every time you retrieve an object from a Collection you must cast it back to its original type. Thus the type of the variable may be specified in dozens of places. If the type later changes, all the casts must be changed to match. The compiler may or may not detect if the hapless maintenance programmer fails to catch them all (or changes one too many). In a similar way, all matching casts to `(short)` need to be changed to `(int)` if the type of a variable changes from `short` to `int`. There is a movement afoot to invent a generic cast operator `(cast)` and a generic conversion operator `(convert)` that would require no maintenance when the type of variable changes. Make sure this heresy never makes it into the language specification. Vote no on RFE 114691 and on genericity which would eliminate the need for many casts. #### Exploit Java's Redundancy @@ -564,7 +564,7 @@ Make as many of your variables as possible static. If _you_ don't need more than #### Cargill's Quandary -Take advantage of Cargill's quandary (I think this was his) "any design problem can be solved by adding an additional level of indirection, except for too many levels of indirection." Decompose OO programs until it becomes nearly impossible to find a method which actually updates program state. Better yet, arrange all such occurrences to be activated as callbacks from by traversing pointer forests which are known to contain every function pointer used within the entire system. Arrange for the forest traversals to be activated as side-effects from releasing reference counted objects previously created via deep copies which aren't really all that deep. +Take advantage of Cargill's quandary (I think this was his) "any design problem can be solved by adding an additional level of indirection, except for too many levels of indirection." Decompose OO programs until it becomes nearly impossible to find a method which actually updates program state. Better yet, arrange all such occurrences to be activated as callbacks by traversing pointer forests which are known to contain every function pointer used within the entire system. Arrange for the forest traversals to be activated as side-effects from releasing reference counted objects previously created via deep copies which aren't really all that deep. #### Packratting @@ -715,7 +715,7 @@ array = new int [] { #### Convert Indirectly -Java offers great opportunity for obfuscation whenever you have to convert. As a simple example, if you have to convert a double to a String, go circuitously, via Double with `new Double(d).toString()` rather than the more direct `Double.toString(d)`. You can, of course, be far more circuitous than that! Avoid any conversion techniques recommended by the Conversion Amanuensis. You get bonus points for every extra temporary object you leave littering the heap after your conversion. +Java offers a great opportunity for obfuscation whenever you have to convert. As a simple example, if you have to convert a double to a String, go circuitously, via Double with `new Double(d).toString()` rather than the more direct `Double.toString(d)`. You can, of course, be far more circuitous than that! Avoid any conversion techniques recommended by the Conversion Amanuensis. You get bonus points for every extra temporary object you leave littering the heap after your conversion. #### Nesting @@ -742,9 +742,9 @@ myfunc(6291, 8)[Array]; Unfortunately, these techniques can only be used in native C classes, not Java. -#### L o n g   L i n e s +#### L o n g L i n e s -Try to pack as much as possible into a single line. This saves the overhead of temporary variables, and makes source files shorter by eliminating new line characters and white space. Tip: remove all white space around operators. Good programmers can often hit the 255 character line length limit imposed by some editors. The bonus of long lines is that programmers who cannot read 6 point type must scroll to view them. +Try to pack as much as possible into a single line. This saves the overhead of temporary variables, and makes source files shorter by eliminating new line characters and white space. Tip: remove all white space around operators. Good programmers can often hit the 255 character line length limit imposed by some editors. The bonus of long lines is that programmers who cannot read 6 point types must scroll to view them. #### Exceptions @@ -766,7 +766,7 @@ Follow the language lawyer discussions in the newsgroups about what various bits *++b ? (*++b + *(b-1)) : 0 ``` -are not defined by the language spec. Every compiler is free to evaluate in a different order. This makes them doubly deadly. Similarly, take advantage of the complex tokenising rules of C and Java by removing all spaces. +are not defined by the language spec. Every compiler is free to evaluate in a different order. This makes them doubly deadly. Similarly, take advantage of the complex tokenizing rules of C and Java by removing all spaces. #### Early Returns @@ -790,7 +790,7 @@ If you need several variables of a given type, just define an array of them, the #### Never Beautify -Never use an automated source code tidier (beautifier) to keep your code aligned. Lobby to have them banned them from your company on the grounds they create false deltas in PVCS/CVS (version control tracking) or that every programmer should have his own indenting style held forever sacrosanct for any module he wrote. Insist that other programmers observe those idiosyncratic conventions in "his " modules. Banning beautifiers is quite easy, even though they save the millions of keystrokes doing manual alignment and days wasted misinterpreting poorly aligned code. Just insist that everyone use the **same** tidied format, not just for storing in the common repository, but also while they are editing. This starts an RWAR and the boss, to keep the peace, will ban automated tidying. Without automated tidying, you are now free to _accidentally_ misalign the code to give the optical illusion that bodies of loops and ifs are longer or shorter than they really are, or that else clauses match a different if than they really do. e.g. +Never use an automated source code tidier (beautifier) to keep your code aligned. Lobby to have them banned from your company on the grounds they create false deltas in PVCS/CVS (version control tracking) or that every programmer should have his own indenting style held forever sacrosanct for any module he wrote. Insist that other programmers observe those idiosyncratic conventions in "his " modules. Banning beautifiers is quite easy, even though they save the millions of keystrokes doing manual alignment and days wasted misinterpreting poorly aligned code. Just insist that everyone use the **same** tidied format, not just for storing in the common repository, but also while they are editing. This starts an RWAR and the boss, to keep the peace, will ban automated tidying. Without automated tidying, you are now free to _accidentally_ misalign the code to give the optical illusion that bodies of loops and ifs are longer or shorter than they really are, or that else clauses match a different if than they really do. e.g. ```c if(a) @@ -963,7 +963,7 @@ Computer languages are gradually evolving to become more fool proof. Using state #### FØRTRAN -Write all your code in FORTRAN. If your boss ask why, you can reply that there are lots of very useful libraries that you can use thus saving time. However the chances of writing maintainable code in FORTRAN are zero, and therefore following the unmaintainable coding guidelines is a lot easier. +Write all your code in FORTRAN. If your boss asks why, you can reply that there are lots of very useful libraries that you can use thus saving time. However the chances of writing maintainable code in FORTRAN are zero, and therefore following the unmaintainable coding guidelines is a lot easier. #### Avoid Ada @@ -1002,7 +1002,7 @@ If your boss thinks that his or her 20 year old FORTRAN experience is an excelle #### Subvert The Help Desk -One way to help ensure the code is full of bugs is to ensure the maintenance programmers never hear about them. This requires subverting the help desk. Never answer the phone. Use an automated voice that says "thank you for calling the helpline. To reach a real person press "1" or leave a voice mail wait for the tone". Email help requests should be ignored other than to assign them a tracking number. The standard response to any problem is " I think your account is locked out. The person able to authorise reinstatement is not available just now." +One way to help ensure the code is full of bugs is to ensure the maintenance programmers never hear about them. This requires subverting the help desk. Never answer the phone. Use an automated voice that says "thank you for calling the helpline. To reach a real person press "1" or leave a voicemail wait for the tone". Email help requests should be ignored other than to assign them a tracking number. The standard response to any problem is " I think your account is locked out. The person able to authorise reinstatement is not available just now." #### Keep Your Mouth Shut @@ -1010,7 +1010,7 @@ Be never vigilant of the next Y2K. If you ever spot something that could sneak u #### Baffle 'Em With Bullshit -Subtlety is a wonderful thing, although sometimes a sledge-hammer is more subtle than other tools. So, a refinement on misleading comments create classes with names like `FooFactory` containing comments with references to the GoF creational patterns (ideally with http links to bogus UML design documents) that have nothing to do with object creation. Play off the maintainer's delusions of competence. More subtly, create Java classes with protected constructors and methods like `Foo f = Foo.newInstance()` that return actual **new instances**, rather than the expected singleton. The opportunities for side-effects are endless. +Subtlety is a wonderful thing, although sometimes a sledge-hammer is more subtle than other tools. So, a refinement on misleading comments creates classes with names like `FooFactory` containing comments with references to the GoF creational patterns (ideally with http links to bogus UML design documents) that have nothing to do with object creation. Play off the maintainer's delusions of competence. More subtly, create Java classes with protected constructors and methods like `Foo f = Foo.newInstance()` that return actual **new instances**, rather than the expected singleton. The opportunities for side-effects are endless. #### Book Of The Month Club @@ -1075,7 +1075,7 @@ and left,5 = "without" #### Delphi/Pascal Only -Don't use functions and procedures. Use the label/goto statements then jump around a lot inside your code using this. It'll drive 'em mad trying to trace through this. Another idea, is just to use this for the hang of it and scramble your code up jumping to and fro in some haphazard fashion. +Don't use functions and procedures. Use the label/goto statements then jump around a lot inside your code using this. It'll drive 'em mad trying to trace through this. Another idea is just to use this for the hang of it and scramble your code up jumping to and fro in some haphazard fashion. #### Perl @@ -1108,7 +1108,7 @@ LOCAL lcx lcx = TYPE('somevariable') ``` -The value of lcx is now `'L'` or logical. It is further defined the value of `FALSE`. Just imagine the power of this in writing unmaintainable code. +The value of lcx is now `'L'` or logical. It further defined the value of `FALSE`. Just imagine the power of this in writing unmaintainable code. ```foxpro LOCAL lc_one, lc_two, lc_three... , lc_n @@ -1171,7 +1171,7 @@ Stick with what you know and travel light; if you only carry a hammer then all p #### Standards Schmandards -Whenever possible ignore the coding standards currently in use by thousands of developers in your project's target language and environment. For example insist on STL style coding standards when writing an MFC based application. +Whenever possible ignore the coding standards currently in use by thousands of developers in your project's target language and environment. For example, insist on STL style coding standards when writing an MFC based application. #### Reverse the Usual True False Convention @@ -1195,7 +1195,7 @@ someone is bound to "correct" the apparent redundancy, and use var elsewhere in if ( var ) ``` -Another technique is to make `TRUE` and `FALSE` have the same value, though most would consider that out and out cheating. Using values 1 and 2 or -1 and 0 is a more subtle way to trip people up and still look respectable. You can use this same technique in Java by defining a static constant called `TRUE`. Programmers might be more suspicious you are up to no good since there is a built-in literal true in Java. +Another technique is to make `TRUE` and `FALSE` have the same value, though most would consider that out and out cheating. Using values 1 and 2 or -1 and 0 is a more subtle way to trip people up and still look respectable. You can use this same technique in Java by defining a static constant called `TRUE`. Programmers might be more suspicious you are up to no good since there is a built-in literal truth in Java. #### Third Party Libraries @@ -1287,7 +1287,7 @@ void* Realocate(void*buf, int os, int ns) * Reinvent simple functions which are part of the standard libraries. * The word _Realocate_ is not spelled correctly. Never underestimate the power of creative spelling. -* Make a temporary copy of input buffer for no real reason. +* Make a temporary copy of an input buffer for no real reason. * Cast things for no reason. `memcpy()` takes `(void*)`, so cast our pointers even though they're already `(void*)`. Bonus for the fact that you could pass anything anyway. * Never bothered to free temp. This will cause a slow memory leak, that may not show up until the program has been running for days. * Copy more than necessary from the buffer just in case. This will only cause a core dump on Unix, not Windows. @@ -1312,7 +1312,7 @@ Make the body of every method as long as possible - hopefully you never write an #### One Missing File -Make sure that one or more critical files is missing. This is best done with includes of includes. For example, in your main module, you have +Make sure that one or more critical files are missing. This is best done with includes of includes. For example, in your main module, you have ```c #include @@ -1324,7 +1324,7 @@ Make sure that one or more critical files is missing. This is best done with inc #include "a:\\refcode.h" ``` -and `refcode.h` is no where to be found. +and `refcode.h` is nowhere to be found. #### Write Everywhere, Read Nowhere @@ -1361,3 +1361,4 @@ An early version of this article appeared in Java Developers' Journal (volume 2 This essay is a **joke**! I apologise if anyone took this literally. Canadians think it gauche to label jokes with a :-). People paid no attention when I harped about how to write __maintainable code. I found people were more receptive hearing all the goofy things people often do to muck it up. Checking for **un**maintainable design patterns is a rapid way to defend against malicious or inadvertent sloppiness. _**The original was published on [Roedy Green's Mindproducts](http://mindprod.com/jgloss/unmain.html) site.**_ + From 9f7f9c94e7b42f6c5c1eef6f0884ea91a5a698d9 Mon Sep 17 00:00:00 2001 From: Andrew Yurisich Date: Mon, 2 Aug 2021 19:00:42 +0200 Subject: [PATCH 18/18] Revert "true" -> "truth" change, include code block formatting --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 38253be..9d94959 100644 --- a/README.md +++ b/README.md @@ -1195,7 +1195,7 @@ someone is bound to "correct" the apparent redundancy, and use var elsewhere in if ( var ) ``` -Another technique is to make `TRUE` and `FALSE` have the same value, though most would consider that out and out cheating. Using values 1 and 2 or -1 and 0 is a more subtle way to trip people up and still look respectable. You can use this same technique in Java by defining a static constant called `TRUE`. Programmers might be more suspicious you are up to no good since there is a built-in literal truth in Java. +Another technique is to make `TRUE` and `FALSE` have the same value, though most would consider that out and out cheating. Using values 1 and 2 or -1 and 0 is a more subtle way to trip people up and still look respectable. You can use this same technique in Java by defining a static constant called `TRUE`. Programmers might be more suspicious you are up to no good since there is a built-in literal `true` in Java. #### Third Party Libraries @@ -1361,4 +1361,3 @@ An early version of this article appeared in Java Developers' Journal (volume 2 This essay is a **joke**! I apologise if anyone took this literally. Canadians think it gauche to label jokes with a :-). People paid no attention when I harped about how to write __maintainable code. I found people were more receptive hearing all the goofy things people often do to muck it up. Checking for **un**maintainable design patterns is a rapid way to defend against malicious or inadvertent sloppiness. _**The original was published on [Roedy Green's Mindproducts](http://mindprod.com/jgloss/unmain.html) site.**_ -