I'm convinced everytime I have to manually write the try catch clause for parse a kitten dies somewhere!
I'm convinced everytime I have to manually write the try catch clause for parse a kitten dies somewhere!
It's sort of ironic that the JVM, with it's limited Java-only bytecode has attracted so many languages, while the CLR, which is designed to handle multiple languages in an efficient manner, has relatively few.
But it occurred to me that even if they did so, a lot of people wouldn't trust them to continue to support the other platforms indefinitely. The only way around that would be for them to spin off the entire .NET division.
Microsoft being Microsoft, of course, they would never do any of this.
The way Scala (and probably other functional languages, with which i am not familiar) handle this is with a little bit of polymorphism. Using Java syntax, parsing a string into integer would return a Validation<Integer, Exception>, an abstract type which could be either a Failure<Exception> or Success<Integer>. This then exposes methods like ifSuccess(Consumer<Integer>) (it's called something less obvious in Scala, because that's how Scala works) and ifFailure(Consumer<Exception>), and various other useful things.
This seems a bit weird at first glance, but it makes it quite easy to deal specifically with either success or failure, or both, or to defer dealing with them until later (you can put a load of Validation objects in a set and worry about whether they're successful or failed later on). It also makes it impossible to ignore failure - there is no error code to forget to check, and no unchecked exception to forget to write a catch block for.
int res;
if int.TryParse(s, out res) { // OK } { else // not ok }
You certainly do not need an exception to deal with the simple case of "did this string parse into an int".Edit: A great alternative signature is to use Maybe/Option, so you get Some int or None.
match int.TryParse s with
| None -> ...
| Some i -> ...int res = int.TryParse(s, 0); // 0 as the default if parsing fails
Of course if there is no reasonable default you should bubble the thing up anyway or handle it on the spot. But very often for input parsing there is sane default you can choose.
int res;
try { res = Integer.parseInt( s ); } // if part
catch ( NumberFormatException nfe ) { } // else part
The words are different (try/catch instead of if/else), but still 2 blocks of code with similar syntax...Another reason is composability. If you're checking several values together, returning a Maybe/Option is much more clear and usable.
if(Int.CanParse(s))
{
i = Int.Parse(s);
// OK things.
}
else
{
// Not ok.
}
but it also be weird in Java because Parse throws and exception, so you'd have to either write an empty catch block or declare the method with a throw clause, event though it actually doesn't throw anything.Similarly, C# has TryGet where in Java, you need a containsKey/get combo, or have to assume your collections do not store nulls.
I do think C# could do better, though. Neither C# nor Java have the equivalent of "insert ... on duplicate key ..." for collections. You now have to do:
items.TryGet( key, out value);
items[key] = value + 1;
In C++, that would just be: items[key] += 1;