Introduction to   Scala Aleksandar Prokopec EPFL
 
Pragmatic Since 2003 runs on the  JVM Seamless Java interoperability Statically  typed Production ready Martin Odersky Hybrid
Statically  typed
runs on the   JVM
Scala  programs are fast.
OOP   +  FP
“ I can honestly say if someone had shown me the  Programming Scala  book by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I'd probably have never created Groovy.“ James Strachan, creator of Groovy
“ If I were to pick a language to use today other than Java, it would be  Scala .” James Gosling
Pragmatic
Scala  is lightweight.
println( “Hello world!” )
scala> println( “Hello world!” ) Hello world! REPL evaluating expressions on the fly
object  MyApp  extends  App { println( “Hello world!” ) } Compiled version
object  MyApp  extends  App { println( “Hello world!” ) } Singleton  object s no more static methods
object  MyApp { def  main(args: Array[String]) { println( “Hello world!” ) } } Declaring methods
object  MyApp { def  main(args: Array[String]) { var  user: String = args(0) println( “Hello, ” +user+ “!” ) } } Declaring  var iables
object  MyApp { def  main(args: Array[String]) { val  user: String = args(0) println( “Hello, ” +user+ “!” ) } } Declaring  val ues prevents accidental changes
object  MyApp { def  main(args: Array[String]) { val  user = args(0) println( “Hello, ” +user+ “!” ) } } Local type inference less… “typing”
class  StringArrayFactory { def  create : Array[String]  = { val  array:  Array[String]  = Array [String] ( “1” ,  “2” ,  “3” ) array } } Local type inference less… “typing”
class  StringArrayFactory { def  create = { val  array = Array( “1” ,  “2” ,  “3” ) array } } Local type inference less… “typing”
// Scala class  Person( var  name: String, var  age: Int ) Declaring  class es … concisely // Java public class  Person { private  String name; private   int  age; public  Person(String name,  int  age) { this .name = name; this .age = age; } public  String getName() { return  name; } public   int  getAge() { return  age; } public   void  setName(String name) { this .name = name; } public   void  setAge( int  age) { this .age = age; } }
Scala  is object-oriented.
object   Foo   { val  b =  new  ArrayBuffer[Any] } Object-oriented everything’s an object
Object-oriented everything’s an object Any AnyRef AnyVal String Boolean Char Int
object   Foo   { val  b =  new  ArrayBuffer[Any] b += 1 b += 1.toString b += Foo println(b) } Object-oriented everything’s an object
1 + 2 1.+(2) Array(1, 2, 3) ++ Array(4, 5, 6) Array(1, 2, 3).++(Array(4, 5, 6)) 1 :: List(2, 3) List(2, 3).::(1) Operator overloading operators are methods
trait   Iterator[T]   { def  next(): T def  hasNext: Boolean } Declaring  trait s traits are like interfaces
trait   Iterator[T]   { def  next(): T def  hasNext: Boolean def   printAll() = while   (hasNext) println(next()) } Declaring  trait s traits are rich
trait   Animal Multiple inheritance traits are composable
trait   Animal trait   Mammal   extends   Animal { def  think() = println( “hm...” ) } Multiple inheritance traits are composable
trait   Animal trait   Mammal   extends   Animal { def  think() = println( “hm...” ) } trait   Bird   extends   Animal { def  layEgg() = System.createEgg() } Multiple inheritance traits are composable
 
