T LIN KEDIN LIVIN G SO C IAL Q U O RA REM EM BER TH E M ILK SEESM IC STAC KM O B TW ITTER TU M BLR VM W ARE YAM M ER N O VEL AO L BO X E-H ARM O N Y http://www.quora.com/Startups/What-startups-or-tech-companies-are-using-Scala
support for map, flatmap, tabulate, filter, foreach... Traits, classes, case classes, object... Attach behaviors at runtime. new Foo with Other Flexible syntax, create constructs, infix support, everything is a value val test = if(...) val collection = for(...) Emphasis on immutable data structures. Transformations and copies vs state Built in support for this high concurrency pattern IMMUTABILITY EMPHASIS FUNCTIONAL OOP ACTORS MIXINS IDIOMATIC
need synchronization JAVA List<Integer> even = new ArrayList<Integer>(); for (String num : numbersAsStrings) { int parsedInt = Integer.parseInt(num); if (parsedInt % 2 == 0) { ints.add(parsedInt); } } In Scala we transform values into new values SCALA val ints = for (num <- numbersAsStrings; if num.toInt % 2 == 0) yield num.toInt No need to synchronize in structures which state is never modified
= 1 myInt: Int = 1 scala> def myFunction = "I don't need a return" myFunction: String scala> val result = for (n <- 0 to 10) yield n result: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) scala> val ifAreValues2 = if (true) "test" ifAreValues2: Any = test scala> val ifAreValues3 = if (true) "test" else "test2" ifAreValues3: String = test Functional style encourages to pipe the results of functions and operations Vs Imperative style Iterator.continually(Option(queue.poll(1, TimeUnit.SECONDS))).takeWhile(_ => running) foreach { msg => write(msg) }
messaging system /** invoke your army **/ val emailServiceActor = Akka.system.actorOf( Props[EmailServiceActor].withRouter( SmallestMailboxRouter(nrOfInstances = 50) ), name = "emailService" ) /** send him to war **/ emailServiceActor ! emailMessage /** this is the guy overseeing everything in the pentagon **/ class EmailServiceActor extends Actor{ override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10) { case emailException: EmailException => Restart case unknownCase: Any => Stop } def receive = { case message: Any => context.actorOf(Props[EmailServiceWorker]) ! message } } /** And this one is the one in the field **/ class EmailServiceWorker extends Actor{ /** And this one is the one in the field **/ private var emailMessage: Option[EmailMessage] = None def receive = { case Some(email): EmailMessage => { email.deliveryAttempts = email.deliveryAttempts + 1 email sendEmailSync() } case unexpectedMessage: Any => throw new Exception("can't handle %s" format(unexpectedMessage)) } override def preRestart(reason: Throwable, message: Option[Any]) { context.system.scheduler.scheduleOnce(emailMessage.get.retryOn, self, emailMessage.get) } }
walk = println("I'm walking")} trait Swimmer { def swim = println("I'm swimming")} class Fish extends Swimmer ... val mudSkipper = new Fish() with Walker mudSkipper.walk()