This reminds me of a manager of mine who wrote a 10,000 line Perl script.
He thought himself how to write Perl in a week. And then started coding. He wrote a script to automate a very tedious testing process so perfectly, we were able to reduce our test team by like 70% and test more precisely than before.
It was fully procedural code. And it looked monstrous. Our architect challenged him that it won't workout. He even challenged to rewrite it in Java, but that project never finished. He was never able to ever complete the rewrite.
It motivated me to learn Perl. Since then my life has been totally different. I've done mountains of work alone working, hacking during nights.
I learned the following things from that episode:
1. First write the program.
2. Write the correct program.
3. Write the program to run fast and efficient(scalability and all that)
4. Beautify the program.
But most people never cross 2)- The point is there are tons of people who can do this tasks related to micro optimization. The people who win in a ordinary work environment are ones who know the art of converting ideas to sell able products in the fastest way possible.
By the way that manager also wrote database clients in C++ which helped us troubleshoot our in memory databases from remote locations. Again the architect challenged to get it done Java, as before the project never completed :)
Its a fact that majority of the software world is hacked and held in existence with tools like Perl and Php. The people who care about artistic elegance are few, they often fail and generally don't matter.
Actually its all the 'design' craze. Most architects think drawing UML diagrams on mspaint to be a sign of technical superiority.
The real issue I think is heavy OO programmers(read java) can't live without.
1. Design patterns- The art of bloating already heavily bloated code.
2. Avoiding meta programming of any kind.
3. Love towards getters/settters and absolutely anything that lends to code bureaucracy.
Why get/set variable directly when you can write tens of classes of methods to set them?
4. Avoid learning the command line. And write bad implementations of sub functionalities of tools like awk/sed to achieve the same tasks.
5. Lengthen anything and everything as much as you can. thisIncludesTheVariableNames, Class names, methods names, package hierarchies, class inheritance. You name it they can pointlessly lengthen it.
6. If you write code in file at least 40% of the lines MUST be try/catch statements. If you can't be satisfied with that write your won exception classes and invoke point 5.
7. Always write code which can't be read or figured out unless you have auto complete, intellisense and other IDE goodies.
8. Use XML as much as you can so that you can dogfood your insanity even more.
9. Make the code so verbose that even simple programs sound like very complicated ones that can be written only by you.
and many more...
If you don't follow these points Java programmers/architects think you are writing bad code.
Ugh... don't blame "design patterns". They are just tools, and any good developer utilizes them nearly constantly. Are we really going to suggest that you can write good imperative code that doesn't involve delegation, strategies, or factories at some level?
The issue is with a culture that thrives on complicating relatively simple concepts by abusing those tools, not with the tools themselves.
Design patterns don't make for bad code, bad coders do.
I'm sorry, but your comment is really not much more than pointless, cynical Java bashing. Java has it's share of problems, and it's definitely not as modern (regarding language features) as some of the other languages today (although that seems to be changing too), but if you're going to attack it, then at least do it for it's bad characteristics, not because you personally dislike/don't understand certain features, or principles of OO development.
Design patterns- The art of bloating already heavily bloated code.
Design patterns are to OO code what salt is to food. Put just the right amount, and you get a tasty meal. Put too much, and you get an inedible pile of crap. Design patterns are not the problem, they are a solution. Bad developers who don't understand when and how to use them are the problem.
Love towards getters/settters and absolutely anything that lends to code bureaucracy.
It's true that Java is more bureaucratic than most languages, but there is a reason why getters and setters are the standard. And the reason is encapsulation. I can expand on this further if you want me to. For what it's worth, I think that this is one of the things that Scala got right [1].
Lengthen anything and everything as much as you can. thisIncludesTheVariableNames, Class names, methods names, package hierarchies, class inheritance. You name it they can pointlessly lengthen it.
CnfNfEx. ConfigurationFileNotFoundException.Which one of these two names do you think describes what the class does better?
If you write code in file at least 40% of the lines MUST be try/catch statements. If you can't be satisfied with that write your won exception classes and invoke point 5.
I don't know which APIs you worked with, but those that I use don't force me to put 40% of my code into try-catch statements.
Always write code which can't be read or figured out unless you have auto complete, intellisense and other IDE goodies.
I can see how autocomplete would make it easier to write code, but to read it? Nope, Java code is perfectly readable in a plain old editor, actually. But it's definitely not as easy to write using a plain old editor, to be perfectly honest.
Use XML as much as you can so that you can dogfood your insanity even more.
I agree with this one. XML madness needs to stop. Fortunately, it seems to be stopping already. For example, most modern DI frameworks don't require you to write your configuration in an XML file.
Make the code so verbose that even simple programs sound like very complicated ones that can be written only by you.
Verbosity is an unfortunate trait of Java. But nobody writes code so that it would seem that only they can write it. If they do, that's called over-engineering and is, believe it or not, considered to be a bad practice.
I read the grandparent as criticizing Java programmers. A sufficient number of bad programmers seem to fall in these trap often enough that the result is a mess.
Design pattern: I wouldn't be surprised if they are used too much.
Love towards getters/setters. Not the fault of the language, that's just bad practice. And no, you don't have encapsulation. Rarely, getters and setters do some verifications or filtering, but most of the time they don't, in which case you just have raw access to the object's mutable state. Be honest and make your variable public, that's less code. If you ever need to put checks or filters (almost never), then just refactor.
Long names: my jury is out for this one. In your example, I'd say the overly long name comes from an overly narrow functionality. For something that specific, you should use a description string.
Try/Catch: If your QA section tells you to check all exceptions, you may have quite a bit of those statements. (Also, maybe he included the body of the try/catch statements?)
Code that requires an advanced IDE to approach: a good IDE let you manage and tolerate higher levels of complexity. You'll also be less encouraged to simplify your code. You may not even notice when it becomes too complex for a humble vi user.
Verbose code: People tend to stop as soon as it works, without simplify their code further. It's not the language's fault, nor is it done on purpose. I hate when I see code like that. I often have to apply various correctness preserving transformations before I stand a chance at understanding it.
"In your example, I'd say the overly long name comes from an overly narrow functionality. For something that specific, you should use a description string." - What use is a description string when you're staring at a code listing, trying to figure out what it does?
"a good IDE let you manage and tolerate higher levels of complexity." - Which is a good thing.
"You'll also be less encouraged to simplify your code." - Simplifying code is a discipline that can just as easily be avoided by people writing in Notepad. Simpler code comes with experience, not through tool abstinence.
"You may not even notice when it becomes too complex for a humble vi user." - If your tools don't get the job done, switch tools. If you find yourself saying "My tools would work fine if only OTHER PEOPLE would ...", you're using the wrong tools.
1) This error looks like it can't be recovered from. Just throw UnrecoverableError("Config file not found"), and you're done. The code is just as readable. Now if you also need to easily catch it, you need better pattern matching than Java and C++ can give you (Ocaml works well). Again, the code will readily display the relevant string. With C++ and Java, okay, drop the string. But try to limit the scope of your exception to the module it belongs to, and use context to give it a shorter name.
2) I agree
3) Thinking about it… you're probably right.
4) I agree
My point was, IDEs are double edged. Like debuggers. Without such fancy tools, you are forced to think before you write nonsense to the compiler. Good programmers will do the thinking anyway, but many others need some "encouragement". Optimizing for good programmers is a good heuristic, but sometimes, you also need to prevent the bad ones to make too many mistakes.
A similar argument can be made about functional languages: I can avoid side effects in C++ just fine, and I mostly do because its plain simpler most of the time. But many programmers need at least an Ocaml straight jacket.
OK, I thought you were taking exception(har har) to the name length, not to the fact that such an exception subclass was being used rather than simply filling in a description.
However, even then I think it's not quite so simple. In most cases simply putting in a text description for the exception would be sufficient, given language support when catching should it be needed. But if the application at a higher level needs to know what went wrong in order to inform the user in a friendly way, you'd need some kind of mapping between the exception and what to display on the screen. And if your app is internationalized, simply displaying the description of the exception would be even more problematic, especially if you have the same exception being thrown from different places (in which case you need to make sure none of their descriptions differ by even a single character lest you destroy the i18n mapping). I couldn't say definitely that subclassed exceptions would be superior in this case, but one could make an argument in favor.
Regarding 1)... Yes, in this particular case you could just throw an UnrecoverableError (or whatever) and pass a string with a message of what went wrong to its constructor. But that wasn't my point at all. I wasn't trying to make a point about how to structure code or deal with errors/exceptions, I was trying to make a point about naming conventions. My example could just as easily have been something like:
"PtgSL. PatagonianSeaLion. Which of these names describes the class better?"
Now whatever you do, long names should be reserved to infrequently used things. If a long name litters your program, you'd better use a shorter one. Conversely, short names belong to frequently used things. This is because a long name is a cognitive burden. On the other hand, one needs to learn what is behind each label, and don't want to forget it.
Fortunately, good long names (such as "PatagonianSeaLion") tend to be about very specific things. So specific that you rarely need them. But there can be bad long names, like "System_Out_Println". Something this pervasive should never have such a long name.
It's true that Java is more bureaucratic than most languages, but there is a reason why getters and setters are the standard. And the reason is encapsulation
Zen tip: When there is a reason for a bad thing, that is called a bad reason.
The bit about building a web app in C is totally off-topic from your claim that 100 lines of python would equal 100 hrs of Java. If you can only write good software in a short amount of time in one or two languages, that's just a reflection of you as a developer and not the language, and I'd seriously challenge you to show me something you've written in 100 lines of python that I couldn't hire a single senior Java developer to write in the same amount of time (lines of code doesn't equal cost, so I'm not interested in debating lines of code nor do I think it's a valid measure of anything).
I'll give you a short story that approaches this issue from both sides. A client walks into a consulting shop with a piece of really bad client/server software written by a different consulting shop. The server is written in Ruby/Rails and the client in Java (Android). Both client and server code is horrible even though the server is written in Ruby (a supposedly beautiful/compact/expressive language) and the client in Java (super ugly long winded grandpa language, or whatever). The client paid the original consultants about $60k in total. One Ruby engineer and one Java engineer rewrote the entire thing in a few days for 1/20 the cost without really reusing an ounce of the original code. Ruby didn't stop the original server engineer from delivering horseshit in too much time, and Java didn't stop the second client engineer from delivering a clean/functional/performant app in just a few days.
So, you're suggesting the following analogy: The crime level of a region relates to the region itself the same way that the quality of software relates to the language the software is built on? You're comparing a property of an object to the object itself and a property of an object to another property. Pretty awesome you'd make that mistake in a thread where you're agreeing with someone's criticism of OO principles.
Depends on whether step 2 is a complete rewrite (in a different language) or further hacking to "make it right".
My process tends to be:
1. Make it work - Knock up a prototype (lots of assumptions made and noted, limited error checking, etc)
2. Make it right - By starting from scratch and use what was learned in making the prototype
3. Make it fast(er) - Having a prototype, and trying it at scale, should have already given me an idea of what algorithms/structures to use/avoid in Stage #2 but, obviously, a further optimisation stage will almost always be beneficial.
Ideally (if time allows) the prototype is written in a completely different language to the desired target. This is the most important point.
Most of the production code I write is C and I tend to do my prototypes in Perl. The helps me for several reasons:
a) ADTs (lists, hashes/dictionaries, etc) are just easier/quicker in Perl/python/ruby than in C (I do have my own C library that I reuse for ADTs so it's not as if it's a great chore writing them each time, but ADT instantiation is just easier in Perl/python/ruby than C).
b) It's also easier to play around with different algorithms if you can switch between ADTs more easily.
c) I can use the prototype stage to continue to learn new languages (it used to just be Perl but has extended to include languages like Python and ruby). This list will keep on growing.
d) It prevents me (or the business) stopping at Stage #1 and using the prototype code for production. (This could be even worse if the prototype was written in C.)
e) A prototype, being quicker to knock up, means faster to getting it in-front of someone else to look at and give feedback.
f) It prevents me just copy-and-pasting chunks of the prototype code as production code so I, hopefully, don't carry over any of the assumptions I'd made in creating the prototype.
g) "Knock up a prototype" doesn't mean no design/testing/etc. I usually end up with design notes and some automated black box testing that can be reused in the later stages.
He thought himself how to write Perl in a week. And then started coding. He wrote a script to automate a very tedious testing process so perfectly, we were able to reduce our test team by like 70% and test more precisely than before.
It was fully procedural code. And it looked monstrous. Our architect challenged him that it won't workout. He even challenged to rewrite it in Java, but that project never finished. He was never able to ever complete the rewrite.
It motivated me to learn Perl. Since then my life has been totally different. I've done mountains of work alone working, hacking during nights.
I learned the following things from that episode:
1. First write the program.
2. Write the correct program.
3. Write the program to run fast and efficient(scalability and all that)
4. Beautify the program.
But most people never cross 2)- The point is there are tons of people who can do this tasks related to micro optimization. The people who win in a ordinary work environment are ones who know the art of converting ideas to sell able products in the fastest way possible.
By the way that manager also wrote database clients in C++ which helped us troubleshoot our in memory databases from remote locations. Again the architect challenged to get it done Java, as before the project never completed :)
Its a fact that majority of the software world is hacked and held in existence with tools like Perl and Php. The people who care about artistic elegance are few, they often fail and generally don't matter.