Friday, June 29, 2007

What's Wrong With ... Exceptions

Do you know what checked exceptions are for? They are one of the main features of Java, yet many people don't how when to use checked or runtime exceptions. Sadly, this is not only true for beginners, who are regularly confused by this topic, but also Java professionals. Moreover, when the topic comes up, a heated discussion flares up between the pro and the against groups. I'll call them the vi and emacs groups, because they behave so similarly.

The vi group wants to get things done. Their tools must be simple, solid, always available. They despise checked exceptions because they feel they get in the way. The Emacs group, on the other hand, likes the comfy, all-encompassing tools, that read your lips and bring you coffee. For them, checked exceptions are a way to build more robust software.

I'm in the vi group. I've never bought the idea that checked exceptions make software more solid just as I don't believe that laws reduce crime, but that's another story. First, let us look at what checked exceptions really are. For the sake of your sanity, I omit java.lang.Error.

When Java was developed, C++ was all the hype. C++ had this thing called exceptions which could be used to report unusual (= exceptional) states. The Java designers looked at them and found that you could use them for two purposes: Error and exception handling. Errors are, unlike exceptions, expected states. When I open a file and the file doesn't exist, that's an error. When a user is asked for some info and that info is obviously wrong (text instead of a number), that's an error. Errors happen outside the scope of your program. They are likely to happen and it makes sense to handle the error by, for example, showing a dialog to the user so she can solve the problem and there is a high chance that she can actually do it.

Exceptions are unexpected. They happen within the scope of the program but there is probably nothing you can do anymore after the problem happened. Null pointers are the standard example. When the program tries to follow a reference and that reference is null, what can it do? Obviously, something must be broken elsewhere but more often than not, there is nothing that could be done to fix the problem when it happens. Except maybe display a death message and crash.

The Java designers decided to invent checked exceptions to denote errors, illegal and unexpected states outside of the scope of your program. Let's look at what they came up with:

FileNotFoundException is checked (correct).
IOException (harddisk dies) is checked, too (correct but not very intuitive: What can the program possibly do when this happens?).
SQLException which can mean your DB connection just died because the DB server was rebooted (error) or you tried to insert data twice (exception) is checked, so it's right sometimes, sometimes, it's wrong; Oracle folds some 50'000 errors into SQLException; some are exceptions, some are errors according to the defintion.
IllegalArgumentException (when you pass wrong arguments to a method) is not checked (correct).
ClassCastException is not checked (correct).
ClassNotFoundException is checked; I believe this is wrong since the classpath is within the scope of the program and there is not a big chance that recovery is possible.

So as you can see, even the designers of the language were also confused when to use errors or exceptions (or they dreaded the amount of code that would have to be written if they had used an error). But it goes on: Checked exceptions must be handled. If you don't do anything, the compiler will stubbornly refuse compile your code even though nothing is wrong with it. The code would work! It's not like a syntax error or something. The compiler just bullies you. So especially beginners (who have to juggle all these many new things in their heads) are challenged how to handle them. Some add the necessary throws statements to their methods until they have 20 of them in the method definition and they give up. Here are a few common patterns what happens next:

void foo1() throws Exception { ... }

void foo2() {
  try { ... } catch (Exception ignore) { }
}

void foo3() {
  try { ...
  } catch (Exception e) {
    e.printStackTrace();
  }
}

void foo4() {
  try { ...
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}

void foo5() {
  try { ...
  } catch (Exception e) {
    throw new RuntimeException("Something was wrong");
  }
}

There are many problems with these approaches:

  1. foo1() hides which exceptions can be thrown, so there is no way to handle them higher up even if you could. The compiler won't allow you to add specific catch statements (because these exceptions aren't thrown anymore), you will have to catch Exception and then use instanceof and cast. Ugly at best.
  2. foo2() just swallows all exceptions, runtime and checked. They are just gone! The code will start to behave erratically and there is no way to figure out why except using FindBugs or your eyeballs. Have you ever tried to find such a bug in 20'000 lines of code?
  3. foo3() seems to be an improvement but it isn't: Instead of having a notification when a problem happened, someone (a human) has to control the output of the code manually. This doesn't get better when the exception is sent to some logging tool, because they usually also don't notify someone on their own (who wants to get 10'000 emails if something breaks in a loop?), so I omitted this case.
  4. foo4() is most often used but it's no solution, either: All exceptions are again folded into one (so you can't say anymore which could happen and react accordingly) and RuntimeExceptions are wrapped (because they extend Exception) even though that is unnecessary.
  5. foo5() is my favorite. "Something" is wrong. Really? What? How do I find out after the fact? How do I test that my bugfix in fact fixes the problem?

