
perfect. I think it'll work.

perfect. I think it'll work.
As a joke (but not really), I was terribly annoyed at Java today, and wrote this Java code in a few minutes. It’s (not surprisingly) capable of accomplishing *anything*. Give it a shot.
ProjectAttempt project = new Project();
try {
attempt = project.codeWith(Java);
if( attempt.results == tooRigid
||
attempt.developmentTime > acceptableThreshold) {
// since the above condition is usually true,
// we should expect this next line to happen frequently
throw ExceptionallyNotGoodEnoughException;
}
} catch (ExceptionallyNotGoodEnoughException e) {
System.out.println(" ERROR: Java is too rigid!");
System.out.println("Rigid:");
System.out.println("1 a: deficient in or devoid of " +
"flexibility <rigid price controls> <a rigid bar of metal> ");
System.out.println(" b: appearing stiff and unyielding <his face rigid with pain>");
// Don't bother with another try/catch block,
// since it's impossible for the next line to fail.
attempt = project.codeWith(Python);
// Should always read "Impressive"
System.out.println("Development time: " + attempt.developmentTime);
}
Smart-alec replies are welcome, but you won’t change my opinion on the matter
Why is it that, to you, “Object Oriented” is a synonymous colloquial abbreviation for “Absolutely everything must be inside of an Object, even if it kills me, so help me God” ?
Callbacks. Yes, I’m perfectly aware that Java can implement callback routines (via an implementation of a prototype Interface, or Observer, or whathaveyou), but are *YOU* perfectly aware that a simple callback function/method sometimes doesn’t need all the verbose scaffolding that Java makes you jump through?
In fact, the very reason why a “callback function” was designed as it was, had to do with the fact that it was a single “function” (or “method”, if you prefer). It was not a “callback object”. There’s a good reason for that.
You’ll probably argue that I’m just accustomed to the C-style callbacks, and that Java’s are just as well. And yes, this is me insulting Java. Java is not perfect. Accept that fact. Java’s style is cumbersome.
Because Java’s OO framework only really support pointers to objects, you’re actually incapable of passing a function/method reference as a callback function, for the host method to execute arbitrarily.
The task is simple: call a routine, pass a function which defines behaviors. Frankly, there’s no reason for there to be a whole object enveloping this function. After all, it’s just a function. Its only purpose is to define some routine.
It feels like Java is rather OO “trigger happy”. And because of this, setting up a quick callback method (to pass into another method to execute) becomes a friggin beast of a task. This guy describes a 3-step process for accomplishing the task. One part is an interface, another implements that interface and solidly defines some methods, and then there’s the executing class, which takes in an ‘implemented’ interface and can run a particular method from the object created in step 2.
That’s all well can good, but… all I want to do is pass an arbitrary callback to be invoked later on. I don’t want to create an interface, implement it, and then write an invoker class (which, by the way, only invokes some hard-coded method from the object it is given). The only way to simplify it is to try to abbreviate with an anonymous inner class on your implemented interface. Sure, it’s more “inline”, but it’s still way more time consuming than a simple function reference.
Consider this thread, where the thread starter fears the very reality that I am also annoyed with: “don’t know how in Java (other than possibly wrapping up the function in an object ? – good grief please say it isn’t so !“
And then the typical Java junkie reply comes in the very next comment: “If you fear objects, you shouldn’t program in Java.” and then later “What, you’re averse to using objects in an object-oriented language?” Quit being so dense, you idiots. He doesn’t fear the objects themselves. Instead, he (and I) fear the fact that every aspect of Java annoyingly forces you to make an object out of something that should be far simpler.
(And then props to the guy who said “you post some example code of how ‘you’ would implement the Observer Pattern in C++.” … psst.. who’s he quoting when he put the single quotes around ‘you’? You don’t place emphasis with quotes, man.)
The point at hand is that a language can be object oriented without being disgustingly anal about wrapping everything up into class definitions. It is for this very reason that coding in Java slows you down. Dear God, just pass a function reference and be done with it. And it’s more flexible, too.
Don’t complain that passing function references makes the code harder to debug. I personally find well-documented code to be *far* more valuable than needlessly stupid class objects littering my project.
I recently wrote about “Why Java is stupid”; the responses were interesting, found both here and on other aggregating blog sites. I intentionally was a bit uncensored in my post, and it became obvious that the point was being missed.
I’m going to backtrack, and try explaining myself again, though this time with more directed arguments and reasons. I’m also going to break it up into a few parts (at least 2), so that it’s easy to understand the isolated concepts in each part.
In addition, I will completely leave out the mention of any other language (except for simple references to their existences) so that readers may avoid misunderstanding the point being made.
Part 1: Time Will Tell
Over time, it becomes clear why certain technologies were good or bad; with time, we begin to see the mistakes we made early on. When the technology first debuts, we use it because its new. Then, as time goes on, we begin to see where improvements could have been made.
A few examples:
So clearly good ideas were present in each of those examples, but the technologies are now radically different than when they first came out.
What changed? Sure, we made the parts smaller. Of course, we changed the casings to look more sleek.
But what REALLY happened? Here’s what changed: Laptops now have dual core processors. You can buy 16gb flash SD cards for under $50, and solid-state harddrives are finally pushing their way into the market. We’ve got cell phones that double as music players, and triple as GPS systems, and are becoming development platforms, as with the Apple iPhone, and Google’s Andriod-powered phone. For crap’s sake, we have OPEN SOURCE *phones*, and we read our email on them.
Its obvious that the core functionality of those technologies has been radically redone. We didn’t just slap a new face on cell phones in order to get them to where they are now. The fundamentals were rethought.
However, some things just simply seem to lag a little bit behind in our vast Information Age, where the ideas backing the technology seem to be slightly out-dated.
To be fair, those technologies (dusty or not) will still have their uses. The Verilog programming language IDE— holy heck that’s a hard buggy thing to use. It would benefit from a makeover. But we don’t do that because too many things rely on the situation as it currently is. Changing it would probably only create more troubles than its worth, one might argue.
But here’s an example of a technology that actually holds a massively large part of our programming playing field: Java. Java is far more prestigious than Verilog (thank goodness), yet it seems to be suffering from its failure to imp lament more modern programming ideals.
Java, by nature, is remarkably similar to C++, given some basic syntactical differences. It was designed to be C++++, if you will; conceptually it didn’t stray far from what the world knew and loved (that’d be C), yet had the advantage of executing itself on any platform for which a JVM was created. It was a marvelous step forward into the fairly unknown territory of abstraction of programming into layers. It took away the nastiness of having to manage your own dynamic memory, with “destructors” and such.
And Java became popular.
And this comes at no complaint from me, I assure you. The problem arises, however, when 6 or 7 years go by, and we realize that there are better conceptual models. Staying “fair”, various models have their various specialized usages.
And the list could go on. Each has its use. Each has its flaws or weaknesses. Java is not exempt.
The concept of the JVM was miraculous. That’s the sort of thinking that progresses the information age. But as we explore new technologies, coding in Java for small simple tasks is far from the best option. You’re much better off just tagging a lighter-weight scripting language to do your task. There’s almost no sense going through the burdensome process of defining separate files for just a few simple class objects, and then one more class object (and file) for just your static utility methods, and then possibly another class/file to server as your program’s entry point. That’s silly. Just script it and get the task done.
The “Just script it” method is great, because it removes the needless, never-changing parts of writing in C or Java– you just worry about the task, and the scripting language alternative will worry about getting it done. This method often suffers a bit in speed, but we’re no strangers to that trade-off.
Take this example: Computers work on “synchronized” designs, where everything is controlled by one common “clock” signal. It ensures that everything is coordinated, so that if one part of the computer finishes its task before another part, you avoid “race conditions” where there’s no absolute guarantee as to which of the computer’s tasks it will finish first. If the computer can’t predict which will be first, then you’re bound to have a very very unstable computer. The cost of having a synchronous design is that we suffer from a little bit of slowdown. However, the opposing “asynchronous” idea is mass chaos when aimed at a design of the complexity of a full desktop computer. If tediously designed, yes, it may be possible to create an asynchronously clocked personal computer, but would the effort be worth it?
So that’s what it comes down to: Is all that extra effort worth it? Lose a little speed, gain productivity. The argument is that there is a diminishing return on a function f(x)=y, where ‘x’ is the time put in, and ‘y’ is the results. Eventually you get to the point where a huge amount of effort is required, just to get a small more amount of ‘better’ results.
Java is a strange case, because it’s interpreted, yet it’s verbose.
It can be fast, but the methods that actually do the dirty “fast” work are hard to read and are packaged up into shadowed utility packages in the dark corners of the language, and you’ll be scolded by Java junkies about how to “do it better”, which only proves that you have to be a junkie to know about the good fast utilities.
It’s big JVM is possibly a little *too* big, and it very quickly rules Java out of module-based web programming (where a server like Apache just calls a Java process to run your Java code). So instead, we’ve developed “solutions” specific to Java, like Tomcat, Glassfish, and a few other such things to accommodate the ragingly popular Java.
And here’s where we ask ourselves, in light of Java and its world-wide influence:
Is there a better way?
I submit that there is. More to follow in Part 2, yet to be written.
If Java and a language like Python got in a fight, Python would eat the eyeballs of Java, and then spit them out at jobless teenie-bopper Java coders.
Blinded by the magical cross-platform abilities Java presents to its audience, Java coders are hard at work being hard at work. Meanwhile, back at the ranch, Python coders are producing things that perform actual tasks.
(Keep in mind that in the first few comments below, people have bashed on the idea that I’m comparing APIs. But in fact, I’m stating that Java is conceptually flawed and thus its API is inferior, because it doesn’t have a JAVA api. It only has its PACKAGE apis, which only invokes more inefficient java byte codes, which STILL must be put through the JVM. If Java itself had an API for internal tasks, this post would have no relevence.)
A comparison is in order:
The Java philosophy states rather boldly that “less is more”, in the sense that programming shorthand creates troubles for programmers, because they can’t say for sure what is happening behind the scenes, and thus creates confusion.
The Python philosophy is radically the opposite: Shorthand improves readability (so long as the shorthand is intelligently founded on useful concepts) and thus boosts productivity. This allows you to simply get mundane tasks out of the way, so that you can quickly accomplish your task. Others who look at the code can easily understand what the shorthand does, so long as they have an interest in understanding the language.
A simple universal illustration should easily demonstrate the concept. Here is an agreeably poorly coded loop, followed by the revolutionary shorthand:
|
for (int i = 0; i < max; i++) { |
The reason why this is poorly coded is merely derived from the fact that you can’t tell what is happening by glancing at it. This is a fact. The author of the code may know what it does, but the rest of us need to read it. This is why the for loop came into existance.
Nobody will take the stance that the for loop intrudes on namespace and creates confusion. It helps make code easier to read. If you don’t agree, you need emotional help.
Now, by sharp contrast, consider this bit of Java code, which demonstrates how to count how many times a substring appears in a String object. I’ve written it out in three (very) different ways, neither of which is a productive use of my time to write:
// 1
int count = 0;
for (int fromIndex = 0; fromIndex > -1; count++)
fromIndex = text.indexOf(search, fromIndex + ((count>0) ? 1: 0));
count -= 1;
// 2
import java.util.regex.*;
Matcher m = Pattern.compile(search).matcher(text);
int count;
for (count = 0; m.find(); count++);
// 3
int count = text.split(search).length
#1 is pretty ghetto, because it has a for statement which mixes meanings, and doesn’t really illustrate the traditional use of the for statement. It’s effective, but burdened by the fact that Java won’t cast boolean values into integers (hence the ternary operator in there).
#2 is more concise, but requires the regex package, just to count flipping substrings. The very non-traditional for statement is easier to read than that in #1, but still kind of goofy.
The only method that comes CLOSE to being efficient is #3. As a bonus, #3 can use regex without having to import the blasted regex package. But the fact still remains that it doesn’t scream at you that it’s counting a substring. I haven’t benchmarked, so I don’t know how efficient it is with resources. The split method on the String class is specific to the String class itself, and thus can’t be used with other String variants, like StringBuffer or StringBuilder.
Now let’s consider some Python code. But first, if you didn’t know the Python language, what would you guess the name of the function is? An intuitive guess would include the possibility of it having the word “count” in it somewhere.
# Python
count = text.count(search)
What? We’re already done? Example concluded. Nobody can argue that this is hard to understand, or that it pollutes namespace, since the “count” method is one that is called on the string object itself. Naming a variable “count” (as I in fact did in the example) does not create any confusion or ambiguity for the rest of the code.
If you want to multiply a String in Java, you can’t do it effectively. You much make a for loop to iterate X number of times, appending the source string to a new StringBuilder until you’re done. What would possess me to do that? That oozes with inefficiency, and begs a newbie to do it poorly.
Python (and many other interpreted languages) have simply overloaded the multipication operator, so that “x” * 5 simply equals “xxxxx”. This isn’t a terribly frequented piece of code, but the mere fact that Java can’t do it as effectively as most other languages suggests something. For a Django admin application I have written, the web page renders a tree-structure in a table form. In other words, table rows are indented five spaces per nested level, to give the traditional file-tree effect. If I had written this in Java, my best mustered attempt would be an inefficient static utility method to do the same. Heaven knows I don’t want to subclass every String in my project, so so that I can multiply my Strings!
No, the solution lies in simply multipication overloading. Indenting my table rows is as simple as five spaces multiplied by the nested level:
indent = " " * nested_level()
Good. Clean. Code.
So then, how would a novice go about creating something like the PHP ‘implode’ function, which takes an array of strings, and turns it into one big string with a specific delimiter between each array position? (Quick example: )
{“1″,”2″,”3″} imploded with “, ” == ”1, 2, 3″
Note that the 3 is not followed by another “, “. That is the purpose of the function, and it is amazing easy to understand. Observe the primitive method that Java must resort to, while Python laughs at the sideline:
// Java |
# Python |
Java needs to go to its room.
There is nothing effective about forcing (7 + 4*myArray.length) java commands into the Java Virtual Machine. That’s each static statement, plus the two lines inside the for statement per iteration, the ‘i++’ part of the for statement each iteration, plus the condition evaluation each iteration. This is horrendous.
Python understands that things are simply easier and faster if it stays on the internal side of the code; if Python can keep its tasks inside of its C-coded backend, things are going to be much faster, and easier to read. If Java could do the same, it would be a better language. But the fact is that it *can’t* do that, because the code you are writing is just as deep as the set of packages you import. Everything has to pass through the Java Virtual Machine. The Java Virtual Machine has no functions/methods of its own in order to speed things up (in terms of clocked speed and productivity).
Java’s motto is effectively: Java Can’t. And it’s that simple. It’s founded on a design flaw, which bases the language off of pseudo-low level code. This is a silly notion, since Java is interpretted. If there is an effective way of doing things, and it’s oppositely ineffective way, Java leaves you in the middle of the ocean to try your luck. And if you show your code to someone else, they’ll inevitably have a better, faster, harder to read solution.
On the other hand, Python provides you with the effective solution. You don’t have to know the exact algorithm to Python’s “join” function (but if you wanted to know how it does it, you could open up the source and look). Python has witnessed Java’s blunder, and has improved upon the design. Python’s equivalent to Java’s Virtual Machine is actually intelligent, by comparison. The Python interpretter is code written in C. The C code is where the power of the built-in functions lies. Python can then execute your scripts at far better efficiency, and look good doing it,
and Java Can’t.
Despite my distaste for Java, I work in it every day at e-kiwi (author of software Screen-Scraper).
As usual, I was surprised to find that Java has no easy way to count the number of occurances of a substring within a given String variable. I Google’d it and was surprised at the first result’s poor coding. It had a ‘while (true)‘ loop with a goofy break statement tied to a misleadingly-named variable.
Try this:
public int countIndexOf(String text, String search)
{
int count = 0;
for (int fromIndex = 0; fromIndex > -1; count++)
fromIndex = text.indexOf(search, fromIndex + ((count > 0) ? 1 : 0));
return count - 1;
}
Pardon the ternary operator in there, but Java doesn’t like making boolean-casting-to-int easy.
If there are any errors you encounter, just let me know and I’ll fix it. My use for such a function doesn’t require the ‘border’ cases where substrings are at the beginning or end of the main string. If you know that you don’t need to match a substring which will begin at the first character of the main string, you can change the ternary part from:
fromIndex + ((count > 0) ? 1 : 0)
to just
fromIndex + 1
Sorry to the dude that I flamed on his blog, but poorly written code is easy to find these days. Idioms are the way to go. Java’s slow enough as an interpretted language that it doesn’t need extraneous if-else statements in ‘while (true)’ loops and incessant variable assignment to immutable values.
You might argue that it doesn’t really matter if you lose a few cycles on today’s machines, but programs should be as efficient as possible when it’s worth the time. You may as well take a few minutes (or even an hour) and figure out the best way to do something. Forethought with save you an amazing amount of time in the future when you develope real programs and not just school assignments.