Curious if the the originally planned coin null-safe method invocation feature **for Java 7 **comes in to play on this discussion?
Eric Reference: - http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000047.html** - http://metoojava.wordpress.com/2010/11/15/java-7-awesome-features/ On Sunday, June 3, 2012 9:43:48 PM UTC-5, Cédric Beust ♔ wrote: > > I just listened to the latest podcast and I'm a bit surprised by the > explanation that Dick gave about Scala's Option type, so I thought I'd make > a few comments (and congratulations to Tor and Carl for pressing Dick to > clarify some of the things he said). > > First of all, Option's effect is 100% runtime, not static. It's nothing > like @Nonnull or @Nullable. Dick, can you explain why you said that Option > added static checking? > > If you want to get an intuition for Option, it's described in details in > the GOF book (1994!) under the name "Null Object Design Pattern" (here is > the wikipedia entry <http://en.wikipedia.org/wiki/Null_Object_pattern>, > although it doesn't mention the GOF book so maybe I'm misremembering). > > The idea behind Option is for the program to continue working even if a > method is invoked on a "null" (called "None" in Scala and "Nothing" in > Haskell) object. Obviously, null checks are still present but since they > are hidden inside the Option object, code that operates on these objects > can be oblivious to them. In other words, if f is an Option of any type, > f.foo() will never crash. Either it will actually call foo if there is an > object inside the Option or it will do nothing if there is no object. > > Here are some of the problems with this approach. > > Let's say that you have an HTTP request object and you want to see if a > GET parameter is present. Since this parameter could not be there, it's > reasonable to use an Option[String]: > > class HttpRequest { > def getParameter(val name: String) : Option[String] { ... > > > Now that you have this parameter wrapped in an option, you want to pass it > to another method. Either that method takes a String or an Option[String]: > > 1) def process(val param: String) { ... } > 2) def process(val param: Option[String]) { ... } > > In the first case, you have two choices: 1a) either you extract that > string from the option or, if that process() method belongs to you and you > can change it, 1b) you can modify its signature to accept an Option[String] > instead of a String (and obviously, you need to change its implementation > as well). > > The 1a) case is basically checking against null, like Java. You will do > something like: > > Option[String] p = req.getParameter("foo") > p match { > case Some(s) : process(s) > case None: _ > } > > You have gained nothing (I touched on this particular scenario in this > blog > post<http://beust.com/weblog/2010/07/28/why-scalas-option-and-haskells-maybe-types-wont-save-you-from-null/> > ). > > If 1b) is an option (no pun intended) to you, you go ahead and modify your > process() method to accept an Option, and your modified code will probably > have some matching code as shown above. And if you don't do it at this > level, you will, eventually, have to extract that value from the Option. > > Scenario 2) is the best of both worlds: you have two methods that > communicate with each other in terms of Option, and this buys you some nice > properties (composability). > > As you can see from this short description, the benefit of Option is > directly proportional to how many of your API's support Options. This is > often referred to as the "Midas effect", something that used to plague the > C++ world with the `const` keyword. The direct consequence is that you end > up reading API docs with method signatures that contain a lot of Options in > them. > > The problem with this rosy scenario is that you can't ignore the Java > world, and as soon as you try to interoperate with it, you will be dealing > with raw (non Option) values). So the scenario 1) above is, sadly, common. > > Another dark side of Options is that they tend to sweep errors under the > rug. You definitely see a lot less NPE's when you use options, because what > is happening is that your code is happily working on nonexistent objects > (by doing nothing) instead of blowing up. That's fine if your logic is > expected to sometimes return nonexistent objects but there are times when > you are dealing with Options that should never contain None. The correct > thing to do here would be to leave the Option world, extract the underlying > object and keep passing this, but then you are back to the interop problems > described above between raw objects and boxed ones. > > Debugging applications that have misbehaving Option objects is quite > challenging because the symptoms are subtle. You put a break point into > your code, look into the Option and realize that it's a None while you > would expect a Some. And now, you have to figure out what part of your code > returned a None instead of a Some, and Option doesn't have enough > contextual data to give you this information (some third party libraries > attempt to fix that by providing improved Options, e.g. scalaz's > Validation). > > This is why I think of Options as having a tendency to "sweep errors under > the rug". > > From a practical standpoint, I think that the "Elvis" approach which I > first saw in Groovy and which is also available in Fantom and Kotlin is the > best of both worlds. It doesn't offer the nice monadic properties that > Option gives you, but it comes at a much cheaper price and less boiler > plate. > > Finally, Option is still an interesting beast to study since it's a > gateway drug to monads. You probably guessed it by now but Option is a > monad, and understanding some of the properties that it exhibits (e.g. you > can chain several options) is a good first step toward getting a good > understanding of the appeal of monads, and from then on, functors and > applicatives are just a short block away. > > Dick, would love to get more details on what you were explaining during > that podcast! > > -- > Cédric > > > On Sunday, June 3, 2012 9:43:48 PM UTC-5, Cédric Beust ♔ wrote: > > I just listened to the latest podcast and I'm a bit surprised by the > explanation that Dick gave about Scala's Option type, so I thought I'd make > a few comments (and congratulations to Tor and Carl for pressing Dick to > clarify some of the things he said). > > First of all, Option's effect is 100% runtime, not static. It's nothing > like @Nonnull or @Nullable. Dick, can you explain why you said that Option > added static checking? > > If you want to get an intuition for Option, it's described in details in > the GOF book (1994!) under the name "Null Object Design Pattern" (here is > the wikipedia entry <http://en.wikipedia.org/wiki/Null_Object_pattern>, > although it doesn't mention the GOF book so maybe I'm misremembering). > > The idea behind Option is for the program to continue working even if a > method is invoked on a "null" (called "None" in Scala and "Nothing" in > Haskell) object. Obviously, null checks are still present but since they > are hidden inside the Option object, code that operates on these objects > can be oblivious to them. In other words, if f is an Option of any type, > f.foo() will never crash. Either it will actually call foo if there is an > object inside the Option or it will do nothing if there is no object. > > Here are some of the problems with this approach. > > Let's say that you have an HTTP request object and you want to see if a > GET parameter is present. Since this parameter could not be there, it's > reasonable to use an Option[String]: > > class HttpRequest { > def getParameter(val name: String) : Option[String] { ... > > > Now that you have this parameter wrapped in an option, you want to pass it > to another method. Either that method takes a String or an Option[String]: > > 1) def process(val param: String) { ... } > 2) def process(val param: Option[String]) { ... } > > In the first case, you have two choices: 1a) either you extract that > string from the option or, if that process() method belongs to you and you > can change it, 1b) you can modify its signature to accept an Option[String] > instead of a String (and obviously, you need to change its implementation > as well). > > The 1a) case is basically checking against null, like Java. You will do > something like: > > Option[String] p = req.getParameter("foo") > p match { > case Some(s) : process(s) > case None: _ > } > > You have gained nothing (I touched on this particular scenario in this > blog > post<http://beust.com/weblog/2010/07/28/why-scalas-option-and-haskells-maybe-types-wont-save-you-from-null/> > ). > > If 1b) is an option (no pun intended) to you, you go ahead and modify your > process() method to accept an Option, and your modified code will probably > have some matching code as shown above. And if you don't do it at this > level, you will, eventually, have to extract that value from the Option. > > Scenario 2) is the best of both worlds: you have two methods that > communicate with each other in terms of Option, and this buys you some nice > properties (composability). > > As you can see from this short description, the benefit of Option is > directly proportional to how many of your API's support Options. This is > often referred to as the "Midas effect", something that used to plague the > C++ world with the `const` keyword. The direct consequence is that you end > up reading API docs with method signatures that contain a lot of Options in > them. > > The problem with this rosy scenario is that you can't ignore the Java > world, and as soon as you try to interoperate with it, you will be dealing > with raw (non Option) values). So the scenario 1) above is, sadly, common. > > Another dark side of Options is that they tend to sweep errors under the > rug. You definitely see a lot less NPE's when you use options, because what > is happening is that your code is happily working on nonexistent objects > (by doing nothing) instead of blowing up. That's fine if your logic is > expected to sometimes return nonexistent objects but there are times when > you are dealing with Options that should never contain None. The correct > thing to do here would be to leave the Option world, extract the underlying > object and keep passing this, but then you are back to the interop problems > described above between raw objects and boxed ones. > > Debugging applications that have misbehaving Option objects is quite > challenging because the symptoms are subtle. You put a break point into > your code, look into the Option and realize that it's a None while you > would expect a Some. And now, you have to figure out what part of your code > returned a None instead of a Some, and Option doesn't have enough > contextual data to give you this information (some third party libraries > attempt to fix that by providing improved Options, e.g. scalaz's > Validation). > > This is why I think of Options as having a tendency to "sweep errors under > the rug". > > From a practical standpoint, I think that the "Elvis" approach which I > first saw in Groovy and which is also available in Fantom and Kotlin is the > best of both worlds. It doesn't offer the nice monadic properties that > Option gives you, but it comes at a much cheaper price and less boiler > plate. > > Finally, Option is still an interesting beast to study since it's a > gateway drug to monads. You probably guessed it by now but Option is a > monad, and understanding some of the properties that it exhibits (e.g. you > can chain several options) is a good first step toward getting a good > understanding of the appeal of monads, and from then on, functors and > applicatives are just a short block away. > > Dick, would love to get more details on what you were explaining during > that podcast! > > -- > Cédric > > > -- You received this message because you are subscribed to the Google Groups "Java Posse" group. To view this discussion on the web visit https://groups.google.com/d/msg/javaposse/-/MZv__a_7al4J. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.
