(How) Can we benefit
        from
      adopting
       Scala
          ?

          Tomasz Wróbel, 2011-01-24
in other words what Scala has to offer
Few quick facts
•   Strong typing
•   Static typing
•   Can be both interpreted and compiled into
    bytecode and run on top of a JVM (among
    others)
•   Interoperability with Java
•   No primitive types – everything is an object
Productivity gain
•   Concise, expressive → achieve more with less
•   Reduced boilerplate code – semicolons, dots,
    parentheses, return – these are often optional
    (depending on the context)
•   Extensive type inference
•   ½ LOC at least
•   Code is read more frequently than written
Support for both functional and
    object-oriented programming paradigms


•   Code blocks (anonymous functions)
•   Higher-order functions (ones that produce or
    consume functions)
•   Closures
•   Sophisticated collection library
REPL
Read-Evaluate-Print Loop

scala> val s = "Hello!"
s: java.lang.String = Hello!


scala> println(s)
Hello!
REPL
:help             print this help message
:load <arg>       load and interpret a Scala file
:sh <line>        fork a shell and run a command


scala> :sh ls
stdout: List[String] = List(Desktop, Documents,
  Downloads, Library, Movies, Music, Pictures, Public,
  Sites)
How difficult is it to switch?
                       Java → Scala
// class
public class A {}               class A {}


// variable
private int i = 0;              private var i: Int = 0;


// function
public String fun(String s) {   def fun(s: String): String = {
    return s;                       return s;
}                               }
Variables
•   everything is either val or var
•   val – immutable
•   var – mutable

val x: Int = 1; x = x + 1
var y = 1; y = y + 1


val set = new java.util.HashSet[String]
set.add("abc")
Type inference
val i: Int = 1
def upper(s: String): String = s.toUpperCase
val list: List[Int] = List[Int](1,2,3)


note: there are situations where type is required, e.g. recursive methods
operators = functions
•   1 + 2 is actually (1).+(2)
•   operators overloading
•   possibility to define new data types
Euro
case class Euro(euros: Int, cents: Int = 0) {
    def +(e: Euro) = Euro(
         euros + e.euros + ((cents + e.cents) / 100),
         (cents + e.cents) % 100
     )
}
case class Cent(cents: Int)


assertThat(Euro(5) + Euro(5), is(Euro(10)))
assertThat(Euro(4) + Cent(99), is(Euro(4, 99)))
Ranges
val oneToTen = 1 to 10
assertThat(oneToTen.size, is(10))


val evenNumbers = 2 to 10 by 2
assertThat(evenNumbers.size, is(5))


val alphabet = 'a' to 'z'
assertThat(alphabet.size, is(26))
Tuples
are typed
scala> val tuple = ("CODE", 31)
tuple: (java.lang.String, Int) = (CODE,31)
Tuples
are convenient way to return multiple values from
  a function
def analyzeString(s: String): (String, Int) = {
    (s.toUpperCase, s.length)
}


scala> val result = analyzeString("abc")
result: (String, Int) = (ABC,3)
Controlling executions
for (i <- 0 to 9) {
    print(i)
}


for (i <- 0 to 9) {
    if (i % 2 == 0) println("even: " + i) else
    println("odd: " + i)
}
Controlling executions
var i = 0
while (i < 10) {
    print(i)
    i += 1
}
Raw strings
// given
val s = """|first line
           |second "B" line
           |third line""".stripMargin


// then
assertThat(s, is("first linensecond "B" linenthird
  line"))
Raw strings
assertThat("1234".matches("""d*"""), is(true))
assertThat("12ab".matches("""d*"""), is(false))




new File("""c:somepathtofile.txt""").exists
Making assertions
@Test(expected = classOf[IllegalArgumentException])
def convenientAssertions {
    val i = -1


    require(i > 0)
}
Objects equality
•   == is Java's equals()
•   eq()is Java's ==
Imports
import java.util.Date
import java.text.{DateFormat, SimpleDateFormat}
import java.math._


// static imports
import java.util.Arrays.asList
import java.util.Collections._


// aliasing
import java.sql.{Date => SqlDate}
Tail recursion
compiler optimizes tail-recursive functions to
  loops → preventing stack overflow errors

@tailrec
final def fact(n: Int, acc: Long = 1): Long = {
    if (n < 1) acc else fact(n - 1, n * acc)
}


@tailrec – optional, compiler hints you if on not tail-recursive function
There is always an Option
                                 i.e. null alternative

scala> def map = Map("PL" -> "Poland")

scala> val country: Option[String] = map.get("PL")

country: Option[String] = Some(Poland)



scala> val res = country.get

res: String = Poland

scala> val res = country.getOrElse("default")

res: String = Poland

scala> val country: Option[String] = map.get("UK")

country: Option[String] = None

scala> val res = country.getOrElse("default")

res: String = default

scala> val res = country.get

java.util.NoSuchElementException: None.get
Implicits
Allow to add functionality to existing classes
val past = 2 days ago // 2.days(ago)
val future = 5 days later // 5.days(later)


println(new java.util.Date)
println(past)
println(future)


Sun Jan 23 22:18:51 GMT 2011
Fri Jan 21 22:18:51 GMT 2011
Fri Jan 28 22:18:51 GMT 2011
class, object, trait
•   class – holds instance methods and fields
•   object – companion object – singleton
    object, holds class (static) methods
•   trait – partial class implementation or
    interface with implementation, it is possible to
    mixin multiple traits
class and object
class Article private(title: String)
object Article {
    def newInstance(title: String) = new Article(title)
}


object App {
    def main(args: Array[String]) {
        val article = Article.newInstance("a Title")
    }
}
Traits
trait SingleJournalRelease extends PressRelease {

    override def validate = println("articles form the same journal")

}

trait IssueRelease extends PressRelease {

    override def header = print("Issue Press Release containing ")

}

trait AopRelease extends PressRelease {

    override def header = print("AOP Press Release containing ")

}

class AcademicJournalAopPressRelease extends AopRelease with
   SingleJournalRelease

class ResearchJournalIssuePressRelease extends IssueRelease with
   SingleJournalRelease
Anonymous functions
val list = List(1, 2, 3)
val odds = list.filter((each: Int) => each % 2 != 0)
assertThat(odds, is(List(1, 3)))
Functions
Functions can be assigned to variables and be
 passed as parameters

val complicatedProcessing = (s: String) =>
  s.toUpperCase
assertThat(complicatedProcessing("abc"), is("ABC"))


val list = List("a", "b", "c")
val result = list.map(complicatedProcessing)
assertThat(result, is(List("A", "B", "C")))
Local functions
Functions can be nested

def outer {
    def inner(s: String) = println("inner " + s)


    inner("outer")
}
Passing parameters to functions
scala> def fun(s: String) = println(s)
fun: (s: String)Unit


scala> fun("abc")
abc


scala> fun{"abc"}
abc
Curried functions
Currying = turning a function that takes two arguments
 into a chain of functions that take one argument
def sum(x: Int, y: Int) = x + y
def multiple(x: Int)(y: Int) = x * y


scala> val result = sum(1, 2)
result: Int = 3


scala> val result = multiple(1)(2)
result: Int = 2
Adding new control structures
writeToFile("output.txt") {
    writer => writer.println("abc")
}


def writeToFile(fileName: String)(block : PrintWriter
  => Unit) = {
    val writer = new PrintWriter(new File(fileName))
    try { block(writer) } finally writer.close()
}
Implementing unless
scala> def unless(cond: => Boolean)(body: => Unit): Unit =
     |     if (!cond) {
     |         body
     |     }
unless: (cond: => Boolean)(body: => Unit)Unit


scala> unless(1 > 2) {
     |     print("1 is not greater than 2")
     | }
1 is not greater than 2
Closures
// given
val base = 100


def closeAroundBase(i: Int) = {
    i + base
}


// then
assertThat(closeAroundBase(10), is(110))
Why is closure useful?
val patternProvidedByUser = "L.*"
val data = List("London", "Oxford", "Leeds")
val result =
  data.filter(_.matches(patternProvidedByUser))


result: List[java.lang.String] = List(London, Leeds)
Case classes
case class Article(var doi: String, var title: String)


// Provide convenient factory method
val article = Article("10.1038/nature01234", "a Title")


// and implementations for
assertThat("toString", article.toString,
  is("Article(10.1038/nature01234,a Title)"))
assertThat("hashCode", article.hashCode,
  equalTo( equalArticle.hashCode ))
assertTrue("equals", article == equalArticle)
Pattern matching
•   match as switch on steroids
•   always results in a value
•   no “fall through”
•   MatchError thrown if no match
•   _ is default
Matching by constant
def fun(o: Any): Int = o match {
    case "abc" => 1
    case 1 => 2
    case Nil => 0
}
Matching by type
                   (no more instanceof and casting)

def size(o: Any): Int = o match {
    case s: String => s.length
    case l: List[_] => l.size
    case _ => -1
}


assertThat(size("abc"), is(3))
assertThat(size(List(1, 2)), is(2))
Matching by tuple
def fun(o: Any): Any = o match {
    case (a: Int, b: Int) => a + b
}
Matching by constructor
case class Rectangle(a: Int, b: Int)


def identify(r: Rectangle): String = r match {
    case Rectangle(2, 4) => "2x4"
    case Rectangle(a, b) if a == b => "Square" // pattern guard
    case Rectangle(a, b) => "Rectangle " + a + "x" + b
}


assertThat(identify(Rectangle(2, 4)), is("2x4"))
assertThat(identify(Rectangle(1, 1)), is("Square"))
assertThat(identify(Rectangle(1, 2)), is("Rectangle 1x2"))
(optional) Exception handling
try {
    val f = new FileInputStream("file.txt")
} catch {
    case e: IOException => // handle the exception
}


but can be also just:
val f = new FileInputStream("file.txt")
Named and default parameters
case class Article(id: Int, doi: String, title:
  String)


def make(id: Int = 1, doi: String = "a Doi", title:
  String = "a Title") = {
    Article(id, doi, title)
}
Named and default parameters
               Defaulting omitted parameter(s)

val article = make(99, "10.1038/nature01234")


assertThat(article.id, is(99))
assertThat(article.doi, is("10.1038/nature01234"))
assertThat(article.title, is("a Title"))
Named and default parameters
                 Setting parameter by name

val article = make(doi = "10.1038/nature01234")


assertThat(article.id, is(1)) // default
assertThat(article.doi, is("10.1038/nature01234"))
assertThat(article.title, is("a Title")) // default
Collections
                               Easy construction

val aList = List(1, 2, 3)

val aMap = Map("A" -> 1, "B" -> 2, "C" -> 3)

val aSet = Set("a", "b", "c", "b", "a")



scala> val list = List(1) ::: List(2) // concatenate

list: List[Int] = List(1, 2)



scala> val list = List(1) ++ List(2) // concatenate

list: List[Int] = List(1, 2)



scala> val list = 1 :: List(2) // add element (as a first one)

list: List[Int] = List(1, 2)
Collections
 Iterable - a base trait for iterable collections with ~100 functions

scala> val numbers = List(1, 2, 3, 4, 5)


scala> val negatives = numbers.map(e => -e)
negatives: List[Int] = List(-1, -2, -3, -4, -5)


scala> val even = numbers.filter(n => n % 2 == 0)
even: List[Int] = List(2, 4)


scala> val (even, odd) = numbers.partition(_ % 2 == 0)
even: List[Int] = List(2, 4)
odd: List[Int] = List(1, 3, 5)
Collections
scala>   val result = numbers.mkString(", ")
result: String = 1, 2, 3, 4, 5


scala> val result = numbers.count(_ > 2)
result: Int = 3


scala> numbers.foreach(print _)
12345
Collections
                           Example for groupBy

scala> case class Article(journal: String, doi: String)

scala> val articles = List(
   Article("NATURE", "nature09733"), Article("NMAT", "nmat2937"),
   Article("NMAT", "nmat1807"), Article("NPHYS", "nphys1906"))

scala> val result = articles.groupBy(e => e.journal)



scala> val nmat = result("NMAT")

nmat: List[Article] = List(Article(NMAT,nmat2937), Article(NMAT,nmat1807))



scala> val nature = result("NATURE")

nature: List[Article] = List(Article(NATURE,nature09733))



scala> val nphys = result("NPHYS")

nphys: List[Article] = List(Article(NPHYS,nphys1906))
XML literals and XPath-like processing

// given
val xml = <article id="1">
  <doi>10.1038/nature01234</doi>
  <title>A Title</title>
</article>


// then
assertThat(xml  "@id" text, is("1"))
assertThat(xml "doi" text, is("10.1038/nature01234"))
Evaluating Scala code in XML literal
// given
val tstamp = System.currentTimeMillis
val xml = <timestamp>{tstamp}</timestamp>


// then
xml = <timestamp>1295726256063</timestamp>
Loading XML
// given
val xml = XML.loadString("<code>ABC</code>")


// then
assertThat(xml, is(<code>ABC</code>))
Pattern matching on XML
val xml = <info>
    <message>a message</message>
</info>


val result = xml match {
    case <info>{_*}</info> => logInfo(xml)
    case <error>{_*}</error> => logError(xml)
}
Concurrency – Actor model
•   Asynchronous message passing between
    actors
•   Messages are immutable
•   Synchronized mailbox
•   Mailbox is read with pattern matching
•   No shared state + No locks = Safe concurrency
•   Actors are lightweight → millions of them on
    regular box
Type parameterization
class A
class B extends A
class C extends B


def upperBound[T <: B](o: T) {}


upperBound(new A)
upperBound(new B)
upperBound(new C)
Type parameterization
def getSize[T <: { def size: Int }](o: T): Int = {
    o.size
}


getSize(List(1, 2, 3))
getSize(new StringBuilder("abc"))
getSize("abc") // String has length() not size()
Automatic Resource Management
                        use of type parameterization and closure

def using[T <: {def close()}](resource: T)(block: T => Unit) = {

    try {

        block(resource)

    } finally {

        if (resource != null) {

            try resource.close

            catch {

                case e: Exception =>

            }

        }

    }

}
Automatic Resource Management
using(stream) { // where stream is InputStream
    res => { val data = res.read }
}


using(resultSet) { // where resultSet is ResultSet
    res => {
        val data = if (res.next) res.getString("column")
                   else ""
    }
}
ScalaTest BDD testing DSL
class StackSpec extends Spec with ShouldMatchers {

    describe("A Stack") {

        describe("(when empty)") {

            val stack = new Stack[Int]


            it("should be empty") {

                stack should be ('empty)

            }


            it("should complain when popped") {

                evaluating { stack.pop() } should produce [NoSuchElementException]

            }

        }

    }

}
Tooling
•   Plugins for Eclipse, NetBeans and IDEA
•   Support for (some) refactorings, debugging,
    code completion, hints, syntax highlighting,
    navigation


•   maven support (also mix Java/Scala projects)
•   sbt – simple build tool
Benefits
•   Productivity
•   Functional aspects
•   XML
•   DSL
•   Concurrency
Quirks (functions)
Way functions are declared determines how they can be used


def foo = 1
def bar() = 2


foo
foo()
bar
bar()
Warning!




  There is a danger that once you start
programming in Scala you may not want to
        program in Java anymore!
Resources
Scala - http://www.scala-lang.org/
A Tour of Scala - http://www.scala-lang.org/node/104
Scala API - http://www.scala-lang.org/api/current/index.html
New features of Scala 2.8 - http://escalatesoft.com/screencasts
Scala for Java Refugees
  http://www.codecommit.com/blog/scala/roundup-scala-for-java-refugees
AlBlue’s Blog - http://alblue.bandlem.com/search/label/scala
Scala Style Guide (good to learn about some Scala quirks) -
  http://davetron5000.github.com/scala-style/
Scaling Web Apps with Akka -
  http://maciejmatyjas.com/2010/07/scaling-web-apps-with-akka/
Resources
Programming in Scala - http://www.artima.com/shop/programming_in_scala
Programming Scala - http://programming-scala.labs.oreilly.com/
Seven Languages in Seven Weeks (chapter, comparison with Java and Ruby)
  http://pragprog.com/titles/btlang/seven-languages-in-seven-weeks
Programming Scala - http://pragprog.com/titles/vsscala/programming-scala
Scala in London
London Scala User Group
  http://www.meetup.com/london-scala/
regular meetups – recorded and available at
  http://skillsmatter.com/go/scala
LSUG Scala Dojo
Thanks!

http://tomaszwrobel.com
        @twr_wrtp

(How) can we benefit from adopting scala?

  • 1.
    (How) Can webenefit from adopting Scala ? Tomasz Wróbel, 2011-01-24
  • 2.
    in other wordswhat Scala has to offer
  • 3.
    Few quick facts • Strong typing • Static typing • Can be both interpreted and compiled into bytecode and run on top of a JVM (among others) • Interoperability with Java • No primitive types – everything is an object
  • 4.
    Productivity gain • Concise, expressive → achieve more with less • Reduced boilerplate code – semicolons, dots, parentheses, return – these are often optional (depending on the context) • Extensive type inference • ½ LOC at least • Code is read more frequently than written
  • 5.
    Support for bothfunctional and object-oriented programming paradigms • Code blocks (anonymous functions) • Higher-order functions (ones that produce or consume functions) • Closures • Sophisticated collection library
  • 6.
    REPL Read-Evaluate-Print Loop scala> vals = "Hello!" s: java.lang.String = Hello! scala> println(s) Hello!
  • 7.
    REPL :help print this help message :load <arg> load and interpret a Scala file :sh <line> fork a shell and run a command scala> :sh ls stdout: List[String] = List(Desktop, Documents, Downloads, Library, Movies, Music, Pictures, Public, Sites)
  • 8.
    How difficult isit to switch? Java → Scala // class public class A {} class A {} // variable private int i = 0; private var i: Int = 0; // function public String fun(String s) { def fun(s: String): String = { return s; return s; } }
  • 9.
    Variables • everything is either val or var • val – immutable • var – mutable val x: Int = 1; x = x + 1 var y = 1; y = y + 1 val set = new java.util.HashSet[String] set.add("abc")
  • 10.
    Type inference val i:Int = 1 def upper(s: String): String = s.toUpperCase val list: List[Int] = List[Int](1,2,3) note: there are situations where type is required, e.g. recursive methods
  • 11.
    operators = functions • 1 + 2 is actually (1).+(2) • operators overloading • possibility to define new data types
  • 12.
    Euro case class Euro(euros:Int, cents: Int = 0) { def +(e: Euro) = Euro( euros + e.euros + ((cents + e.cents) / 100), (cents + e.cents) % 100 ) } case class Cent(cents: Int) assertThat(Euro(5) + Euro(5), is(Euro(10))) assertThat(Euro(4) + Cent(99), is(Euro(4, 99)))
  • 13.
    Ranges val oneToTen =1 to 10 assertThat(oneToTen.size, is(10)) val evenNumbers = 2 to 10 by 2 assertThat(evenNumbers.size, is(5)) val alphabet = 'a' to 'z' assertThat(alphabet.size, is(26))
  • 14.
    Tuples are typed scala> valtuple = ("CODE", 31) tuple: (java.lang.String, Int) = (CODE,31)
  • 15.
    Tuples are convenient wayto return multiple values from a function def analyzeString(s: String): (String, Int) = { (s.toUpperCase, s.length) } scala> val result = analyzeString("abc") result: (String, Int) = (ABC,3)
  • 16.
    Controlling executions for (i<- 0 to 9) { print(i) } for (i <- 0 to 9) { if (i % 2 == 0) println("even: " + i) else println("odd: " + i) }
  • 17.
    Controlling executions var i= 0 while (i < 10) { print(i) i += 1 }
  • 18.
    Raw strings // given vals = """|first line |second "B" line |third line""".stripMargin // then assertThat(s, is("first linensecond "B" linenthird line"))
  • 19.
  • 20.
    Making assertions @Test(expected =classOf[IllegalArgumentException]) def convenientAssertions { val i = -1 require(i > 0) }
  • 21.
    Objects equality • == is Java's equals() • eq()is Java's ==
  • 22.
    Imports import java.util.Date import java.text.{DateFormat,SimpleDateFormat} import java.math._ // static imports import java.util.Arrays.asList import java.util.Collections._ // aliasing import java.sql.{Date => SqlDate}
  • 23.
    Tail recursion compiler optimizestail-recursive functions to loops → preventing stack overflow errors @tailrec final def fact(n: Int, acc: Long = 1): Long = { if (n < 1) acc else fact(n - 1, n * acc) } @tailrec – optional, compiler hints you if on not tail-recursive function
  • 24.
    There is alwaysan Option i.e. null alternative scala> def map = Map("PL" -> "Poland") scala> val country: Option[String] = map.get("PL") country: Option[String] = Some(Poland) scala> val res = country.get res: String = Poland scala> val res = country.getOrElse("default") res: String = Poland scala> val country: Option[String] = map.get("UK") country: Option[String] = None scala> val res = country.getOrElse("default") res: String = default scala> val res = country.get java.util.NoSuchElementException: None.get
  • 25.
    Implicits Allow to addfunctionality to existing classes val past = 2 days ago // 2.days(ago) val future = 5 days later // 5.days(later) println(new java.util.Date) println(past) println(future) Sun Jan 23 22:18:51 GMT 2011 Fri Jan 21 22:18:51 GMT 2011 Fri Jan 28 22:18:51 GMT 2011
  • 26.
    class, object, trait • class – holds instance methods and fields • object – companion object – singleton object, holds class (static) methods • trait – partial class implementation or interface with implementation, it is possible to mixin multiple traits
  • 27.
    class and object classArticle private(title: String) object Article { def newInstance(title: String) = new Article(title) } object App { def main(args: Array[String]) { val article = Article.newInstance("a Title") } }
  • 28.
    Traits trait SingleJournalRelease extendsPressRelease { override def validate = println("articles form the same journal") } trait IssueRelease extends PressRelease { override def header = print("Issue Press Release containing ") } trait AopRelease extends PressRelease { override def header = print("AOP Press Release containing ") } class AcademicJournalAopPressRelease extends AopRelease with SingleJournalRelease class ResearchJournalIssuePressRelease extends IssueRelease with SingleJournalRelease
  • 29.
    Anonymous functions val list= List(1, 2, 3) val odds = list.filter((each: Int) => each % 2 != 0) assertThat(odds, is(List(1, 3)))
  • 30.
    Functions Functions can beassigned to variables and be passed as parameters val complicatedProcessing = (s: String) => s.toUpperCase assertThat(complicatedProcessing("abc"), is("ABC")) val list = List("a", "b", "c") val result = list.map(complicatedProcessing) assertThat(result, is(List("A", "B", "C")))
  • 31.
    Local functions Functions canbe nested def outer { def inner(s: String) = println("inner " + s) inner("outer") }
  • 32.
    Passing parameters tofunctions scala> def fun(s: String) = println(s) fun: (s: String)Unit scala> fun("abc") abc scala> fun{"abc"} abc
  • 33.
    Curried functions Currying =turning a function that takes two arguments into a chain of functions that take one argument def sum(x: Int, y: Int) = x + y def multiple(x: Int)(y: Int) = x * y scala> val result = sum(1, 2) result: Int = 3 scala> val result = multiple(1)(2) result: Int = 2
  • 34.
    Adding new controlstructures writeToFile("output.txt") { writer => writer.println("abc") } def writeToFile(fileName: String)(block : PrintWriter => Unit) = { val writer = new PrintWriter(new File(fileName)) try { block(writer) } finally writer.close() }
  • 35.
    Implementing unless scala> defunless(cond: => Boolean)(body: => Unit): Unit = | if (!cond) { | body | } unless: (cond: => Boolean)(body: => Unit)Unit scala> unless(1 > 2) { | print("1 is not greater than 2") | } 1 is not greater than 2
  • 36.
    Closures // given val base= 100 def closeAroundBase(i: Int) = { i + base } // then assertThat(closeAroundBase(10), is(110))
  • 37.
    Why is closureuseful? val patternProvidedByUser = "L.*" val data = List("London", "Oxford", "Leeds") val result = data.filter(_.matches(patternProvidedByUser)) result: List[java.lang.String] = List(London, Leeds)
  • 38.
    Case classes case classArticle(var doi: String, var title: String) // Provide convenient factory method val article = Article("10.1038/nature01234", "a Title") // and implementations for assertThat("toString", article.toString, is("Article(10.1038/nature01234,a Title)")) assertThat("hashCode", article.hashCode, equalTo( equalArticle.hashCode )) assertTrue("equals", article == equalArticle)
  • 39.
    Pattern matching • match as switch on steroids • always results in a value • no “fall through” • MatchError thrown if no match • _ is default
  • 40.
    Matching by constant deffun(o: Any): Int = o match { case "abc" => 1 case 1 => 2 case Nil => 0 }
  • 41.
    Matching by type (no more instanceof and casting) def size(o: Any): Int = o match { case s: String => s.length case l: List[_] => l.size case _ => -1 } assertThat(size("abc"), is(3)) assertThat(size(List(1, 2)), is(2))
  • 42.
    Matching by tuple deffun(o: Any): Any = o match { case (a: Int, b: Int) => a + b }
  • 43.
    Matching by constructor caseclass Rectangle(a: Int, b: Int) def identify(r: Rectangle): String = r match { case Rectangle(2, 4) => "2x4" case Rectangle(a, b) if a == b => "Square" // pattern guard case Rectangle(a, b) => "Rectangle " + a + "x" + b } assertThat(identify(Rectangle(2, 4)), is("2x4")) assertThat(identify(Rectangle(1, 1)), is("Square")) assertThat(identify(Rectangle(1, 2)), is("Rectangle 1x2"))
  • 44.
    (optional) Exception handling try{ val f = new FileInputStream("file.txt") } catch { case e: IOException => // handle the exception } but can be also just: val f = new FileInputStream("file.txt")
  • 45.
    Named and defaultparameters case class Article(id: Int, doi: String, title: String) def make(id: Int = 1, doi: String = "a Doi", title: String = "a Title") = { Article(id, doi, title) }
  • 46.
    Named and defaultparameters Defaulting omitted parameter(s) val article = make(99, "10.1038/nature01234") assertThat(article.id, is(99)) assertThat(article.doi, is("10.1038/nature01234")) assertThat(article.title, is("a Title"))
  • 47.
    Named and defaultparameters Setting parameter by name val article = make(doi = "10.1038/nature01234") assertThat(article.id, is(1)) // default assertThat(article.doi, is("10.1038/nature01234")) assertThat(article.title, is("a Title")) // default
  • 48.
    Collections Easy construction val aList = List(1, 2, 3) val aMap = Map("A" -> 1, "B" -> 2, "C" -> 3) val aSet = Set("a", "b", "c", "b", "a") scala> val list = List(1) ::: List(2) // concatenate list: List[Int] = List(1, 2) scala> val list = List(1) ++ List(2) // concatenate list: List[Int] = List(1, 2) scala> val list = 1 :: List(2) // add element (as a first one) list: List[Int] = List(1, 2)
  • 49.
    Collections Iterable -a base trait for iterable collections with ~100 functions scala> val numbers = List(1, 2, 3, 4, 5) scala> val negatives = numbers.map(e => -e) negatives: List[Int] = List(-1, -2, -3, -4, -5) scala> val even = numbers.filter(n => n % 2 == 0) even: List[Int] = List(2, 4) scala> val (even, odd) = numbers.partition(_ % 2 == 0) even: List[Int] = List(2, 4) odd: List[Int] = List(1, 3, 5)
  • 50.
    Collections scala> val result = numbers.mkString(", ") result: String = 1, 2, 3, 4, 5 scala> val result = numbers.count(_ > 2) result: Int = 3 scala> numbers.foreach(print _) 12345
  • 51.
    Collections Example for groupBy scala> case class Article(journal: String, doi: String) scala> val articles = List( Article("NATURE", "nature09733"), Article("NMAT", "nmat2937"), Article("NMAT", "nmat1807"), Article("NPHYS", "nphys1906")) scala> val result = articles.groupBy(e => e.journal) scala> val nmat = result("NMAT") nmat: List[Article] = List(Article(NMAT,nmat2937), Article(NMAT,nmat1807)) scala> val nature = result("NATURE") nature: List[Article] = List(Article(NATURE,nature09733)) scala> val nphys = result("NPHYS") nphys: List[Article] = List(Article(NPHYS,nphys1906))
  • 52.
    XML literals andXPath-like processing // given val xml = <article id="1"> <doi>10.1038/nature01234</doi> <title>A Title</title> </article> // then assertThat(xml "@id" text, is("1")) assertThat(xml "doi" text, is("10.1038/nature01234"))
  • 53.
    Evaluating Scala codein XML literal // given val tstamp = System.currentTimeMillis val xml = <timestamp>{tstamp}</timestamp> // then xml = <timestamp>1295726256063</timestamp>
  • 54.
    Loading XML // given valxml = XML.loadString("<code>ABC</code>") // then assertThat(xml, is(<code>ABC</code>))
  • 55.
    Pattern matching onXML val xml = <info> <message>a message</message> </info> val result = xml match { case <info>{_*}</info> => logInfo(xml) case <error>{_*}</error> => logError(xml) }
  • 56.
    Concurrency – Actormodel • Asynchronous message passing between actors • Messages are immutable • Synchronized mailbox • Mailbox is read with pattern matching • No shared state + No locks = Safe concurrency • Actors are lightweight → millions of them on regular box
  • 57.
    Type parameterization class A classB extends A class C extends B def upperBound[T <: B](o: T) {} upperBound(new A) upperBound(new B) upperBound(new C)
  • 58.
    Type parameterization def getSize[T<: { def size: Int }](o: T): Int = { o.size } getSize(List(1, 2, 3)) getSize(new StringBuilder("abc")) getSize("abc") // String has length() not size()
  • 59.
    Automatic Resource Management use of type parameterization and closure def using[T <: {def close()}](resource: T)(block: T => Unit) = { try { block(resource) } finally { if (resource != null) { try resource.close catch { case e: Exception => } } } }
  • 60.
    Automatic Resource Management using(stream){ // where stream is InputStream res => { val data = res.read } } using(resultSet) { // where resultSet is ResultSet res => { val data = if (res.next) res.getString("column") else "" } }
  • 61.
    ScalaTest BDD testingDSL class StackSpec extends Spec with ShouldMatchers { describe("A Stack") { describe("(when empty)") { val stack = new Stack[Int] it("should be empty") { stack should be ('empty) } it("should complain when popped") { evaluating { stack.pop() } should produce [NoSuchElementException] } } } }
  • 62.
    Tooling • Plugins for Eclipse, NetBeans and IDEA • Support for (some) refactorings, debugging, code completion, hints, syntax highlighting, navigation • maven support (also mix Java/Scala projects) • sbt – simple build tool
  • 63.
    Benefits • Productivity • Functional aspects • XML • DSL • Concurrency
  • 64.
    Quirks (functions) Way functionsare declared determines how they can be used def foo = 1 def bar() = 2 foo foo() bar bar()
  • 65.
    Warning! Thereis a danger that once you start programming in Scala you may not want to program in Java anymore!
  • 66.
    Resources Scala - http://www.scala-lang.org/ ATour of Scala - http://www.scala-lang.org/node/104 Scala API - http://www.scala-lang.org/api/current/index.html New features of Scala 2.8 - http://escalatesoft.com/screencasts Scala for Java Refugees http://www.codecommit.com/blog/scala/roundup-scala-for-java-refugees AlBlue’s Blog - http://alblue.bandlem.com/search/label/scala Scala Style Guide (good to learn about some Scala quirks) - http://davetron5000.github.com/scala-style/ Scaling Web Apps with Akka - http://maciejmatyjas.com/2010/07/scaling-web-apps-with-akka/
  • 67.
    Resources Programming in Scala- http://www.artima.com/shop/programming_in_scala Programming Scala - http://programming-scala.labs.oreilly.com/ Seven Languages in Seven Weeks (chapter, comparison with Java and Ruby) http://pragprog.com/titles/btlang/seven-languages-in-seven-weeks Programming Scala - http://pragprog.com/titles/vsscala/programming-scala
  • 68.
    Scala in London LondonScala User Group http://www.meetup.com/london-scala/ regular meetups – recorded and available at http://skillsmatter.com/go/scala LSUG Scala Dojo
  • 69.

Editor's Notes

  • #4 In static typing all expressions have their types determined prior to the program being run (typically at compile-time). Dynamic typing determines the type-safety of operations at runtime - types are associated with runtime values rather than textual expressions. Strong typing = type safe Weak typing allows a value of one type to be treated as another. Think of if(1) {} Static/Dynamic typing is about when type information is acquired (Either at compile- or at runtime) Strong/Weak typing is about how strictly types are distinguished (e.g. whether the language tries to do implicit conversion from strings to numbers). Strong typing means the language detects when two types are compatible – it can throw an error or coerce the types if they are not. Static typing – compilers know more about your code, greater tool support.
  • #5 It&apos;s true that tools now can generate most of the boilerplate code for us. Unfortunately they do not read it yet.
  • #6 Functional programs are made up of functions. A function always returns a value. A function, given the same inputs, will return the same values. Functional programs avoid changing state or mutating data. Functional programming concepts are important when dealing with concurrent applications. Functional programming is a declarative style in which you say what to do instead of how something should be done. Java is imperative.
  • #9 Few words on class, variables and methods
  • #10 Scala forces you to explicitly make a decision about whether a variable is mutable.
  • #25 Compiler sees Int But Int does not have days function It then searches for a implicit conversion from Int to a type that support days It finds method converting Int to DateHelper Compiler invokes days on DateHelper
  • #26 decorate objects with capabilities add behaviours to the class hierarchy
  • #31 Helper functions do not pollute namespace
  • #36 Closure = function literal that binds to, or close over, variables outside of their local scope and parameter list. A closure is simply a more convenient way to give a function access to local state.
  • #38 No new keyword. But constructor is an option too. This is used in pattern matching.
  • #39 Pattern matching is used to conditionally execute code based on some piece of data.
  • #44 Scala does not require catching checked exceptions
  • #48 Scala comes with their own collections. You can still use java collections however. By default you work with immutable collections. There are mutable implementations as well.
  • #49 Except functions you would normally expect defined on a collection: length, reverse, contains, slice, etc.
  • #56 an Actor is an object that receives messages and takes action on those messages
  • #61 http://www.scalatest.org/
  • #62 IDEA: rename – SHIFT + F6 format – ALT + CMD + L refactor new FileReader – gives you a hint Alt+Enter
  • #66 Have a look at Scala API - dynamic