Verbosity is Evil
Posted by Skrud at Monday, August 14th 2006 at 8:43pm
Programming in Java is like a rollercoaster. At first I hated it. Then I started to like it a bit…. Then I hated it again. Then I discovered the robustness and completeness of Java’s Standard Library, and I started to like it again. Now I still appreciate the library, but I hate the language. The Java Programming language is probably one of the most verbose languages in existence. It takes a lot of effort just to express some of the simplest things.
I think this is because the design philosophy of Java is anal-retentive to the extreme. The library _is_ well-designed, but to the detriment of the programmer who has to deal with the textual overhead that all this flexibility demands. Take a simple example of a program that writes a text file to the screen. This is an extremely basic thing to do. Here is what it looks like in Java:
public class FileRead {
static void printFile(String filename) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(new File(filename))));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (FileNotFoundException e) {
System.err.printf("No such file found: %s\n", filename);
} catch (IOException e) {
System.err.println("Error reading from file.");
}
}
public static void main(String[] args) {
if (args.length == 1)
printFile(args[0]);
}
}(I actually googled for a while hoping to find a shorter version of this thing, and I actually couldn’t. I spent a good ten minutes thinking “It can’t seriously be this long…”).
There are good reasons why this sort of program needs to be written this way. We want to read from a File, so we create a File, and a FileInputStream to read from it. The FileInputStream basically gives us a sequence of characters from the file, and implements an InputStream interface which all InputStream-type things share. This means that a FileInputStream can easily be interchanged with an InputStream from some other source – this is (in the “big picture”) a good thing, because it’s generic.
But I want to read from the file. So I need to convert that InputStream into something that can actually do reading, which is a Reader. An InputStreamReader converts an Input Stream to a Reader. But I want to read from my file one line at a time. That means I need to use a specific kind of Reader that lets me read by the line. That’s BufferedReader. And that’s why we have that really long line of code that’s creating a file, an input stream, and input stream reader and a buffered reader.
Also notice that we actually are forced to deal with the FileNotFoundException and the IOException errors. So in case something goes wrong with the file and reading process, we are forced to handle the error. In a lot of cases, this is a good thing – it means that the compiler won’t let you get away with some potential bugs. But what if we explicitly checked that the file existed before trying to read from it? What if we did:
File file = new File(filename);
if ( !file.exists() ) // ...Well, we’d still have to handle the FileNotFoundException even if it would never, ever, ever occur because we’re checking for the file’s existence. That’s making things kind of messy. Plus – what if it’s a perfectly normal thing to have a file not exist? By definition, it wouldn’t be an Exception, but we have to handle the error anyway because Java has decided that we have to deal with FileNotFoundException no matter where it may be.
All this just means I have to write a lot more code than I should.
To contrast, here’s a Ruby program that does the exact same thing:
filename = ARGV[0]
open(filename).each_line { |line| print line }Wow. It’s basically one line. And it even reads like English “Open filename, each line print line”. You don’t even have to be a programmer to figure out what that does. Mind you, what if “filename” doesn’t exist? You’re right, I’m not checking for any of the errors here. If the file doesn’t exist, the program will just exit with an error. But I guess just to push things closer to the Java version, I’ll add some error-handling.
filename = ARGV[0] or raise ArgumentError.new("No filename provided")
begin
open(filename).each_line { |line|
print line
}
rescue Errno::ENOENT
$stderr.puts("No such file: #{filename}")
endI think that’s still pretty clean, even though the ENOENT might throw you off if you didn’t know it meant “No Entry”.
What about Python?
from sys import argv
if len( argv ) == 2:
try:
file = open( argv[1] )
for line in file.readlines():
print line,
except IOError:
print "Error reading from the file."
else:
print "No file specified."Hey! That’s also really short. It just calls “open” and then loops over all the lines in the file. It doesn’t take a Computer Scientist to figure out what “file.readlines()” ought to do.
My point is that while Java is great at maintaining a generic, flexible design, it’s not very good at revealing the intentions of the programmer. I don’t think that code in Java is very readable, because you need to understand all the inner workings of the Java Library in order to understand what a simple piece of code that prints a file to the screen does. And I don’t think that should be necessary. I think you should be able to look at a piece of code and see “Oh, ‘print each line of the file’”. Any programming language that is as close as possible to “print each line from file” is certainly revealing the intentions of the programmer, and therefore is much easier to read and follow.
Java is great at revealing the internal workings of the library – waitaminute, isn’t that in contradiction to good Object Oriented Design? Aren’t you supposed to encapsulate and hide away your implementation details so that nobody needs to know how they work? Why then do I need to know that a File needs to be read through an InputStream and converted to a Reader and finally read? Why do I need to know that BufferedReader and LineNumberReader are the only Readers that let me read one line at a time?
WHY CAN’T I JUST SAY “FROM FILE PRINT EACH LINE”?
Alan Kay has a very famous quote:
Simple things should be simple and complex things should be possible.
Java makes complicated things possible, and simple things complicated. There is a huge variance between the code you write and the thing you want to be doing. I think the closer those are, the better.






