Starting with Scala
Frontier Developers' Meetup
December 9th, 2010
Boulder, CO


                              Derek Chen-Becker
                              Senior Network Engineer
                                      CPI Corporation
Scala's Pedigree

 Created by Martin
 Odersky (EPFL), of GJ,
 and later Javac v5
 fame
Scala's History
                                                              Scala History




                                                                                                                           2.8.1
                                                                                                                   2.8.0
                                                                                  2.7.0
                                                                         2.6.0
                                                                 2.5.0
                                                                                                   2.7.1 - 2.7.7



                                                                2.4.0
                                                      2.3.0
                                                     2.2.0
                                             2.1.0
                               1.4.0.0
                 1.3.0.2
       1.2.0.0
      1.1.1.0




 Jan 04               Jan 05             Jan 06       Jan 07                  Jan 08      Jan 09          Jan 10
More Info on Scala

 Home page: http://www.scala-lang.org/
 Excellent community
  scala-user@listes.epfl.ch
  irc://chat.freenode.net/scala
  http://scala.sygneca.com/ (Wiki)
Scala in Print
Scala in the Real World
Scala and the JVM

 Compiles to 100% Java Bytecode
  Generally works flawlessly with Java
  Leverages JIT: performance ±5% of
  Java
 Full access to existing Java ecosystem
 CLR (.Net) port in progress
About This Talk

 Scala 2.8.0+
  Significant changes to library
  I'm still coming up to speed on
  them
 This is not a lecture
Act I
No Time Like the Present
The Scala REPL

 Read, Evaluate, Print, Loop
 You need a JVM (1.6+ preferred) with
 “java” in your path or JAVA_HOME set
 Download the latest binaries from
 http://www.scala-lang.org/downloads
 Unpack wherever, go to bin subdirectory
 Type “scala<enter>”
Play Along at Home!

       http://www.simplyscala.com/
Act II
So, What is Scala?
Three Very Common Keywords

 val – defines an immutable
 value or reference
 var – defines a mutable value
 def – defines a
 function/method
Scala is Concerned with Mutability

 Immutable data structures reduce
 (but not eliminate) concurrency
 issues
 Combined with actors make a
 powerful approach to parallel tasks
 Strong library and language support
Scala is Strongly Typed...


   val foo : Int = 12

   var bar : String = "twelve"

   def baz (in : Int) : Double =
     in.toDouble
...But Can Usually Figure Types Out


  val foo            = 12

  var bar               = "twelve"

  def baz (in : Int)                  =
    in.toDouble
Scala is Generic


val primes : List[Int] =
  List(2,3,5,7,11)

scala> primes.grouped(2).toList
res16: List[List[Int]] =
List(List(2, 3), List(5, 7),
List(11))
Scala is Object­Oriented


      class Foo {
        def bar () = {
         "bat"
        }
      }

      val f = new Foo
I Mean Really Object­Oriented
                           st
 Primitives are treated as 1 class objects
         scala> (12.5).min(47)
         res17: Double = 12.5

         scala> 3825.toHexString
         res18: String = ef1

         scala> '5'.isWhitespace
         res19: Boolean = false
Scala is Functional

val greet =
 (name : String) =>
  "Hello, %s!".format(name)

greet(“Fred”)
res27: String = Hello, Fred!

val greet =
  "Hello, %s!".format(_ : String)
Scala is Functional Everywhere

def doubleMe (f : () => Any) {
  println(f()); println(f());
}

scala>
doubleMe(System.nanoTime)
1588504517303734
1588504517365296
Scala is Closurific


  def counter (name : String) = {
    var i = 0;
    { () =>
      i += 1
      name + ":" + i
    }
  }
Scala is Concise...
public class Person {
  private String name;
  private int age;

    public Person(String name, int age) {
     super();
     this.name = name;
     this.age = age;
     }

    public String getName() {
      return name;
    }                                            case class Person(name : String,
                                            VS                     var age : Int)
    public int getAge() {
      return age;
    }

    public void setAge(int age) {
      this.age = age;
    }

    public int hashCode() {...}
    public String toString() {...}
    public boolean equals() {...}
}
...But Maintains Uniform Access



 case class Person(val name : String,
              private var curAge : Int) {
   def age = curAge
   def age_= (a : Int) { curAge = a }
 }
