Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Tuesday, September 22, 2009

Mid-Twentieth Century Languages

In the News:

Dell to buy Perot. Having trouble competing with HP? Here's an idea: go head-to-head with IBM.

Mid-Twentieth Century Languages

Ruby's powerful and full of Tim Toady. Python's powerful and pythonic. In one area, however, both are bad reminders of the 1960s.

I refer to the fact that both are strictly interpreted, according to the lamest definition of the term. They begin processing at the top of the file. Declarative code? Processed. Imperative statements? Processed.

The intelligent way, of course, is to read the file handling all the declarative code first. Functions, for example, are defined and ready for use when the imperative code is processed. Functions may be declared where they make sense. The structure of the source code is not dictated by the processor; it's decided by the programmer.

Ruby and Python? Nope. Don't place your imperative code at the top of the file; library functions at the bottom. You cannot call a function from statements above the function's definition; you cannot instantiate an object ... This is stupid.

JavaScript eats your source code's declarations first, then goes on to process your imperative code. JavaScript is not the world's most advanced language. That Ruby and Python are less advanced than JavaScript should be an embarassment to both.

If you remember Pascal from the early days of microcomputers you remember being forced to write your main program at the bottom of your file. This was, and is, a tragedy if you valued readability. This is how you must structure your Ruby and Python.

JavaScript gets this right. Java lets you put "main()" where you choose. This should be completely standard in this century.

Friday, September 11, 2009

Error Handling

Today is 9/11/09. John and I played an hour of tennis once a week from 7:30 to 8:30 in the morning. We played eight years ago on this day, quite happily ignorant of the events unfolding in Manhattan. By 9:00 we were a half-hour apart, at our respective offices, watching TV. We haven't played since. And so it goes.

Error Handling Overview

Some processes can generate errors despite the most skillful coding. Disk I/O is one example. (User enters name of a file that doesn't exist. Data cannot be written because the disk is full.) I first met try/catch logic in the mid '90s in Java as a way to handle these sorts of errors. This is now a feature of most mainstream languages.

The basic idea is to surround a block of code (such as disk I/O code) with a "try this" instruction. Following the block to try there is an "if an error occurred" block. Some languages, Java included have an optional "whether or not there was an error do this" block. Code in the "try this" block (including, importantly, subroutines called in that block) can "throw" an error, often an Error or Exception object for use in the "if an error occurred" block.

Error Handling in Java

This is the basic Java syntax:


try {
}
catch (Type1ExceptionOrError var1) {
}
[catch (Type2ExceptionOrError var2) {
}]...
[finally {
}]



Java has both XxxException and XxxError classes. The builtin classes can be extended by the programmers to create more Exceptions and Errors. Multiple catch clauses allow code to be written to handle particular Exception or Error types. Importantly, catch (Exception e ) {} will catch all exceptions, though it loses the ability to use any added information in extending classes. Errors can be handled similarly, but are generally not handled. A Java Error would be something like a hardware failure that the program probably cannot deal with successfully.

If I were redesigning the language I would eliminate the finally block entirely. The catch blocks should simply branch to the code that follows the last catch block.

I would then use only a single catch block. If needed, the programmer can put a switch inside that block which calls code appropriate to the exception type.

That said, let's look at the ways some other languages address the issue.

Error Handling in JavaScript

JavaScript follows Java's try catch finally lead, with two important differences. First, there is only a single catch block. Second, the thing caught may be anything: object, string, number, ...

In JavaScript: The Good Parts, Doug Crockford eliminates the finally block, leaving exactly what I recommend for Java.

Error Handling in Python

Very like Java, but the catch block is known as an except block.

Error Handling in Ruby

Similar to Java, but Ruby stubbornly goes its own way. You don't try, you begin. You don't catch, you rescue. You don't finally, you ensure.

Ruby also features a retry keyword that repeats execution of the try block.

"Martin, don't forget that stupid Tim Toady! You can use catch blocks, too."

"Thanks, Monty. I'll put that in."

Monty, my pet python, knows just enough Ruby to criticize it.

Error Handling in C++

Like Java you have try and catch blocks. Unlike Java there is no finally block. Also unlike Java, there is no restriction on the type of thing caught. Strings and integers, for examples, can be caught. There is also a generic "catch anything" variant, though there is no way to hand the thing caught to the code in this catch block, a disadvantage of strongly-typed languages.