One convention was that all "procedures" should be prefixed with a name indicating where they were in the call graph of the program.
So the main method was always:
int main()
{
a_initialize();
b_process();
c_shutdown();
}
The first function called by a_initialize had to be called "aa_", then "ab_" and so on: void a_initialize()
{
aa_connect_database();
ab_read_accounts();
ac_read_ledger();
...
}
and so on.Of course, sometimes you had to write a function that had to be called from more than one place (strange I know!!)
For this, the naming convention "pzzDDDD" was used where D was a digit from 0-9. "p" for procedure and "zz" because these functions didn't belong to any one place in the hierarchy.
We had a print out of the "pzz"s because just the number was hard to remember. But I can still remember a few of them:
* pzz0030 was for looking up account information from the database (but also for maintaining this information).
* pzz0031 for contracts
* pzz0241 I think was for looking up fees and commissions.
Most of the "functions" had lots of parameters so that they could do different things (modify, update, delete accounts etc.). This soon became unwieldy so eventually you had:
* pzz0241_a_setupcharges()
* pzz0241_c_cleanup()
or something. I forget the details for this last bit.
This was in 1997.
Neat huh? ;-)
Sounds like a good idea, until you see how this turns terse and readable code into a bag of chatty noise. Basically this:
public enum ConnectionState {
Disconnected, Connecting, Connected
}
Was not compliant ("There's no comments! It's not readable!"), while this: /// <summary>
/// The Connection State.
/// </summary>
public enum ConnectionState {
/// <summary>
/// The Connected State.
/// </summary>
Connected,
/// <summary>
/// The Disconnected State.
/// </summary>
Disconnected,
/// <summary>
/// The Connecting State.
/// </summary>
Connecting
}
Was considered Compliant and Good. This example has not been simplified, by the way.> allows extraction of documentation and intellisense.
These already give you type signature and function name. If intellisense already gives you "bool isValid", what possible gains do you get from an extra "boolean value indicating whether the value is valid"?
> I am no drone by any means, but this isn't so insane if you give it some thought.
Trust me, I have given it plenty of thought. Some conclusions from these thoughts:
- Code comments that merely mimic the type signature add nothing. Not for readability, not for intellisense, not for documentation extraction.
- They increase the signal-to-noise ratio of the code immensely, making it harder to read. Comments with actual useful information will now drown in the sea of drivel.
- Fuck it, I'm not working here anymore.
The main fallacy here is that More Process and More Rules can make bad programmers write good code.
> To NEVER remove any code when making changes. We were told
> to comment all changes.
I'm afraid given this rule, I would abuse it horribly. My backspace key would no longer function and every typo I make would introduce a new set of /* */ comments. Every refactoring would have the old type, variable, line, function, or entire class commented out with the fixed code alongside it. Bonus points for interleaving the old code and replacement code.There have been a few times were code was reverted and having the code merely commented out saved time, time spent cut/pasting from archive. Even with a good CMS keeping commented out code can serve another purpose, knowing what was when and why. That way we can avoid the "well back in year X we had a rule" because we have the code readily accessible.
For large blocks (subroutines/procedures/etc) it is not uncommon to move the whole to the end of the source.
Surely source control would be a nicer way than copy/pasting old code back in?
I tend to agree more with coding guidelines that go exactly the other way: Do not leave around any commented out or dead code. It breaks the flow of reading the code and can cause confusion as to what is actually happening. If you need to refer to an old state of the code, just provide a commit id in your comment.
This, here, is your problem.
This resulted in code like:
url = HTTP + COLON + SLASH + SLASH + WWW + DOMAIN_NAME + DOT + COM;
based on lots of definitions like: public final static String COLON = ":";
public final static String SLASH = "/";
public final static String DOT = ".";
public final static String COM = "com";
[Apologies if this contains any Java syntax errors, I pretty much stopped using Java soon after this experience]Also I've just realised that I'm really glad Java doesn't have a standard pre-processor - truly evil things would then have been possible <shudder>
No indentation allowed. Even though the modern compilers supported it, it looked ugly to veterans who had worked with fixed-format compilers for 30 years.
No comments in the code allowed. The function had to be entirely clear by looking at the code. Any code that needed comments for clarification was considered too 'clever' and 'obfuscated' for production.
No new language features allowed. IBM maintained languages and tools always acquire large amounts of feature bloat over the decades. Only a small subset of these features was 'white listed' by the CTO.
That's not necessarily bad advice - at least as a starting point. If you use descriptive variable/function names, then a huge amount of your commenting usually needs go away.
The big advantage is that people are rarely very good at updating comments - at which point they become at best useless and often downright misleading, Whereas most coders will hopefully at least consider renaming a function or a variable when it's no longer accurate.
Now, let's play a game. :) I'm going to Gist the example RPG program from Wikipedia, but with all the comments stripped out. Take a guess as to what it does:
https://gist.github.com/4204324
(Note that the spacing shown here is absolutely essential. Keep this in mind if you ever feel like complaining about whitespace in Python.)
Answer:
http://en.wikipedia.org/wiki/IBM_RPG#Example_code
My company's entire internal business infrastructure is written in, perhaps, millions of lines of this (commented, thankfully).
"Right," you may say, "but this is surely easy enough to read for someone who's used RPG for a while." Now consider that (afaik) RPG hasn't been taught in schools since the 70s, and that this entire format is alien to folks reared on Java. Even a poor comment in this environment is like suddenly stumbling across a line of semi-cogent English scribbled in the margins of the Necronomicon. Which is to say, it might just hold the insanity at bay for a while longer. :)
Footnote: the Wikipedia article mentions a "FREE" mode that makes writing RPG much more similar to modern languages (what an old hand here might call "freeform" languages, a.k.a. languages that aren't column-based). But I get the feeling that the gp's company would regard such notions as heresy.
- (void)
doSomethingOnObjectAndNumber:
(NSObject *) MyObject :
(NSInteger) MyNumber
/*++
Some unstandard doc format.
--*/
{
...
return;
}
Before I started, I was told that the project migrated from git to svn to "make branching easier". I do not work there any more.--John McCarthy, http://www.infoq.com/interviews/Steele-Interviews-John-McCar...
Of course, trivial things like braces on the same or next line or whitespace around operators are solvable that way, but in general, as long as source code is text (and it will remain that way for quite some time). What perpetuates this state is obviously that we have lots of tools that deal with text and very few that deal with more specialised content. In general I find this sad, though, as text is often neither easiest to work with nor most expressive, despite of what diehard Unix users say.
What would be really lovely in my eyes woul be a source control tool that actually understood its content and could say "order of parameters of that function was changed" or "method added", etc. It's sometimes astonishing how the pursuit of optimal diffs masks the intent of a change where an added method diff starts with the closing brace of the previous method, for example.
[1]: http://welbog.homeip.net/glue/71/Whitespace_is_not_a_problem
In Python you can get the whole return statement. Especially when adding a similar type of method, e.g.: Django view functions. Makes
git add -p
more fun. * you can elect to turn off formatting for sections of your code
* you can save/export your formatting convention in an XML file that looks like this: http://pastebin.com/fKjKRuZg
* you can import that code convention into new/other projects
* you can select any number of files or projects and choose to apply the formatting to the Java source
* the result is very readable
This might not tie in directly to your source control tool as is but would make taming and standardizing source from multiple developers a bit easier. As long as every contributor's code eventually is coerced into this form your own/central copy can easily be diff'ed across versions. Also, you could apply other conventions with other formatters for clients that see things differently.Automatic reformatting is evil - sometimes codes is more readable if formatted in a particular way. Readability and maintainability always trumps adhering to rules.
1. There is an agreed autoformatting template, checked into version control.
2. It is always ok to format the lines you are working on however you like, with the understanding that other people may run the autoformatter on the file.
3. It is always ok to run the autoformatter on a file you are working on (autoformatters only really work at file granularity).
4. It is not ok to format code you are not working on.
Needless to say, getting barely PHP capable people who'd heard of unix to automate dependency installation and maintenance on such a platform didn't work out well. Did I mention this was 2010?
[1] http://msdn.microsoft.com/en-us/library/aa260976%28v=vs.60%2...
There again same place made me retest a program I'd tested and was fully working as a full-stop was missing of a comment line.
Crazy days.
If you prefix every table name with "tbl", you can't search for them in the DB manager console, the IDE table listing, a directory list of the creation scripts, etc.
I suffered an extreme version of this: there was some prefix that was also the directory name. So the files were called "prefix/prefixBlah". Also the prefix was used as class name and the fields were also prefixed with it.
The result was that a reference could become "prefix/prefixBlah/prefixBlah.prefixDoh", an awful noise to signal rate.
I complained without success. That way was "a lot more orderly and tidy" <sigh>.
"Good programmers eventually learn to misspell words like void or int so that they can name their variable names what they want to name them."
I of course told him that this was terrible advice, and would mess with the next person who had to maintain the code because you couldn't tell at a glance if a word was a keyword or a keyword mispelled. I asked him what language he was using.
FORTRAN.
Where did he work.
The United States Air Force.
For how long?
Six years.
When?
Before 2000.
Since he had more experience, he claimed I was de facto wrong.
I fought him on it some more.
He told me it was personal preference. I told him you'd have to make me do it.
It was at that moment I figured that someone, somewhere, had probably had to do this as part of a coding guideline.
But such things are quite annoying for automatic code generators, though, as they have to make sure that they won't ever emit an identifier that clashes with a keyword. The ability to just prepend @ in C# is quite helpful in that regard.
Style guides are ok though, so long as they're short and not enforced too bluntly.
Theory: It's prettier.
Reality: Just try to understand the hierarchical relationship between 247 functions in a 10,000 line Material Requirements Planning module of an ERP system when every function name must be all alpha.
FloopTwentySeven
rather than Floop27
:-)For the 1000th time
"there is no need to encode the type of a variable into the name"
It's not the data type (int, char, etc), it's the nature of the thing being counted!
Number of apples, height, distance, etc
But of course when saying "type" most people would think it's the data type when it's not
Still have no idea why they establish it this way.
The tbl01 makes it unique (so you can have a users and someone else can have theirs too), the data dictionary then tells you what fields exist in that particular table and how those fields relate to other tables.
Over-management is much more common and much worse problem than over-engineering.)