Scala is DSL­Friendly (be reasonable)

class   Vector[T](data : Array[T]){
  def   + (that : Vector[T]) = {}
  def   - (that : Vector[T]) = {}
  ...
  def   ⊗ (that : Vector[T]) = {}
}

val product = A ⊗ B
val product = A.⊗(B)
Scala is Optional


val exists: Option[Int]= Some(42)
val notHere: Option[Int] = None

scala> exists.map(_ * 2).getOrElse(12)
res0: Int = 84

scala> notHere.map(_ * 2).getOrElse(12)
res1: Int = 12
Scala Likes Tuples (Heterogeneous)


scala> val state = (12, "Empty", RED)
state: (Int, java.lang.String, java.awt.Color)
= (12,Empty,java.awt.Color[r=255,g=0,b=0])

scala> val (count, description, color) = state
count: Int = 12
description: java.lang.String = Empty
color: java.awt.Color =
java.awt.Color[r=255,g=0,b=0]
Scala is XML­Friendly




 def personToXml(p : Person) =
   <person name={p.name}
     age={p.age.toString} />
Scala is High­Level...



val people = List(Person("Fred", 30),
                  Person("Ted", 25),
                  Person("Ed", 41))
people.foreach (println)
Letting You Get to the Real Work


// One line of magic...
implicit val orderPeople =
  Ordering.by((_:Person).age)

// ...allows powerful constructs
val (oldest,youngest) =
  (people.max,people.min)
Act III
Scala OO Fundamentals
Packages



       package net.foo {
         ...
       }

       package net.foo
Imports



import java.io.File
import java.net._
import java.awt.{Image,
  Color => JCol, Dialog => _}
Packages Nest...

           package net.foo
                  ==
           package net {
             package foo {
               ...
             }
           }
Sometimes in Unexpected Ways (< 2.8)




      package net.foo {
        import java.net.URL
      }
The Scala OO Quadfecta


                trait

     class               object
             case class/
               object
Traits Are Good

 Somewhat analogous to interfaces...

trait   Comparable[T] {
  def   < (that : T) : Boolean
  def   <= (that : T) : Boolean
  def   > (that : T) : Boolean
  def   >= (that : T) : Boolean
}
Traits are Really Awesome

 ...But they can carry implementation
trait Comparable[T <: Comparable[T]] {
    self : T =>
  def < (that : T) : Boolean
  def <= (that : T) = this < that ||
                      this == a
  def > (that : T) = that < this
  def >= (that : T) = that <= this
}
Traits can be Composed

trait A
trait B
trait C

class Base extends A with B
with C
Class Linearization : Base Trait




     trait Pet {
       def greeting : String
       def eat() : Unit
     }
Class Linearization : Extension Traits

trait Dog extends Pet {
  def greeting = "Woof"
  def eat() {...}
}

trait Mute extends Pet {
  override val greeting = ""
}
Class Linearization : Composition

     class Dingo extends Dog
       with Mute


  scala> (new Dingo).greeting
  res0: java.lang.String =
