Add ML style exception handling

ML has a very elegant exception handling syntax. You can write:
```ml
hd [] handle Empty => "the list is empty"
```
and it'll return `"the list is empty"` - if there were any items in the list it would have returned the first item instead. Since there is no need to wrap the expression in a `try` block, this style remains elegant and readable even when you have a complex expression with multiple points where you want to catch errors.

It is possible to get something close in D using lazy arguments and function-method interchanging. I've added the `ifThrown` function to `std.exception` that does just that:
```D
string[] arr=[];
writeln( arr[0].ifThrown!RangeError("the array is empty") );
```

It's not as elegant as ML, since ML has it built in as a syntax and it has better type inference, but I've tried it in a project and it provided much more elegant code than the `try`-`catch` blocks it replaced.

Even more important than elegance, `ifThrown` allows you to catch and handle an exception mid-expression. This allows, for example, to handle exceptions while declaring constants:
```D
const port=args[1].to!int().ifThrown!ConvException(8080);
```
Or while passing arguments to a function:
```D
foo(someString.to!int().ifThrown!ConvException(0));
```