I came to the same conclusion over the summer about Java. To be fair, Java is a great teaching tool for a lot of software engineering principles, but it is fairly impractical. What Java has going for it is the community and their appreciation for developing software right more than the language itself.
Keep in mind that Java is also a great language for people who just won’t ever be super bright. That anal-retentedness keeps idjits in line.
Stuart has a point, but it’s more than that. Java is limiting itself in its own “Object Oriented” blinders. The only reason that certain types arn’t full fledged Objects in Java is probably because they tried it, and it was the most ridiculous thing ever.
Just like everything in the world, as soon as you’re a fanatic about something (such as religion, programming, japanese culture (YES, I’m point at you skrud!), you stop thinking in rational terms.
I’m not saying the people who designed Java weren’t rational, it’s just that they let they’re love of a SYMBOL overshadow the fact that it could be done better.
I’m pretty sure the reason Java still has primitive types was more for performance reasons than anything else. It is totally not the silliest thing ever, and it makes languages like Python and Ruby so much easier to work with and more flexible. (C# also follows the everything-is-an-object-no-primitive-types thing).
Java is a testament to over-engineering.
Dear Skrud,
I concur. Java has a lot going for it except for its overly verbose syntax. Java with Ruby’s syntax and philosophy would have been beautiful. Oh well.
I saw this today:
Please fill in an entry for Java.
IMHO Simple examples are stupid.
Anyway few remarks
1) You can use something like BufferedReader(new FileReader(args[0]));
2) You don’t have to create a static function, and you can add a throw exception to your main method. That will make java code smaller.
3) No matter how good the language it is still easy to write bad code, for example http://dev.rubyonrails.org/svn/rails/trunk/actionwebservice/lib/actionwebservice/dispatcher/actioncontrollerdispatcher.rb
4) Why won’t you just write function printFile(file) and make your life happy? Language designers can’t anticipate all the possible uses of their language, for java console I/O never was a priority; notice the absence of printf till java5!
Well, if we’re throwing error handling out the window, then it becomes
versus
or
And it’s not Java’s Console IO that I’m referring to here, but it’s File IO. Console IO in Java is a whole other peeve of mine. I think it’s just plain foolish to try to ignore something so basic for so long. As if they decided “oh, people don’t write console programs anymore, so we don’t have to think abou those.” (Meanwhile even Microsoft goes and adds a new and improved shell to their next OS).
Obviously no language can prevent you from writing buggy, messy code … but the less code you have to write the less things can go wrong. That’s just statistics. Take a discussion on Java foreach loops as an example. They say:
The point is, more code = more chances to mess something up. Less code = fewer chances to mess something up. Foreach loops let you get away with writing less code, and reducing your chances for fuckups. A language that isn’t Java lets you do the same.
And I held back on posthing this in the article, but since we’re tossing error handling to the wind:
I like that even better than the Java version because again because basically it says open, read, and write. Other than the fact that you have to create a buffer yourself, I think it’s much better at saying what you mean.
I don’t think that more code result in more errors, notice that the blog software that you are using, is written in the language you like and still author managed to introduce a bug in post parsing (notice italic in the URL in my previous post), and it did not save my second post (I did not bother to re-post).
So I don’t think that language with verbose syntax is more mistake prone. COBOL is a good example “add one to counter ;-)” yet anyone can learn it fast and write reasonably complex applications.
On the other hand Perl allows you to write complex code in just few lines and yet make it very complex;
I think errors that matter are logical errors, and I can make them in any language.
C is nice but I think it is not a right level of abstractions for most applications.
COBOL <—-> Java <—-> Ruby <—-> Perl Choose your poison.
Still wishing 248/249 was C++…
I think this is as small and nice as java allows:
BufferedReader reader = new BufferedReader(new FileReader(args[0])); while (reader.ready()) { System.out.println(reader.readLine()); } reader.close();
BTW Skrud, in your code samples you always forget to close file descriptor.
^^ I’m just being lazy. My program exits immediately after so there’s no reason to bother.
good points in general, but wouldn’t what you are asking for basicaly be SimpleJava, which is simply a Java language the generalizes some aspects in Java?
also note: (checking that the files exists, and then reading from it does NOT garantee that the file STILL exists; the action is far from atomic, expecialy given the while loop/buffering/different statements)
Cheers
I never heard of SimpleJava… But I’ll Google it, thanks!
And you’re right about the file not found thing, I didn’t think of that. But the FileNotFoundException is thrown only from the FileInputStream/FileReader constructor – not from the loop. (The loop can throw an IOException if there’s an error reading).
I do like the idea of Jython, though. Which is a Python interpreter written in Java that has the added benefits of letting you call Java library classes from Python.
I think it’s just a matter of finding the right tool for the job. If you want to do simple IO and command-line functions, then a scripting language is the way to go. If you want to design complex systems, then java (or one of the other highly stuctured languages) is the way to go!
I think this whole discussion started because you wanted to swat a fly with a bazooka!
lol, No, SimpleJava doesn’t exists :P
My point is, SimpleJava would be an abstraction of Java. Allowing ppl to assume a whole bunch of things when they want, and still be able to use Java when they want more control.
Which shouldn’t be hard to do, you can define your own grammer, and abstractions, and then simply expand that code to normal java code. (that would be a neet Compiler Class project)
SimpleJava does exist, and it _is_ a neat Compiler class project: http://www.cs.usfca.edu/galles/compilerdesign/simplejava/sjavaex.html
hahahaha
i’ll make sure not to MAKE up things that already exist!
Thats crazy