Scala Objects

 “An object definition defines a single
 object of a new class” (Scala Reference,
 §5.4

    object Friendly {
      var publicInt = 0
      def hi = println("Hi!")
    }
Objects hold Static Methods



 object MyApp {
   def main (args : Array[String]) {
         ...
     }
 }
Objects are Scoped VM Singletons



       class Outer {
         object Inner {
           var foo = "foo"
         }
       }
Objects as Factories

object Person {
  def apply(name : String,
            age : Int) : Person =
    new Person(name,age)
}

val fred = Person("Fred", 20)
Objects as Factories, Continued


object Person {
  ...
  def apply(name : String) : Person =
    new Person(name, 1)
}

val babyFred = Person("Fred")
Named and Default Arguments


object Person {
  def apply(name : String,
            age : Int = 1) : Person =
    new Person(name,age)
}

val fredBaby = Person(name = "Fred")
Case Classes (and Objects)


case class Car (name : String,
                gears : Int)

scala> val myCar = Car("Corolla", 4)
myCar: Car = Car(Corolla,4)

scala> myCar.name
res0: String = Corolla
Case Class Automation

 Factory method (apply)
 toString
 hashCode
 equals (and therefore ==)
 Constructor params become vals,
 can be turned into vars
Case Class Bonii : Copy


 scala> val myCar = Car("Corolla", 4)
 myCar: Car = Car(Corolla,4)

 scala> val myOtherCar =
   myCar.copy(name = "Forester")
 myOtherCar: Car = Car(Forester,4)
Case Class Bonii : Extraction



scala> val myCar = Car("Corolla", 4)
myCar: Car = Car(Corolla,4)

// “_” here means “don't bother”
scala> val Car(_,gears) = myCar
gears: Int = 4
Act IV
Functional is Your Friend
Start With Some Basic Functions

 foreach
 map
 flatMap
 filter
 exists
 takeWhile
 dropWhile
Composing Functions == Power




  people.flatMap(first =>
    people.filter(_ != first).
      map(List(first,_)))
For Comprehensions




   for (first <- people;
        second <- people
          if first != second)
     yield List(first,second)
Currying

 Provide N argument lists, but only use 1
 to N-1 of them to define a new function
 def scaler (factor : Int)
            (value : Int) =
   factor * value

 val times2 = scaler(2) _
 times2(12) // == 24
“By Name” Arguments


def myWhile (condition : => Boolean)
            (f : => Unit) {
  if (condition) {
    f; myWhile(condition)(f)
  }
}
“By Name” Use Case : Logging




 if (logger.isDebugEnabled) {
   logger.debug("Foo: " + foo)
 }
“By Name” Use Case : Logging




      THIS
 if (logger.isDebugEnabled) {
   logger.debug("Foo: " + foo)
 }
     SUCKS
“By Name” to the Rescue

 def debug (msg : => String) {
   if (this.debugEnabled) {
     println(msg)
   }
 }

  https://github.com/weiglewilczek/slf4s
Pattern Matching : Switch on Steroids

 “case _” here is the default case
   def literalMatch (in: Any) {
     in match {
       case 1 => doBar("One")
       case "test" => doBar("test")
       case 'x' => doBar("x")
       case 2.2f => doBar("float")
       case _ => doBar("lemon curry?")
     }
   }
Pattern Matching : Alternate Matches

 Using “|” allows multi-match cases

def literalMatch (in: Any) {
  in match {
    case 1 | 2 | 3 => doBar("One to three")
    case "this" | "that" => doBar("the other")
    case _ => doBar("lemon curry?")
  }
}
Pattern Matching : XML



def xmlMatch (in : Any) = in match {
  case <people>{bar @ _*}</people> =>
    bar.foreach(println)
  case _ => // NOOP
}
Pattern Matching : Case Classes



 def caseMatch (a : Any) = a match {
   case Person(name, age) =>
     println("%s is %d”.
       format(name,age))
 }
Pattern Matching : Type Matches



def typeMatch (in: Any) {
  in match {
    case i : Int => doBar("Int : " + i)
    case s : String => doBar(s)
    case _ => // NOOP
  }
}
Pattern Matching : Generics

  Erasure is not your friend

 def typeMatch   (in: Any) {
   in match {
     case ls :   List[String] => doBar("danger!")
     case li :   List[Int] => doBar("never happens")
     case _ =>   // NOOP
   }
 }
Pattern Matching : Guards

 def guardMatch (in: Any) {
   in match {
     case i : Int
        if i > 12 && i < 47 =>
         doBar("Int : " + i)
     case _ => // NOOP
   }
 }
Pattern Matching : Generics Workaround

 Like duck tape : ugly, but effective
def typeMatch (in: Any) {
  in match {
    case ls : List[_]
      if ls.forall(_.isInstanceOf[String]) =>
        doBar("Strings!")
    case li : List[_] => doBar("Some kind of List")
    case _ => // NOOP
  }
}
More More Info on Scala

 Home page: http://www.scala-lang.org/
 Excellent community
  scala-user@listes.epfl.ch
  irc://chat.freenode.net/scala
  http://scala.sygneca.com/ (Wiki)

Starting with Scala : Frontier Developer's Meetup December 2010