trait   Animal trait   Mammal   extends   Animal { def  think() = println( “hm...” ) } trait   Bird   extends   Animal { def  layEgg() = System.createEgg() } class  Platypus  extends  Bird  with  Mammal Mixin  composition traits are composable
trait   Animal trait  Reptile  extends  Animal { def  layInTheSun : Unit  = {} } class  Dog(name: String)  extends  Mammal new  Dog( “Nera” )  with  Reptile Dynamic  mixin composition … or composition “on the fly”
Cake pattern
trait   Logging { def  log(msg: String) } trait  AnsweringMachine { self: Logging  with  DAO  with  Protocol  => log( “Initializing.” ) ... } Self -types to express requirements
trait  ConsoleLogging { def   log(msg: String) = println(msg) } class  LocalAnsweringMachine extends  AnsweringMachine with  ConsoleLogging with  H2DAO with  JabberProtocol Cake pattern layers above layers
Scala  is functional.
(x: Int)  =>  x + 1 First class functions
val  doub : Int => Int  = (x: Int)  =>  x * 2 doub(1)    2 First class  functions functions are objects too
val  doub = (x: Int)  =>  x * 2 List(1, 2, 3).map(doub)    List(2, 4, 6) First class functions as higher order parameters
List [Int] (1, 2, 3).map((x: Int)  =>  x * 2) // more type inference List(1, 2, 3).map(x  =>  x * 2) // or even shorter List(1, 2, 3).map(_ * 2) Functions with  sugar make code sweeter
var  step = 1 val  inc = x  =>  x + step inc(5)    6 step = 2 inc(5)    7 Closures functions that “capture” their environment
// Java button.addMouseListener( new  MouseAdapter() { public void  mouseEntered(MouseEvent e) { System.out.println(e); } } // Scala listenTo(button) reactions += {  case  e  =>  println(e) } First class functions because you write them in Java all the time
Pattern matching
Pattern matching … is concise // Scala reactions += { case  m: MouseEntered  => println( “I see it!” ) case  m: MouseExited  => println( “Lost it.” ) case  m: MouseClicked  => println( “Poked!” ) } // Java button.addMouseListener( new  MouseAdapter() { public void  mousePressed(MouseEvent e) {} public void  mouseReleased(MouseEvent e) {} public void  mouseEntered(MouseEvent e) {} public void  mouseEntered(MouseEvent e) { System.out.println( “I see it!” ); } public void  mouseExited(MouseEvent e) { System.out.println( “Lost it.” ); } public void  mouseClicked(MouseEvent e) { System.out.println( “Poked!” ); } } // ...alternative - isinstanceof
trait  Tree case class  Node(l: Tree, r: Tree) extends  Tree case object  Leaf extends  Tree Pattern  matching … is precise
def  b(t: Tree): Int = t  match  { case  Node(Leaf, Node(_, _)) | Node(Node(_, _), Leaf)  =>  -1 case  Node(l, r)  => val  (ld, rd) =   (b(l), b(r)) if  (ld == rd) ld + 1  else  -1 case  Leaf  =>  0 case  _  =>  error( “Unknown tree!” ) } Pattern  matching … is precise
sealed trait  Tree ... def  b(t: Tree): Int = t  match  { case  Node(Leaf, Node(_, _)) | Node(Node(_, _), Leaf)  =>  -1 case  Node(l, r)  => val  (ld, rd) =   (b(l), b(r)) if  (ld == rd) ld + 1  else  -1 case  Leaf  =>  0 } Pattern  matching … is exhaustive
def  matchingMeSoftly(a: Any): Any = a  match  { case  11  =>   “eleven” case  s: String  =>   “’%s’” .format(s) case   <tag> {t} </tag>   =>  t case  Array(1, 2, 3)  =>  “1, 2, 3” case  head :: tail   =>  tail case  _  => null } Pattern matching … is extensible
Lazyness
lazy  values don’t compute if there’s no demand class  User(id: Int) { lazy val  followernum =  from(followers)(f  => where(id === f.fid) compute(countDistinct(f.fid)) ) }
Call by name evaluate only when you have to def  withErrorOut(body:  => Unit) = { val  old = Console.out Console.setOut(Console.err) try body finally Console.setOut(old) } ... withErrorOut { if (n < 0) println( “n too small” ) }
Stream s lazy lists e = ∑ 1/n!   = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + …
Stream s lazy lists e = ∑ 1/n!   = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + … 0! ?
Stream s lazy lists e = ∑ 1/n!   = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + … 0! 1! 2! 3! ? 0! ?
Stream s lazy lists e = ∑ 1/n!   = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + … 0! 1! 2! 3! ? 0! ? 0! 1/1! 1/2! 1/3! ?
Stream s lazy lists def   fact(n: Int, p: Int): Stream[Int] =  p #:: fact(n + 1, p * (n + 1)) val  factorials = fact(0, 1) val  e = factorials.map(1./_).take(10).sum
Scala  is expressive.
for  comprehensions traverse anything for  (x <- List(1, 2, 3)) println(x) List(1, 2, 3).foreach(x => println(x)) for  (x <- 0 until 10) println(x) (0 until 10).foreach(x => println(x)) Range(0, 10, 1).foreach(x => println(x))
for  comprehensions map anything for  (x <- List(1, 2, 3))  yield  x * 2 List(1, 2, 3).map(x => x * 2) for  (x <- List(1, 2); y <- List(1, 2)) yield  x * y List(1, 2).flatMap(x => List(1, 2).map(y => x * y) )    List(1, 2, 2, 4)
for  comprehensions like SQL queries for  { p <- people if  p.age > 25 s <- schools if  p.degree == s.degree }  yield  (p, s) // pairs of people older than 25 and // schools they possibly attended
Collections easy to create val   phonebook = Map( “ Jean”  ->   “123456” , “ Damien”  ->  “666666” ) val  meetings = ArrayBuffer( “ Dante” ,  “Damien” ,  “Sophie” ) println(phonebook(meetings(1)))
Collections high-level combinators // Java boolean  isOk = true for  ( int  i = 0; i < name.length(); i++) { if  (isLetterOrDigit(name.charAt(i)) { isOk =  false ; break ; } }
Collections high-level combinators // Scala name.forall(_.isLetterOrDigit)
Collections high-level combinators // count the total number of different // surnames shared by at least 2 adults people
Collections high-level combinators // count the total number of different // surnames shared by at least 2 adults people.filter(_.age >= 18)
Collections high-level combinators // count the total number of different // surnames shared by at least 2 adults people.filter(_.age >= 18) .groupBy(_.surname) : Map[String, List[Person]]
Collections high-level combinators // count the total number of different // surnames shared by at least 2 adults people.filter(_.age >= 18) .groupBy(_.surname) : Map[String, List[Person]] .count {  case  (s, l)  =>  l.size >= 2 }
List s an immutable sequence val  countdown = List(3, 2, 1) 3 2 1 countdown
List s an immutable sequence val  countdown = List(3, 2, 1) val  longer = 4 :: countdown 3 2 1 4 countdown longer
List s an immutable sequence val  countdown = List(3, 2, 1) val  longer = 4 :: countdown val  fast = 10 :: countdown 3 2 1 4 10 countdown longer fast
List s an immutable sequence val  countdown = List(3, 2, 1) val  longer = 4 :: countdown val  fast = 10 :: countdown val  withzero = countdown ::: List(0) 3 2 1 4 10 3 2 1 0 countdown longer fast withzero
Buffer s mutable sequences val  b = ArrayBuffer(1, 2, 3) b += 4 b += 5 b += 6    ArrayBuffer(1, 2, 3, 4, 5, 6)
Map s mutable or immutable, sorted or unsorted import collection._ val  m = mutable.Map( “Heidfeld”  -> 1, “ Schumacher”  -> 2) m +=  “Hakkinen”  -> 3 val   im = immutable.Map( “Schumacher”  -> 1)
Hash tries persistence through efficient structural sharing val   im0: Map[Int, Int] =  ... im0
Hash tries persistence through efficient structural sharing val   im0: Map[Int, Int] =  ... val  im1 = im0 + (1 -> 1) im0 im1
Hash tries persistence through efficient structural sharing val   im0: Map[Int, Int] =  ... val  im1 = im0 + (1 -> 1) val  im2 = im1 + (2 -> 2) im0 im1 im2
Hash tries persistence through efficient structural sharing val   im0: Map[Int, Int] =  ... val  im1 = im0 + (1 -> 1) val  im2 = im1 + (2 -> 2) val  im3 = im2 + (3 -> 6) im0 im1 im2 im3
Hash tries persistence through efficient structural sharing im0 im1 im2 im3 2x-3x slower lookup 2x faster iteration
Parallel  collections parallelize bulk operations on collections def  cntEqlen(m: Map[String, String]) = { m.par.count { case  (n, s) => n.length == s.length } } // be careful with side-effects
Scala  is extensible.
One ring to rule them all.
actor s road to safer concurrency val  a = actor { react { case  i: Int  =>  println(i) } } ... a ! 5
Custom control flow it’s all about control def  myWhile(c:  => Boolean)(b:  => Unit) { if  (c) { b myWhile(c)(b) } }
Custom control flow it’s all about control @tailrec def  myWhile(c:  => Boolean)(b:  => Unit) { if (c) { b myWhile(c)(b) } }
Custom control flow it’s all about control @tailrec def  myWhile(c:  => Boolean)(b:  => Unit) { if (c) { b myWhile(c)(b) } } var  i = 0 myWhile (i < 5) { i += 1 }
ARM automatic resource management withFile ( “~/.bashrc” ) { f  => for  (l <- f.lines) { if  ( “#” .r.findFirstIn(l) != None) println(l) } }
ScalaTest behavioral testing framework “ A list”  should { “ be a double reverse of itself”  in { val  ls = List(1, 2, 3, 4, 5, 6) ls.reverse.reverse should equal (ls) } }
BaySick Basic DSL in Scala 10 PRINT  “Baysick Lunar Lander v0.9” 20 LET ('dist := 100) 30 LET ('v := 1) 40 LET ('fuel := 1000) 50 LET ('mass := 1000) ...
implicit  conversions augmenting types with new operations ‘ a’ .toUpperCase
implicit  conversions augmenting types with new operations implicit def  charOps(c: Char) =  new  { def  toUpperCase = if  (c >= ‘a’ && c <= ‘z’)   (c – 32).toChar else  c } ... ‘ a’ .toUpperCase
Pimp  my library
implicit  conversions pimping your libraries since 2006 import  scalaj.collection._ val  list =  new  java.util.ArrayList[Int] list.add(1) list.add(2) list.add(3) ... for  (x <- list)  yield  x * 2
implicit  conversions pimping your libraries since 2006 import  scalaj.collection._ val  list =  new  java.util.ArrayList[Int] list.add(1) list.add(2) list.add(3) ... for  (x <- list)  yield  x * 2 // list.map(x => x * 2)
implicit  conversions pimping your libraries since 2006 import  scalaj.collection._ val  list =  new  java.util.ArrayList[Int] list.add(1) list.add(2) list.add(3) ... for  (x <- list)  yield  x * 2 // jlist2slist(list).map(x => x * 2)
implicit  arguments restricting operations on types val  is = SortedSet(1, 2, 3) case class  Man(id: Int) ... implicit object  MenOrd  extends  Ordering[Man] { def  compare(x: Man, y: Man) = x.id – y.id } val  ms = SortedSet(Person(1), Person(2))
STM software transactional memory val  account1 = cell[Int] val  account2 = cell[Int] atomic {  implicit  txn  => if  (account2() >= 50) { account1 += 50 account2 -= 50 } }
Scala  has support.
Building Ant SBT Maven
SBT simple build tool > compile ... > ~compile ... > test ... > package
SBT project definition written in Scala val  scalatest =  “ org.scala-tools.testing”  % “ scalatest”  %  “0.9.5” ... > reload [INFO] Building project ... [INFO]  using sbt.Default ... > update
Tools:  IDEs Eclipse Netbeans IntelliJ IDEA Emacs ENSIME JEdit
Web frameworks
Used by...
Thank you!

Scala presentation by Aleksandar Prokopec

  • 1.
    Introduction to Scala Aleksandar Prokopec EPFL
  • 2.
  • 3.
    Pragmatic Since 2003runs on the JVM Seamless Java interoperability Statically typed Production ready Martin Odersky Hybrid
  • 4.
  • 5.
  • 6.
    Scala programsare fast.
  • 7.
    OOP + FP
  • 8.
    “ I canhonestly say if someone had shown me the  Programming Scala  book by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I'd probably have never created Groovy.“ James Strachan, creator of Groovy
  • 9.
    “ If Iwere to pick a language to use today other than Java, it would be Scala .” James Gosling
  • 10.
  • 11.
    Scala islightweight.
  • 12.
  • 13.
    scala> println( “Helloworld!” ) Hello world! REPL evaluating expressions on the fly
  • 14.
    object MyApp extends App { println( “Hello world!” ) } Compiled version
  • 15.
    object MyApp extends App { println( “Hello world!” ) } Singleton object s no more static methods
  • 16.
    object MyApp{ def main(args: Array[String]) { println( “Hello world!” ) } } Declaring methods
  • 17.
    object MyApp{ def main(args: Array[String]) { var user: String = args(0) println( “Hello, ” +user+ “!” ) } } Declaring var iables
  • 18.
    object MyApp{ def main(args: Array[String]) { val user: String = args(0) println( “Hello, ” +user+ “!” ) } } Declaring val ues prevents accidental changes
  • 19.
    object MyApp{ def main(args: Array[String]) { val user = args(0) println( “Hello, ” +user+ “!” ) } } Local type inference less… “typing”
  • 20.
    class StringArrayFactory{ def create : Array[String] = { val array: Array[String] = Array [String] ( “1” , “2” , “3” ) array } } Local type inference less… “typing”
  • 21.
    class StringArrayFactory{ def create = { val array = Array( “1” , “2” , “3” ) array } } Local type inference less… “typing”
  • 22.
    // Scala class Person( var name: String, var age: Int ) Declaring class es … concisely // Java public class Person { private String name; private int age; public Person(String name, int age) { this .name = name; this .age = age; } public String getName() { return name; } public int getAge() { return age; } public void setName(String name) { this .name = name; } public void setAge( int age) { this .age = age; } }
  • 23.
    Scala isobject-oriented.
  • 24.
    object Foo { val b = new ArrayBuffer[Any] } Object-oriented everything’s an object
  • 25.
    Object-oriented everything’s anobject Any AnyRef AnyVal String Boolean Char Int
  • 26.
    object Foo { val b = new ArrayBuffer[Any] b += 1 b += 1.toString b += Foo println(b) } Object-oriented everything’s an object
  • 27.
    1 + 21.+(2) Array(1, 2, 3) ++ Array(4, 5, 6) Array(1, 2, 3).++(Array(4, 5, 6)) 1 :: List(2, 3) List(2, 3).::(1) Operator overloading operators are methods
  • 28.
    trait Iterator[T] { def next(): T def hasNext: Boolean } Declaring trait s traits are like interfaces
  • 29.
    trait Iterator[T] { def next(): T def hasNext: Boolean def printAll() = while (hasNext) println(next()) } Declaring trait s traits are rich
  • 30.
    trait Animal Multiple inheritance traits are composable
  • 31.
    trait Animal trait Mammal extends Animal { def think() = println( “hm...” ) } Multiple inheritance traits are composable
  • 32.
    trait Animal trait Mammal extends Animal { def think() = println( “hm...” ) } trait Bird extends Animal { def layEgg() = System.createEgg() } Multiple inheritance traits are composable
  • 33.
  • 34.
    trait Animal trait Mammal extends Animal { def think() = println( “hm...” ) } trait Bird extends Animal { def layEgg() = System.createEgg() } class Platypus extends Bird with Mammal Mixin composition traits are composable
  • 35.
    trait Animal trait Reptile extends Animal { def layInTheSun : Unit = {} } class Dog(name: String) extends Mammal new Dog( “Nera” ) with Reptile Dynamic mixin composition … or composition “on the fly”
  • 36.
  • 37.
    trait Logging { def log(msg: String) } trait AnsweringMachine { self: Logging with DAO with Protocol => log( “Initializing.” ) ... } Self -types to express requirements
  • 38.
    trait ConsoleLogging{ def log(msg: String) = println(msg) } class LocalAnsweringMachine extends AnsweringMachine with ConsoleLogging with H2DAO with JabberProtocol Cake pattern layers above layers
  • 39.
    Scala isfunctional.
  • 40.
    (x: Int) => x + 1 First class functions
  • 41.
    val doub: Int => Int = (x: Int) => x * 2 doub(1)  2 First class functions functions are objects too
  • 42.
    val doub= (x: Int) => x * 2 List(1, 2, 3).map(doub)  List(2, 4, 6) First class functions as higher order parameters
  • 43.
    List [Int] (1,2, 3).map((x: Int) => x * 2) // more type inference List(1, 2, 3).map(x => x * 2) // or even shorter List(1, 2, 3).map(_ * 2) Functions with sugar make code sweeter
  • 44.
    var step= 1 val inc = x => x + step inc(5)  6 step = 2 inc(5)  7 Closures functions that “capture” their environment
  • 45.
    // Java button.addMouseListener(new MouseAdapter() { public void mouseEntered(MouseEvent e) { System.out.println(e); } } // Scala listenTo(button) reactions += { case e => println(e) } First class functions because you write them in Java all the time
  • 46.
  • 47.
    Pattern matching …is concise // Scala reactions += { case m: MouseEntered => println( “I see it!” ) case m: MouseExited => println( “Lost it.” ) case m: MouseClicked => println( “Poked!” ) } // Java button.addMouseListener( new MouseAdapter() { public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseEntered(MouseEvent e) { System.out.println( “I see it!” ); } public void mouseExited(MouseEvent e) { System.out.println( “Lost it.” ); } public void mouseClicked(MouseEvent e) { System.out.println( “Poked!” ); } } // ...alternative - isinstanceof
  • 48.
    trait Treecase class Node(l: Tree, r: Tree) extends Tree case object Leaf extends Tree Pattern matching … is precise
  • 49.
    def b(t:Tree): Int = t match { case Node(Leaf, Node(_, _)) | Node(Node(_, _), Leaf) => -1 case Node(l, r) => val (ld, rd) = (b(l), b(r)) if (ld == rd) ld + 1 else -1 case Leaf => 0 case _ => error( “Unknown tree!” ) } Pattern matching … is precise
  • 50.
    sealed trait Tree ... def b(t: Tree): Int = t match { case Node(Leaf, Node(_, _)) | Node(Node(_, _), Leaf) => -1 case Node(l, r) => val (ld, rd) = (b(l), b(r)) if (ld == rd) ld + 1 else -1 case Leaf => 0 } Pattern matching … is exhaustive
  • 51.
    def matchingMeSoftly(a:Any): Any = a match { case 11 => “eleven” case s: String => “’%s’” .format(s) case <tag> {t} </tag> => t case Array(1, 2, 3) => “1, 2, 3” case head :: tail => tail case _ => null } Pattern matching … is extensible
  • 52.
  • 53.
    lazy valuesdon’t compute if there’s no demand class User(id: Int) { lazy val followernum = from(followers)(f => where(id === f.fid) compute(countDistinct(f.fid)) ) }
  • 54.
    Call by nameevaluate only when you have to def withErrorOut(body: => Unit) = { val old = Console.out Console.setOut(Console.err) try body finally Console.setOut(old) } ... withErrorOut { if (n < 0) println( “n too small” ) }
  • 55.
    Stream s lazylists e = ∑ 1/n! = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + …
  • 56.
    Stream s lazylists e = ∑ 1/n! = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + … 0! ?
  • 57.
    Stream s lazylists e = ∑ 1/n! = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + … 0! 1! 2! 3! ? 0! ?
  • 58.
    Stream s lazylists e = ∑ 1/n! = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + … 0! 1! 2! 3! ? 0! ? 0! 1/1! 1/2! 1/3! ?
  • 59.
    Stream s lazylists def fact(n: Int, p: Int): Stream[Int] = p #:: fact(n + 1, p * (n + 1)) val factorials = fact(0, 1) val e = factorials.map(1./_).take(10).sum
  • 60.
    Scala isexpressive.
  • 61.
    for comprehensionstraverse anything for (x <- List(1, 2, 3)) println(x) List(1, 2, 3).foreach(x => println(x)) for (x <- 0 until 10) println(x) (0 until 10).foreach(x => println(x)) Range(0, 10, 1).foreach(x => println(x))
  • 62.
    for comprehensionsmap anything for (x <- List(1, 2, 3)) yield x * 2 List(1, 2, 3).map(x => x * 2) for (x <- List(1, 2); y <- List(1, 2)) yield x * y List(1, 2).flatMap(x => List(1, 2).map(y => x * y) )  List(1, 2, 2, 4)
  • 63.
    for comprehensionslike SQL queries for { p <- people if p.age > 25 s <- schools if p.degree == s.degree } yield (p, s) // pairs of people older than 25 and // schools they possibly attended
  • 64.
    Collections easy tocreate val phonebook = Map( “ Jean” -> “123456” , “ Damien” -> “666666” ) val meetings = ArrayBuffer( “ Dante” , “Damien” , “Sophie” ) println(phonebook(meetings(1)))
  • 65.
    Collections high-level combinators// Java boolean isOk = true for ( int i = 0; i < name.length(); i++) { if (isLetterOrDigit(name.charAt(i)) { isOk = false ; break ; } }
  • 66.
    Collections high-level combinators// Scala name.forall(_.isLetterOrDigit)
  • 67.
    Collections high-level combinators// count the total number of different // surnames shared by at least 2 adults people
  • 68.
    Collections high-level combinators// count the total number of different // surnames shared by at least 2 adults people.filter(_.age >= 18)
  • 69.
    Collections high-level combinators// count the total number of different // surnames shared by at least 2 adults people.filter(_.age >= 18) .groupBy(_.surname) : Map[String, List[Person]]
  • 70.
    Collections high-level combinators// count the total number of different // surnames shared by at least 2 adults people.filter(_.age >= 18) .groupBy(_.surname) : Map[String, List[Person]] .count { case (s, l) => l.size >= 2 }
  • 71.
    List s animmutable sequence val countdown = List(3, 2, 1) 3 2 1 countdown
  • 72.
    List s animmutable sequence val countdown = List(3, 2, 1) val longer = 4 :: countdown 3 2 1 4 countdown longer
  • 73.
    List s animmutable sequence val countdown = List(3, 2, 1) val longer = 4 :: countdown val fast = 10 :: countdown 3 2 1 4 10 countdown longer fast
  • 74.
    List s animmutable sequence val countdown = List(3, 2, 1) val longer = 4 :: countdown val fast = 10 :: countdown val withzero = countdown ::: List(0) 3 2 1 4 10 3 2 1 0 countdown longer fast withzero
  • 75.
    Buffer s mutablesequences val b = ArrayBuffer(1, 2, 3) b += 4 b += 5 b += 6  ArrayBuffer(1, 2, 3, 4, 5, 6)
  • 76.
    Map s mutableor immutable, sorted or unsorted import collection._ val m = mutable.Map( “Heidfeld” -> 1, “ Schumacher” -> 2) m += “Hakkinen” -> 3 val im = immutable.Map( “Schumacher” -> 1)
  • 77.
    Hash tries persistencethrough efficient structural sharing val im0: Map[Int, Int] = ... im0
  • 78.
    Hash tries persistencethrough efficient structural sharing val im0: Map[Int, Int] = ... val im1 = im0 + (1 -> 1) im0 im1
  • 79.
    Hash tries persistencethrough efficient structural sharing val im0: Map[Int, Int] = ... val im1 = im0 + (1 -> 1) val im2 = im1 + (2 -> 2) im0 im1 im2
  • 80.
    Hash tries persistencethrough efficient structural sharing val im0: Map[Int, Int] = ... val im1 = im0 + (1 -> 1) val im2 = im1 + (2 -> 2) val im3 = im2 + (3 -> 6) im0 im1 im2 im3
  • 81.
    Hash tries persistencethrough efficient structural sharing im0 im1 im2 im3 2x-3x slower lookup 2x faster iteration
  • 82.
    Parallel collectionsparallelize bulk operations on collections def cntEqlen(m: Map[String, String]) = { m.par.count { case (n, s) => n.length == s.length } } // be careful with side-effects
  • 83.
    Scala isextensible.
  • 84.
    One ring torule them all.
  • 85.
    actor s roadto safer concurrency val a = actor { react { case i: Int => println(i) } } ... a ! 5
  • 86.
    Custom control flowit’s all about control def myWhile(c: => Boolean)(b: => Unit) { if (c) { b myWhile(c)(b) } }
  • 87.
    Custom control flowit’s all about control @tailrec def myWhile(c: => Boolean)(b: => Unit) { if (c) { b myWhile(c)(b) } }
  • 88.
    Custom control flowit’s all about control @tailrec def myWhile(c: => Boolean)(b: => Unit) { if (c) { b myWhile(c)(b) } } var i = 0 myWhile (i < 5) { i += 1 }
  • 89.
    ARM automatic resourcemanagement withFile ( “~/.bashrc” ) { f => for (l <- f.lines) { if ( “#” .r.findFirstIn(l) != None) println(l) } }
  • 90.
    ScalaTest behavioral testingframework “ A list” should { “ be a double reverse of itself” in { val ls = List(1, 2, 3, 4, 5, 6) ls.reverse.reverse should equal (ls) } }
  • 91.
    BaySick Basic DSLin Scala 10 PRINT “Baysick Lunar Lander v0.9” 20 LET ('dist := 100) 30 LET ('v := 1) 40 LET ('fuel := 1000) 50 LET ('mass := 1000) ...
  • 92.
    implicit conversionsaugmenting types with new operations ‘ a’ .toUpperCase
  • 93.
    implicit conversionsaugmenting types with new operations implicit def charOps(c: Char) = new { def toUpperCase = if (c >= ‘a’ && c <= ‘z’) (c – 32).toChar else c } ... ‘ a’ .toUpperCase
  • 94.
    Pimp mylibrary
  • 95.
    implicit conversionspimping your libraries since 2006 import scalaj.collection._ val list = new java.util.ArrayList[Int] list.add(1) list.add(2) list.add(3) ... for (x <- list) yield x * 2
  • 96.
    implicit conversionspimping your libraries since 2006 import scalaj.collection._ val list = new java.util.ArrayList[Int] list.add(1) list.add(2) list.add(3) ... for (x <- list) yield x * 2 // list.map(x => x * 2)
  • 97.
    implicit conversionspimping your libraries since 2006 import scalaj.collection._ val list = new java.util.ArrayList[Int] list.add(1) list.add(2) list.add(3) ... for (x <- list) yield x * 2 // jlist2slist(list).map(x => x * 2)
  • 98.
    implicit argumentsrestricting operations on types val is = SortedSet(1, 2, 3) case class Man(id: Int) ... implicit object MenOrd extends Ordering[Man] { def compare(x: Man, y: Man) = x.id – y.id } val ms = SortedSet(Person(1), Person(2))
  • 99.
    STM software transactionalmemory val account1 = cell[Int] val account2 = cell[Int] atomic { implicit txn => if (account2() >= 50) { account1 += 50 account2 -= 50 } }
  • 100.
    Scala hassupport.
  • 101.
  • 102.
    SBT simple buildtool > compile ... > ~compile ... > test ... > package
  • 103.
    SBT project definitionwritten in Scala val scalatest = “ org.scala-tools.testing” % “ scalatest” % “0.9.5” ... > reload [INFO] Building project ... [INFO] using sbt.Default ... > update
  • 104.
    Tools: IDEsEclipse Netbeans IntelliJ IDEA Emacs ENSIME JEdit
  • 105.
  • 106.
  • 107.