Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Can someone please show the java guys the <Number>.TryParse(String s) from C#?

I'm convinced everytime I have to manually write the try catch clause for parse a kitten dies somewhere!



TryParse uses an out parameter. Java doesn't have that. AFAIK, the JVM has no way to represent pointers in any such fashion.

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.


I started to reply that Microsoft could fix that by providing high-performance CLR implementations on all the platforms the JVM runs on.

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.


To me it's a huge deal how portable my software is. CLR is very much tied to Windows. I know that there are other implementations but they always lag behind.


As a Java programmer, i agree that the catch blocks around parsing are annoying, but i'm not sure a method that returns an error code is any better. Wasn't that tried back in the '80s?

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.


TryParse returns a boolean. So you use it like this:

  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 -> ...


Ah apparently I remembered it wrong. I thought it was

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.


is that really more work than:

  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...


The main reason for TryParse, AFAIK, is avoiding the massive expense of exceptions on the CLR.

Another reason is composability. If you're checking several values together, returning a Maybe/Option is much more clear and usable.


Well, you could substitute that for

     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.


That either is inefficient (you end up parsing each number twice) or requires the compiler to have deep knowledge of the standard library.

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;


You could have a method returning a nullable Integer.


Haskell works the same way.


Since Java doesn't have pass-by-ref, this would probably be just as awkward as try-catch.


Guava's Hints.tryParse is about as good as it can get in Java... Maybe it could return an Optional instead of a nullable boxed type, but the calling code wouldn't be much different.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: