KEMBAR78
Stepping Up : A Brief Intro to Scala | PDF
Stepping Up: A Brief Intro to Scala

    Derek Chen-Becker, October 10th, 2009
A little background

    Scala began around 2003, 2.0 in 2006,
    currently at 2.7.5 (stable)

    Created by Martin Odersky (EPFL), of GJ,
    and later Javac v5 fame

    Compiles to 100% Java Bytecode
    
        Generally works flawlessly with Java
    
        Leverages JIT: performance ±5% of Java

    Excellent community (mailing lists, IRC)

    In use at Twitter, Seimens, Xerox, and others
Not quite déjà vu...
Scala combines features from many different
languages to form a unique hybrid:
  
      Scala is pure OO. Everything is an object, even
      primitives
  
      Scala has first-class function objects. Much of
      the library leverages function arguments
  
      Scala has a comprehensive type system and a
      flexible inheritance mechanism
  
      Method names have less restrictions. This allows
      for operator overloading and nice DSLs
  
      Immutability is strongly supported and
      encouraged. This is important for multi-core
Statics and Singletons


    Scala makes a distinction between
    instance and static methods and fields by
    using a separate “object” entity to
    represent the latter

    Objects are VM singletons

    Objects can be used to create custom
    factories and pattern matching extractors
    (more in a moment)
Scala is Succinct
public class Bike {
  private String brand;
  private int gear;

    public Bike(String brand,           class Bike (val brand : String,
                int gear) {                         var gear : Int) {
      this.brand = brand;                 override def toString =
      this.gear = gear;                     "This is a %s in gear %d"
    }                                         .format(brand, gear)
                                        }
    public int getGear() {
      return gear;
    }

    public void setGear(int gear) {
      this.gear = gear;
    }

    public String getBrand() {
      return brand;
    }
    public String toString() {
      return String.format("This is a %s in gear %d", brand, gear);
    }
}
Scala has Case Classes

    Case classes are defined basically like normal
    classes

    By default are immutable (good!)

    Constructor parameters are automatically vals

    Automatically get a companion object with
    apply/unapply, as well as overrides for equals,
    hashCode and toString on the class itself

case class Book(title : String, author : String)

val classic =
  Book("A Tale of Two Cities", "Dickens")

val Book(title,author) = classic
Scala has Case Classes, part 2

    Can inherit from other classes (although inheriting
    from other case classes is being deprecated)

    Can have their own methods just like normal
    classes

class Vehicle(val description : String,
              val topSpeed : Long)

case class Airplane(description : String,
                    topSpeed : Long,
                    var fuel : Double)
    extends Vehicle(description,speed) {
  def takeOff {...}
}
Scala is Functional
Functions in Scala are first-class objects, and
can be passed as arguments, assigned to
variables, etc.

val printLog =
{ msg : String => // or ⇒
    println(System.currentTimeMillis + ":" + msg)
}

List("one", "two", "three").foreach(printLog)
Scala is Functional, Part 2
Functions (and Scala's type system) allow you
to do things like define new control structures
in a type-safe way:
// Structural typing allows any type with a “close” method
def using[A <: { def close() : Unit }, B]
    (resource : A )
    (f : A => B) : B =
  try {
    f(resource)
  } finally {
    resource.close
  }

val firstLine =
  using(new BufferedReader(new FileReader("/etc/hosts"))) {
    reader => reader.readLine
  }
Scala has Closures
Closures capture variables in the scope of their
definition. These are ideal for callbacks, among
other things.

// Note that this example is not thread-safe
def logAndAdd(name : String) = {
  var counter = 0

    val logFunc = { msg : String =>
      println(name + "-" + counter + ":" + msg)
      counter += 1
    }

    logFunc
}
Scala is Higher Level
In particular, collections support complex
operations directly:
case class User(name : String, age : Int)
val people = List(User("Fred", 35), User("Barney", 32),...)

val sorted = people.sort(_.age < _.age).take(5)

// The same as :
val sorted =
  people.sort({(a,b) => a.age < b.age}).take(5)

val under30 = sorted.takeWhile(_.age < 30)

val youngest5 = sorted.take(5)

val oldest5 = sorted.takeRight(5).reverse
Scala has For-Comprehensions
For-comprehensions provide an elegant
construct for tying multiple sources and
criteria together to extract information:
val prefixes = List("/tmp", "/work",
                    System.getProperty("user.home"))

val suffixes = List("txt", "xml", "html")

def locateFiles(name : String) : List[String] =
  for (prefix <- prefixes;
       suffix <- suffixes;
       filename <-
         Some("%s/%s.%s".format(prefix, name, suffix))
           if (new File(filename)).exists)
    yield filename
Scala does Pattern Matching

    Like the “switch” statement on steroids

    Incredibly powerful for expressing
    conditional logic

    Cases are tested in order
def matchIt (in : Any) = in match {
  case 1 | 14 | "test" => {...}
  case x : Int => {...}
  case x : Double if x > 42.0 => {...}
  case Vehicle(description, _) => {...}
  case <head>{ stuff }</head> => {...}
  case _ => {...}
}
Scala does Custom Matching

    My favorite Scala example (more in the
    handout)
// Regexps in Scala define a custom unapply to match on groups
val colonSplit = """(w+):(w+)""".r

// It's easy to define your own as well
object IntVal {
  def unapply(in : String) =
    try { Some(in.toInt) } catch { case _ => None }
}

def parts (in : String) = in match {
// Matching allows nested use of extractors (here we want Ints)
  case colonSplit(IntVal(number), value) if number == 14 => {...}
  case colonSplit(IntVal(number), value) => {...}
  case colonSplit(key, value) => {...}
  case _ => {...}
}
Scala has Traits

    At their most basic, traits are 1-to-1 with Java
    interfaces

    Support concrete implementations of methods

    Support both concrete and abstract
    implementations of vals and vars

trait Named {
  val version = "1.0.0"

    val name : String

    def printName { println(name) }
}
Scala Enforces Trait Composition

    Traits can restrict which classes and traits
    they can be mixed into

    Traits can also define what “this” means
trait CreepyPerson extends Named {
  self : Person =>

    override def printName {
      println("Creepy! " + name +
              ", size = " + this._size)
    }
}

class A extends CreepyPerson {} // Error!
Scala Mixes In Traits

    Classes can have multiple traits mixed in,
    but can still only extend one superclass

    Disambiguation of method calls is done via
    a process called “Linearization”. Basically,
    right-to-left
trait Messageable { def msg (msg : String) }

trait Emailable extends Messageable {...}

trait SMSable extends Messageable {...}

class iPhone extends SMSable
  with Emailable {...}
Scala has Native XML
 
     XML literals are part of Scala's syntax
 
     Xpath-like expressions and pattern
     matching supported for extraction
val simpleFragment =
  <entries>
    <entry><name>Fred</name></entry>
    <entry><name>Barney</name></entry>
  </entries>

(simpleFragment  "name").toList.map(_.text)

simpleFragment.child.foreach({
   case <entry><name>{name}</name></entry> => println(name);
   case _ =>
})
Scala has Native XML, Part 2

    Values can be embedded in XML literals
    via braces.

    Interpretation of values is via toString,
    although scala.xml.{PCData,Unparsed} can
    do special handling
// <name>Fred&amp;Barney</name>
val embedFragment =
  <name>{ "Fred&Barney" }</name>

val noEscapes = // <name>Betty&Wilma</name>
  <name>{ Unparsed("Betty&Wilma") }</name>
Conclusion


    Scala lets you write less boilerplate and
    concentrate on the logic

    Interoperates very well with the existing
    Java ecosystem

    IDE support is still not where it needs to be,
    but it's functional

    Odersky, et. al, are committed to long-term
    growth and stability
Further Reading


    http://www.scala-lang.org/

    http://scala.sygneca.com/

    Books:
    
        Programming in Scala by Odersky, Venners &
        Spoon
    
        Beginning Scala by David Pollak
    
        Programming Scala by Wampler & Payne (online)
    
        Programming Scala by Venkat Subramaniam
    
        Steps in Scala by Loverdos & Syropolous
    
        The Definitive Guide to Lift (shameless plug)

Stepping Up : A Brief Intro to Scala

  • 1.
    Stepping Up: ABrief Intro to Scala Derek Chen-Becker, October 10th, 2009
  • 2.
    A little background  Scala began around 2003, 2.0 in 2006, currently at 2.7.5 (stable)  Created by Martin Odersky (EPFL), of GJ, and later Javac v5 fame  Compiles to 100% Java Bytecode  Generally works flawlessly with Java  Leverages JIT: performance ±5% of Java  Excellent community (mailing lists, IRC)  In use at Twitter, Seimens, Xerox, and others
  • 3.
    Not quite déjàvu... Scala combines features from many different languages to form a unique hybrid:  Scala is pure OO. Everything is an object, even primitives  Scala has first-class function objects. Much of the library leverages function arguments  Scala has a comprehensive type system and a flexible inheritance mechanism  Method names have less restrictions. This allows for operator overloading and nice DSLs  Immutability is strongly supported and encouraged. This is important for multi-core
  • 4.
    Statics and Singletons  Scala makes a distinction between instance and static methods and fields by using a separate “object” entity to represent the latter  Objects are VM singletons  Objects can be used to create custom factories and pattern matching extractors (more in a moment)
  • 5.
    Scala is Succinct publicclass Bike { private String brand; private int gear; public Bike(String brand, class Bike (val brand : String, int gear) { var gear : Int) { this.brand = brand; override def toString = this.gear = gear; "This is a %s in gear %d" } .format(brand, gear) } public int getGear() { return gear; } public void setGear(int gear) { this.gear = gear; } public String getBrand() { return brand; } public String toString() { return String.format("This is a %s in gear %d", brand, gear); } }
  • 6.
    Scala has CaseClasses  Case classes are defined basically like normal classes  By default are immutable (good!)  Constructor parameters are automatically vals  Automatically get a companion object with apply/unapply, as well as overrides for equals, hashCode and toString on the class itself case class Book(title : String, author : String) val classic = Book("A Tale of Two Cities", "Dickens") val Book(title,author) = classic
  • 7.
    Scala has CaseClasses, part 2  Can inherit from other classes (although inheriting from other case classes is being deprecated)  Can have their own methods just like normal classes class Vehicle(val description : String, val topSpeed : Long) case class Airplane(description : String, topSpeed : Long, var fuel : Double) extends Vehicle(description,speed) { def takeOff {...} }
  • 8.
    Scala is Functional Functionsin Scala are first-class objects, and can be passed as arguments, assigned to variables, etc. val printLog = { msg : String => // or ⇒ println(System.currentTimeMillis + ":" + msg) } List("one", "two", "three").foreach(printLog)
  • 9.
    Scala is Functional,Part 2 Functions (and Scala's type system) allow you to do things like define new control structures in a type-safe way: // Structural typing allows any type with a “close” method def using[A <: { def close() : Unit }, B] (resource : A ) (f : A => B) : B = try { f(resource) } finally { resource.close } val firstLine = using(new BufferedReader(new FileReader("/etc/hosts"))) { reader => reader.readLine }
  • 10.
    Scala has Closures Closurescapture variables in the scope of their definition. These are ideal for callbacks, among other things. // Note that this example is not thread-safe def logAndAdd(name : String) = { var counter = 0 val logFunc = { msg : String => println(name + "-" + counter + ":" + msg) counter += 1 } logFunc }
  • 11.
    Scala is HigherLevel In particular, collections support complex operations directly: case class User(name : String, age : Int) val people = List(User("Fred", 35), User("Barney", 32),...) val sorted = people.sort(_.age < _.age).take(5) // The same as : val sorted = people.sort({(a,b) => a.age < b.age}).take(5) val under30 = sorted.takeWhile(_.age < 30) val youngest5 = sorted.take(5) val oldest5 = sorted.takeRight(5).reverse
  • 12.
    Scala has For-Comprehensions For-comprehensionsprovide an elegant construct for tying multiple sources and criteria together to extract information: val prefixes = List("/tmp", "/work", System.getProperty("user.home")) val suffixes = List("txt", "xml", "html") def locateFiles(name : String) : List[String] = for (prefix <- prefixes; suffix <- suffixes; filename <- Some("%s/%s.%s".format(prefix, name, suffix)) if (new File(filename)).exists) yield filename
  • 13.
    Scala does PatternMatching  Like the “switch” statement on steroids  Incredibly powerful for expressing conditional logic  Cases are tested in order def matchIt (in : Any) = in match { case 1 | 14 | "test" => {...} case x : Int => {...} case x : Double if x > 42.0 => {...} case Vehicle(description, _) => {...} case <head>{ stuff }</head> => {...} case _ => {...} }
  • 14.
    Scala does CustomMatching  My favorite Scala example (more in the handout) // Regexps in Scala define a custom unapply to match on groups val colonSplit = """(w+):(w+)""".r // It's easy to define your own as well object IntVal { def unapply(in : String) = try { Some(in.toInt) } catch { case _ => None } } def parts (in : String) = in match { // Matching allows nested use of extractors (here we want Ints) case colonSplit(IntVal(number), value) if number == 14 => {...} case colonSplit(IntVal(number), value) => {...} case colonSplit(key, value) => {...} case _ => {...} }
  • 15.
    Scala has Traits  At their most basic, traits are 1-to-1 with Java interfaces  Support concrete implementations of methods  Support both concrete and abstract implementations of vals and vars trait Named { val version = "1.0.0" val name : String def printName { println(name) } }
  • 16.
    Scala Enforces TraitComposition  Traits can restrict which classes and traits they can be mixed into  Traits can also define what “this” means trait CreepyPerson extends Named { self : Person => override def printName { println("Creepy! " + name + ", size = " + this._size) } } class A extends CreepyPerson {} // Error!
  • 17.
    Scala Mixes InTraits  Classes can have multiple traits mixed in, but can still only extend one superclass  Disambiguation of method calls is done via a process called “Linearization”. Basically, right-to-left trait Messageable { def msg (msg : String) } trait Emailable extends Messageable {...} trait SMSable extends Messageable {...} class iPhone extends SMSable with Emailable {...}
  • 18.
    Scala has NativeXML  XML literals are part of Scala's syntax  Xpath-like expressions and pattern matching supported for extraction val simpleFragment = <entries> <entry><name>Fred</name></entry> <entry><name>Barney</name></entry> </entries> (simpleFragment "name").toList.map(_.text) simpleFragment.child.foreach({ case <entry><name>{name}</name></entry> => println(name); case _ => })
  • 19.
    Scala has NativeXML, Part 2  Values can be embedded in XML literals via braces.  Interpretation of values is via toString, although scala.xml.{PCData,Unparsed} can do special handling // <name>Fred&amp;Barney</name> val embedFragment = <name>{ "Fred&Barney" }</name> val noEscapes = // <name>Betty&Wilma</name> <name>{ Unparsed("Betty&Wilma") }</name>
  • 20.
    Conclusion  Scala lets you write less boilerplate and concentrate on the logic  Interoperates very well with the existing Java ecosystem  IDE support is still not where it needs to be, but it's functional  Odersky, et. al, are committed to long-term growth and stability
  • 21.
    Further Reading  http://www.scala-lang.org/  http://scala.sygneca.com/  Books:  Programming in Scala by Odersky, Venners & Spoon  Beginning Scala by David Pollak  Programming Scala by Wampler & Payne (online)  Programming Scala by Venkat Subramaniam  Steps in Scala by Loverdos & Syropolous  The Definitive Guide to Lift (shameless plug)