Why Java is stupid (and should be deprecated, haha..)

12 02 2009

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:


int ctr = 0;
int anotherVar = 100;
while (true) {
   // doingStuff
   if (ctr == anotherVar)
      break;
}
for (int i = 0; i < max; i++) {
// doingStuff
}

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
import java.lang.StringBuilder;
StringBuilder result = new StringBuilder();
String[] myArray = {"1", "2", "3"};
for (int i = 0; i < myArray.length; i++) {
   result.append(", ");
   result.append(myArray[i]);
}
result.deleteCharAt(0);
String implodedString = result.toString();
# Python
implodedString = ", ".join(["1", "2", "3"])

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.

Advertisements

Actions

Information

20 responses

13 02 2009
Pete

Effectively comparing a language to a library (regardless of whether it was implemented internally or not). Seems a bit daft to me.

Also, I guess the people who created C#, Python, etc are all emotionally disturbed – they thought for loops where confusing enough to include foreach and equivalents to solve some problems that were *very* common.

13 02 2009
Jason

So true. I cry real human tears for those still coding java in 2009.

(pssst… deprEcated)

13 02 2009
tonightslastsong

@pete

No, this isn’t a comparison of language to library. Yes, Python’s “join” function is just in a package, but the point is that it has a C-api, which allows for keeping effective tasks INSIDE of the compiled language, instead of cramming a bunch of needless bytecodes through the JVM.

Foreach loops are invaluable. A big majority of for loops need to access the data IN the for loop, not just the indices. I’m surprised you can’t recognize that fact. My arugment isn’t that the for statement is the end-all solution. I’m saying that it’s an improvement to using a while(true) loop. A foreach loop is a further case-specific improvement of the for loop.

Unwillingness to introduce new shorthand is exactly the kind of dearth of forward-thinking that will make Java die in the future. Mark my words.

The point is that if there is a task that is more effectively done in C, let it be done in C, not leave it up to a poor programmer to inevitably do inefficiently. Java can’t do that, and must be incessantly over verbose instead. That will never change.

13 02 2009
tonightslastsong

@ Jason

Thanks for the typo correction. I rather hastily added that to the title, and didn’t think to check it. (Chrome doesn’t check spelling in single-line text boxes.. grrr..)

13 02 2009
Daniel

I wrote a similar Java function called flatten:


public static String flatten( List entries, String separator ) {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i 0) sb.append( separator );
sb.append( entries.get( i ) );
}
return sb.toString();
}

The function is really ugly and I’m definitely not proud of it (I feel rather ashamed).

BTW this function is available in Apache Commons StringUtils (join). However if you don’t want to import the package you have to write your own bloated function.

13 02 2009
tonightslastsong

@ Daniel

I think your function is effective and useful. The issue still seems to be that Java leaves everybody to come up with their own way. There must exist some way to do it *most effectively*, and its sad that a very small fraction of people will ever find that way.

Therefore, Java code will run slower because the only a small fraction of the programmers behind it will be using as-efficient-as-it-gets code.

13 02 2009
CaptainDipstick

Go back to waiting tables. You’re clearly not cut out for this.

13 02 2009
tonightslastsong

@ CaptainDipstick

If you can give me an argument, I’ll listen to you. I gave a fraction of my argument above. And if you ask me for my resume, I’ll be happy to provide you with credible points, not “waiting tables”. Comments like that are for low-punching fools like you.

I just put my neck out there for all to take a swing, but you’ve tucked yours safely in your shell.

13 02 2009
Joe Momma

I did not read your full post because you’re obviously a trolling idiot. The first example is a difference in API, not language. Further, you could subclass the String class and implement your precious count method.

13 02 2009
tonightslastsong

Well, there’s your first mistake– you didn’t read the post, where I explicitly said that subclassing the String class defeats the purpose of Java’s reasoning to have a “final” class. If you extend it, it then becomes impossible for an outsider to definitively know how the object behaves.