If you think only beginner make these mistakes, then search the JDK. You can find plenty of examples for each of these. It's not a mistake, it's the standard response of developers when they use a feature which is not well-understood.

What can be done?

Many of the Java frameworks gave up on checked exceptions and converted all their code to use runtime exceptions instead. Spring and Hibernate are the most prominent examples, especially since they had such a huge codebase to fix. They probably put a lot of thought into that before investing countless hours into rewriting all the exception handling code and imposing the same work on all their clients.

Maybe this is the best solution since Sun will probably not modify their compiler (and it's only the compiler that needs to be fixed! The Java runtime, the VM, does not care about missing catch and throws statements). Unfortunately, this leaves a large gap. Personally, I don't hate checked exceptions, I hate that the compiler insists on knowing when I can handle them. I also hate that the compiler hides half (or more) of the exceptions that could be thrown in a given piece of code from me. I have to compile the code in my head to get that information which is wrong for any reason. In both cases, the compiler (or the guy who wrote it) makes assumptions on what I can do where in my code or tries to impose limitations on me that make sense for him.

What I would like to see is this: The compiler should collect all the exception information it can get and add that to the throws clause in the .class file (you can add runtime exceptions to the throws clause, you knew that, didn't you?). There are very strict rules what Java code can throw where, so this should be hard but not impossible. True, this will never be perfect but I'm only asking for best effort here. Next, it should not complain when an exception is not handled anywhere. Sounds like a sure recipe for a painful death but bear with me.

In the IDE, I would like to have a tool which allows me to see and filter all these exceptions. I would like to see all SQLExceptions that my DB code can throw. Ideally, I would like to see all the possible error codes as well (I'm dreaming here but you get the idea).

The goal is to have tool support for handling any number (from 0 to 100%) of exceptions that could occur based on my needs. There is a big difference whether I whip up some run-once tool for myself that scratches an urgent itch or whether I write a framework or code for a nuclear power plant.

Right now, the compiler is doing the wrong thing for everyone. That is bad.

Moreover, when you're doing Test Driven Development (like I do and you should), then having the compiler enforce error handling becomes a real nuisance since your tests will check both the correct and the error cases. In that regard, the error handling in your code will always be the best that could be there. And if you look at this from the economical side, there is no point in handling an error that never happens (even if it could): The more rarely an error occurs, the more it becomes an exception.

More info: "Java's checked exceptions were a mistake" by Rod Waldhoff and "Removing Language Features?" by Neil Gafter. These are just two examples of many you can find on the net. If you want to see a reason why nobody gets it right, have a look at Chapter 11: Exceptions of the Java Language Specification or "Unchecked Exceptions - The Controversy".

Thursday, June 28, 2007

Back from JaZOOn, Fourth and Last Day

In the morning, Neal Gafter gave some insight into "Adding Closures to the Java Programming Language". You remember anonymous classes? Well, closures are similar but solve all the problems associated with it: You can access and modify variables from the surrounding method, for example. You can use closures to replace all the listeners in Swing. Look at this code:

 InputStream is = createStream();
 try {
    doSomething(is);
 } finally {
    try { is.close(); }
    catch (IOException e) {
       log.warn("Error closing", e);
    }
 }

What do we have here? The actual information is the "doSomething()". That's where the interesting stuff happens. Everything else is boiler plate code. Now imagine you must change the logging. You have copied this code a thousand times. The stream has often a different name or it's a Reader. You can bet that you'll forget to make the change in at least one place. Okay, it's just logging, but how often have you seen this pattern repeated? A piece of code where the meat is embedded deeply into some other Java code and the whole thing is duplicated with cut&paste all over the place. That's what closures are for:

 with (InputStream is : createStream()) {
    doSomething(is);
 }

with() is a method which takes two arguments: An InputStream and a Closure. The code for with() looks somewhat like this:

 void with(InputStream is, {InputStream => void} block) {
     try {
         block.invoke(is);
     } finally {
         try { is.close(); }
         catch (IOException e) { log.warn("Error closing", e); }
     }
 }

As you can see, the code wrapping the closure is now in one place. The same pattern can be used when reading objects from a database (in this case, with() could handle the opening and closing of connections, statements and ResultSet's). Neal showed examples how to use this in listeners or how to have a loop in the with() method. In this case, "break" in the closure can exit the loop (if you have read enough objects from the database or enough files from the file).

Great stuff. Late but great.

After him, Danny Coward showed how Java will evolve into Java SE 7 and Java EE 7. Not many surprises here. Sun aims for a 18 to 24 month release cycle. That is should give the expert groups enough time to come up with great and stable features. We'll see about that. I would prefer if they came up with useful features that made developing software easier. For example, annotations in Java 5 could have been a great feature but they can't modify the code. Makes sense from a compiler point of view but castrates the feature. And don't get me started with generics. I couldn't even name a feature of Java 6 that I had seen and that I feel helps me in my daily work.

Enough of that. Where does the big world spin to? Henry Story showed Web 3.0 (and Web 2.7 a.k.a Freebase). The "Semantic Web". Every information annotated with an URI to tell what it is and how it is related to another information. The whole world seen in 3-tuples. Unfortunately, tools aren't there, yet. If you don't want to use VI and cwm, there is not much to chose from. You can try Protégé, Swoop or a commercial product TopBraid Composer. All this looks very promising, especially in relation to JCR/Apache Jackrabbit. Jackrabbit allows to store structured and unstructured data and manage it (search, modify, import, export). This is one step above relational databases which offer only very limited capabilities when it comes to data which is only partly structured or not structured at all (like texts, images and videos). If you're lucky, you can store this types of data but searching it? Forget it.

The semantic web (SW) looks at the problem from the other side: It allows to annotate data with types, so you can know (or rather, your programs can know) if two "things" are the same, similar or related. Example: You are a person. You have a name. In the SW world, "you" is an object or entity of type "Person". Your name is a value of type "Person:name". If you know someone, you can attach the relation "knows" to the entity "you" and then refer to other person objects. Since the code walking this graph knows that it's traversing persons, it knows that there are names somewhere so it can display them on the screen when you list all the people that you know, etc. For more information, see Henry Story's BabelFish blog. Maybe start here.

He explained many more details and answered questions in the long Q&A session after his talk. I wished there had been more of these. Many talks raised interests but 5 minutes were never enough to ask any complicated questions.

The talk "JCR, the Content Repository API for Java" wasn't very interesting for me because it mainly focused on the API. Peeter Piegaze showed different node types and typical Java code. Therefore, I didn't attend "Content Management with Apache Jackrabbit" but "Development of a 3D Multiplayer Racing Game". I had hoped for some insight into the problems Evangelos Pournaras had ran while developing the game or details of the physical simulation. Instead, he listed the features and showed the UML diagram of the game. I was very disappointed.

Afterwards, the conference closed with the Jazzon Jam. Over the several days, the moderator had told us about something called "Lighning Talks". People were supposed to walk on stage, get the mike for two minutes and talk about whatever they want. I was a bit suspicious of the concept but it works. Speakers don't have time to dally around (setting up the laptop counts against the two minutes!) and get their point over quickly. A nice way to close a conference.

All in all, a positive experience. If possible, I'll attend the Jazoon'08.

Back from JaZOOn, Third Day

There are several ways to rate a conference. Here is mine: How many time do you spend bored in the lobby/outside the conference and/or how often do you wish you were bored outside of the talk you're currently sitting in?

Looking at it from this angle, Jazoon is doing great. Go, guys, go!

The keynotes today was Eclipse Way to Jazz by Erich Gamma. It took me some time to figure out what Jazz actually is. There was no abstract and Erich rushed us through the talk. Apparently, it's a tool to design a software process in the Eclipse way: Help you to get your things done without getting in the way (at least as long as you can keep the pointy haired boss (PHB) away from it). This looks pretty promising, even for a process-hater like me (seen too many processes imposed by PHB's who think anything can be solved by micro-management) since it allows you to keep track of all the info (for example all bugs, the state of the current build(s), messages from team colleagues, your todo-list) in the IDE so you don't have to go back and forth between tools to keep track of all this non-coding work.

It's planned to be a commercial tool which is understandable but still a pity. OTOH, how many OSS projects need to keep a schedule? Some part might be available for free but not Open Source. We'll see. I was impressed with the UI which looks pretty slick for a Java app, even when using SWT and forms.

Next in my schedule was of course "Why can Groovy succeed?" held by Mike Müller. Many nice arguments but I was missing the main point: Groovy (or any other language or Java library or whatever) will succeed as soon as one of the main players (IBM, Sun, etc.) adopts it. Large customers (= those who pay bills which get converted into developer paychecks in turn) will not adopt anything that isn't backed by big companies. I've heard that "Oracle backs Groovy and Grails" which is promising but, despite Larry being one of the richest men in the world, well, Oracle is not IBM. I don't want to be the bad guy here but ... well ... let me put it this way: If you plan to buy a new telephone, are you going to ask your plumber which brand you should get?

Sun's support is half-hearted at best ("We don't care which language it is as long as it runs on the Java VM"). Let's see if IBM can afford to spare some attention. If you want to learn more about Oracle's stance, here is a press release. Good luck to them.

Next, JavaFX. I'm someone with broad interests and I know a bit about design, too, and layout. For example, I know what a "river" is (when whitespace in adjacent lines creates verticals gaps in texts that irritate the eye) and I'm using TeX to layout my texts (which not only formats it nicely but also gives me feedback how "bad" a paragraph looks). When I first heard about JavaFX, it was just another UI description language. Oh bother. Instead of creating a good UI builder like Adobe's Flex 2, they created another programming language. And no, Matisse doesn't cut it. Matisse does Swing and a swing is something kids have in the backyard. It's a toy. In 2007, Swing UI elements still can't be connected to bean properties without the help of some extra library. In 3.3, Eclipse at least comes with the binding framework.

Back to JavaFX. Designers will never ever touch a text editor even if their lives depend on it! They use Photoshop or Illustrator or Flex. Tools that can do all kinds of amazing things with just using your mouse or *gasp* a pen tablet. Any software developers here? Who has a pen tablet attached to his computer? Ever used one? Forget about text editors. That's just like asking your boss: "Why don't you come to work with a VW Golf instead of your Lamborghini? I would feel much better!"

"Who cares what you feel? Get to work! The rates for my fourth Porsche aren't payed, yet!"

Ahem. Where was I? Oh yes, JavaFX. At the Jazoon, they showed quite a few very nice demos what you can actually achieve. There was the usual boring stuff (showing that you can type in some code and the result of that code is shown in near-realtime) but they also converted the Tesla Motors website into a JavaFX app which looked and behaved so similar that you could only tell the difference by looking at the header of the window (one had the browser toolbar in it). Nice and smooth transitions. JavaFX connects Swing, Java 2D and it supports data binding, something that should have been in Swing 1.0 (when it was still called JFC).

Unfortunately, they didn't show how the code (i.e. how many horrible hacks they had to use to make it work) but apparently, you can download the demo and see for yourself. So it looked pretty slick and nice and appealing. I'm just not really convinced that the designers will swallow the JavaFX pill. Sun is concerned that there is no compiler for JavaFX, yet, but designers don't care about compilers. They care if they can do anything from their pen tablets. A designer will only touch her keyboard when she has to add the few lines of text to her work.

On the positive side, Anatoli and Greg gave a great show. Thanks, guys! For all the companies out there who think about sending someone to present them at a conference: Send two guys who get a long with each other very well. That way, one of them can do the presentation and the other can use her/his head to keep things interesting. Also, that way, more of your staff gets free conference passes. Win-win.

A short break during which I rode the elevator with Bruce Willis. Well, not actually Bruce Willis but his character John McLane. And not the character as such but an image of him. Many in fact. Thousands. 24 * 60 * 60 ... bc to the rescue ... 86'400 ... but he's not on all of them ... say 50% ... that makes roughly 43'200 images of John McLane, give or take 5'000. If you still don't know what I'm talking about: I was riding in the elevator when the cinema staff brought the second reel of the movie Live Free or Die Hard (called "Die Hard 4.0" in Europe) was brought in. I had a camera with me but I was too upset to think of taking a picture. You'll have to believe me. I really was in that elevator ...

The last show in the morning was Revisiting the Anything Pattern. An "Anything" is a data structure which has properties of a list (it keeps the order in which elements are inserted) and a hash (you can attach names to items of the list and access them by name). Nice and powerful, especially for configuration-like data. The guys around Stefan Tramm extended the original code so you can now read JDBC ResultSet's into an Anything and write them back into the same or another database. Nice stuff. There is a google project at http://code.google.com/p/java-anything/. You can find the source at http://java-anything.googlecode.com/svn/trunk/. Don't be confused that there are two directories there: "initial-release" is the original code as Stefan got it and "starting-release" contains the extensions of him and his team (including the DAO code). Use that one.

In the afternoon, we all enjoyed Die Hard 4. Nice movie, lot's of action and good characters. Go watch it.

Tuesday, June 26, 2007

Back from JaZOOn, Second Day

Well, modern medicine worked it's usual miracle and my brain was much less clogged today. I went to the keynotes but left a bit disappointed. The history of the web and REST was nice to see but my interest in the past is usually reduced to use it as a source for cynical comments about mistakes that bite us today, and there wasn't much in it for me in that regard. The second talk just contained nothing that I didn't knew already. Well, you can't always win.

Next, I went to see a software demonstration (Automated (J)Unit Testing) but I had seen that one before so I left early and attended Hibernate Search: Unstructured Search for Hibernate instead. The group around Emmanuel Bernard managed to extend the query API of Hibernate for Apache Lucene. Nice work, easy to use, looks promising. If you have a web application which allows users to search for something, this is definitively something you should try. Like Google, you can offer a single text field and the search results will be ranked in an intelligent way. Cool.

After lunch, I enjoyed the The Zen of jMaki. They have started to collect all and every JavaScript Web widget set out there, wrapped all of them in the same way, so they get much more simple to use. I don't like JSP's and tag-libraries but they have done a nice job and the demos looked real enough to believe that this can actually help.

In the same room, I watched David Nuescheler Blitzing the Content Repository: AJAX meets JCR. He developed a little JavaScript library called "R-JAX" which allows to create something that resembles CRUD with a JCR and a few lines of HTML. Since you can access the Content Repository via HTTP, all you need to do is to copy all files (JavaScript, HTML, CSS, etc.) into the repository and then make sure you use the right (relative) URLs and you were ready to go. This JCR stuff also looks very interesting. I hope I'll find the time to have a closer look at Apache Jackrabbit one of these days.

Of course, when you do a lot of AJAX, you need to test it somehow. Ed Burns held the talk Java Platform Automated Testing of Ajax Applications where he compared four different tools to do this (some commercial, some OSS) and Webclient a.k.a. MCP (Mozilla Control Program) which allows to embed a web browser in a Java program and control it from a unit test (so you can load a web page, examine it, check AJAX requests, etc). GWT gets you only so far with their own testing framework (especially since it's insane to setup and some things (like UI elements) can't be tested at all. MCP solves all that but you have to deploy the webapp somewhere. Choose your poison.

Right now, MCP can only run Firefox (but they are working on getting at least IE on Windows). It would be nice to see the same integration on Linux using the IEs4Linux project. You did know that you can run IE on Linux, didn't you? Not that anyone ever wanted (except for those web pages which stubbornly refuse to display correctly in Firefox ... and for those, who insist on Flash 123.5 which will come for Linux in 2150 ... but who needs them anyway).

The next talk was obvious: Java and Scripting: One VM, Many Languages. Rags Srinivas (with hat!) showed us around the Java Scripting API. Pretty low level presentation with little new information. I had hoped for more meat here. The only interesting he mentioned was that Sun doesn't really care about dynamic languages per se. They care that as many of them as possibly run on the Java VM but not the languages themselves. That probably explains the strange maneuvering in the last months: Hiring key Ruby developers, working on standardizing Groovy (JSR 241 and then suddenly JavaFX is the Next Great Thing(TM). Actually, JavaFX just seems to be another building block in a growing forest (some would say swamp) of dynamic languages flourishing around Java.

Smells a lot like .NET (one runtime, any language you like) and probably makes sense. There are so many common problems (Singletons, DB access, HTML generation, mixing HTML and Java) which you can't really do well in Java but perfectly well in other languages which don't (have to) drag the Java legacy along. Java is ten years old, now, and it begins to show. GC was a fantastic new feature when Java came out, but today, every contender for the language of the next decade can do that. In Java, Beans, lists, maps and other, important types and concepts are second class citizens. To create a simple list and sort it, you have to write ten lines of code. In Groovy, you write:

def list = ['a', 1, 'b']

1 is of course turned into an Integer. Try that in Java 5 and the vital information, the data in the list, is drowned in syntax to club the compiler into silence:

import java.util.Arrays;
import java.util.List;

public class Foo {
    List list = Arrays.asList (new Object[] { 'a', 1, 'b' });
}

The sad part is that I had to start Eclipse to make sure that the syntax is correct. The Java code is six times as long and only 1/6th of that is actual information. The rest is only there to make the compiler happy. :-(

Back to Jazoon. I would have loved to attent the BOF's, especially the ones registered by Neil M. Gafter about Java Closures and something else (I forgot) but I still wasn't too well and didn't want to risk to have to miss the last two days.

All in all, I enjoyed this day. My thanks go to the JUGS guys for organizing it.

Back from JaZOOn, First Day

During the keynote speeches, someone mentioned that the streetcar no. 5, which goes to Jazoon'07, also goes to the zoo of Zurich. The good news was that the zoo was at the other end of the line, so JaZOOn (which apparently doesn't mean anything) is either not related to the zoo or it's related in such a way that it's the opposite.

I kind of disagree. A zoo is a place where you can see things that you normally can't and in a safe way. In this regard, Jazoon is a zoo full of Java animals and I'm a happy part of it.

Yesterday, I attended the keynote given by Ted Neward which was "Why the Next Five Years Will Be About Languages". He mentioned a lot of interesting things, like:

  • Tools to build custom languages (a.k.a DSL's) become more simple, more powerful, more widespread
  • The need to use there tools grows because it takes so much to formulate some things in general purpose languages like Java. What was great ten years ago seems clumsy today.
  • There is a plethora of languages that run on the Java VM (which is not Java(TM)) like Groovy, JRuby, Jython, Nice, Rhino (see here for a more complete list). He mentioned something like 200 languages using the VM besides Java but my memory could fail me here.

For me, this means that my own talk What's Wrong With Java?, where I compare Java, Groovy and Python, probably wasn't that far off. Of course, I was pretty nervous how people at a Java conference would take it (plus I got sick on the weekend, so I had to take so many drugs to be able to give the talk that, if I had fallen into the Lake of Zurich, they would have had to pump it dry and deposit the water as medical waste ;-) ... anyway ...).

Moreover, I had to rush through my talk because the time limits were really tight. All in all, I felt my performance could have been better but the critics seem fair. (see Fabrizio Gianneschi's comment, thomas and another blog). Also, the room in my talk was full of people; something I haven't seen for any other talk since (which probably means that I attend the wrong ones ;-)) and comments at the show were good, too (but I can't prove it).

I was thinking about registering a BOF but I just don't feel well enough, so I'll expand my thoughts and ideas a bit more here where space and time are only limited by your and my endurance. And you can think about your comments before sharing them with the world. Win-win, I'd say.

Back to Jazoon. After my own talk, I attended Space Based Architecture - Scalable as Google, Simple as Spring. The talk itself was interesting and made sense; unfortunately, my body demanded sleep and it takes what it can't get. So if you want to know any details, ask the person who sat next to me. I can only pray that I didn't snore. Not the fault of the speaker, I swear!

After having restored some of my energy, I went to see Impossible Possibilities - Programming Java an Unusual Way. The presenter, Michael Wiedeking, has the same problem with English as I: Great pronunciation but small built-in dictionary. Still, I could get what he talked about. He presented a way to implement a generator/corouting in Java 5. The basic idea here is that you have a piece of code which can return something to the caller and then continue it's work when the caller calls it again. Confused? Here is an example:

def parse(filename):
    handle = file(filename, 'r')
    while True:
        line = handle.readline()
        if line[0] == '#':
          continue
        yield line
        # <-- If you call parse() a second time, you will be here.
    handle.close()

parse() throws away every line that starts with a hash (#) and returns ("yields") all the rest. The interesting part is when you call parse a second time: It will not start with the line where a new file is opened but it will continue with the next statement after "yield", therefore reading the next line in the already opened file.

In Python, you can have as many yields in one method or function as you like. They work with recursion and exceptions. This way, you can run a complex algorithm until a certain point (when you have a first result to return), return it and then go on as if the return had never happened. You don't have to worry about local variables, closing the file handle, control flow. The language all handles it for you.

If Java, you achieve the same thing with two threads and about four or five hoops to jump through. This is the difference between a modern dynamic language like Python or Ruby: There are completely new ways to do things that are very powerful, simple to understand and (almost) impossible to do in Java.

I spend the rest of the day with Michael Wiedeking and Neil M. Gafter, arguing about checked exceptions until I was to tired that I crept home and went to bed.