+1 as you can't fight the future, but clear warning signs ahead would be helpful :)
Just be careful that it's not an exact equivalent to *match*, else we can get confused by behavior like this: *scala> class parentdefined class parent* *scala> class child1 extends parentdefined class child1* *scala> class child2 extends parentdefined class child2* *scala> Option("abc") match { case None => new child1 ; case _ => new child2 } res16: parent = child2@9d9347d* *scala> Option("abc").fold { new child1 } { _ => new child2 }<console>:11: error: type mismatch; found : child2 required: child1 Option("abc").fold { new child1 } { _ => new child2 }* *scala> Option("abc").fold { new child1 : parent } { _ => new child2 } res14: parent = child2@58a470a8* -- Christopher T. Nguyen Co-founder & CEO, Adatao <http://adatao.com> linkedin.com/in/ctnguyen On Thu, Dec 26, 2013 at 12:54 PM, Michael (Bach) Bui <free...@adatao.com>wrote: > +1. > > It is a little bit harder to read for new comers but not really a big deal. > > > > > On Dec 26, 2013, at 2:33 PM, Mark Hamstra <m...@clearstorydata.com> wrote: > > > In code added to Spark over the past several months, I'm glad to see more > > use of `foreach`, `for`, `map` and `flatMap` over `Option` instead of > > pattern matching boilerplate. There are opportunities to push `Option` > > idioms even further now that we are using Scala 2.10 in master, but I > want > > to discuss the issue here a little bit before committing code whose form > > may be a little unfamiliar to some Spark developers. > > > > In particular, I really like the use of `fold` with `Option` to cleanly > an > > concisely express the "do something if the Option is None; do something > > else with the thing contained in the Option if it is Some" code fragment. > > > > An example: > > > > Instead of... > > > > val driver = drivers.find(_.id == driverId) > > driver match { > > case Some(d) => > > if (waitingDrivers.contains(d)) { waitingDrivers -= d } > > else { > > d.worker.foreach { w => > > w.actor ! KillDriver(driverId) > > } > > } > > val msg = s"Kill request for $driverId submitted" > > logInfo(msg) > > sender ! KillDriverResponse(true, msg) > > case None => > > val msg = s"Could not find running driver $driverId" > > logWarning(msg) > > sender ! KillDriverResponse(false, msg) > > } > > > > ...using fold we end up with... > > > > driver.fold > > { > > val msg = s"Could not find running driver $driverId" > > logWarning(msg) > > sender ! KillDriverResponse(false, msg) > > } > > { d => > > if (waitingDrivers.contains(d)) { waitingDrivers -= d } > > else { > > d.worker.foreach { w => > > w.actor ! KillDriver(driverId) > > } > > } > > val msg = s"Kill request for $driverId submitted" > > logInfo(msg) > > sender ! KillDriverResponse(true, msg) > > } > > > > > > So the basic pattern (and my proposed formatting standard) for folding > over > > an `Option[A]` from which you need to produce a B (which may be Unit if > > you're only interested in side effects) is: > > > > anOption.fold > > { > > // something that evaluates to a B if anOption = None > > } > > { a => > > // something that transforms `a` into a B if anOption = Some(a) > > } > > > > > > Any thoughts? Does anyone really, really hate this style of coding and > > oppose its use in Spark? > >