Not to mention that Strings are used so frequently that this isn’t just a matter of instantiating the class one single time; you’d have to do this a myriad number of times. Imagine the hell if you ever wanted to change it back to String.

4 03 2011
William

Just to note: the String class if FINAL. We cannot even subclass it. So, we cannot add any new methods either.

13 02 2009
Mikael Ståldal

Java can run several threads in parallell on a multi core CPU, and Python can’t (due to the GIL).

13 02 2009
tonightslastsong

Python is perfectly capable of multi-threaded execution, though usually this relies on the framework that you’re working in. multi-threaded support != multi-core support. The OS should be responsible for using the cores. The program should be responsible for creating threads.

For instance, a Python 3d programming engine I work in: the overall framework had to be compiled with support for multiple threads. And then Python worked on multi-core implementations.

13 02 2009
Pete

“which allows for keeping effective tasks INSIDE of the compiled language, instead of cramming a bunch of needless bytecodes through the JVM”

If you’re worry is actually about performance (which wasn’t clear in the article!), you should be measuring execution times and not just eyeballing source-code.

“My arugment isn’t that the for statement is the end-all solution”

“Nobody will take the stance that the for loop intrudes on namespace and creates confusion”

Foreach is useful as a way of avoiding common confusion that often arrises with for loops (common off-by-one errors, etc). In other words, for loops can indeed create confusion, something I have seen many times (and I would guess so have the implementers of foreach constructs).

Eh… I don’t know why I’m bothering with this.

13 02 2009
tonightslastsong

Clarification needed, I can tell: I’m not comparing raw performance (though performance issues are implied). Instead, I’m declaring that if there is a “best” way to do something, that shorthand should be provided. This keeps needlessly mundane tasks fast and inarguably effective.

Java can’t provide anything better than Java. But Python provides actual compiled C. Java is an overly verbose interpreted language, lacking compiled shorthand for tasks better left to compiled code.

(as for your for loop comment, you can’t possible argue that a while(condition) statement circumvents the off-by-one error. That’s not a characteristic of a for loop, and thus you can’t hold it against the for loop for creating that confusion. It’s a confusion based on 0-indexing. Yet necessary. This is far from the point of my post.)

15 02 2009
turtlewax

I’d have to agree. I’m not a python coder, except except for hello-world. Java deserves credit for pioneering the JVM concept, but somewhere deep down in its guts there is something fundamentally wrong. I can’t even quantify it, but even its showcase killer apps are sluggish. As a user I feel a sense of dread when java apps start.

I hope that I’m wrong. Life would be a lot simpler if java could be ‘fixed’. It has such a large user-base because it came first. But in the end, I think java/jvm is a beautiful academic concept; lofty and pure, but ill-suited for getting things done.

15 02 2009
tonightslastsong

I agree with you wholeheartedly. I’m a frequent user of java apps, as well as a programmer of them, and I just can’t help but notice the slowdown. Some tasks should be trivially fast, yet for some reason they take WAY too long in java apps. Part of the fault is on the coders. Part of the fault is on Java.

You’re exactly right about it having a large user-base because it came first. Had some other language been first, it would be in the same position.

3 11 2009
Annie_Lennox's_quimslime

I am continually appalled by Java and the mentality underlying it.

eg. I’ve just discovered that this is legal Java array identifier declaration :
interface dodgyExamQuestion {
boolean setFlag(Boolean[] test[]);
}
…..FFS! I’d painfully learned the rule about the [] appearing before or after the identifier, but now I find it works in BOTH places at once. I cannot fully express my disgust and will have to troll Kathy Sierra just like everyone else.

I hope that with the introduction of the “module” command, the entire codebase from v7 (or 1.7 – belm) onwards can change (without breaking backwards compatibility…….note “BACKWARDS” being apt here )

Note:
When the decision to use inconsistent parameters for indexing was “justified” by the description of “inbetween element numbering”, that should have been grounds for quietly killing those responsible and starting anew.

2 12 2010
Cartlemmy

You’ve actually convinced me to look into Python a bit further.

11 06 2011
Does anyone know Java?

[…] […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: