Oops - that should have been

for (p <- person; a <- p.address; z <- a.zipCode) yield z

Said I was tired didn't I? :-)

On Sunday, June 3, 2012 7:43:48 PM UTC-7, 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/-/I3BXOuP6a4kJ.
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.

Reply via email to