Scala at GenevaJUG by Iulian Dragos

63
Introduction to Scala Iulian Dragos Scala Solutions

description

Scala is a general purpose programming language designed to express common programming patterns in a concise, elegant, and type-safe way. It has established itself as one of the main alternative languages on the Java Virtual Machine, being used by companies like Twitter and LinkedIn. Scala fuses functional programming (from which it borrows higher-order functions and closures, generic typing and immutable data structures) and object-oriented programming programming (from which it takes inheritance and encapsulation). It interoperates fully with Java, allowing a smooth transition and access to all existing Java libraries. Scala’s lightweight syntax makes it easy to extend the language through DSLs. In this talk we are going to have a quick overview of Scala’s main features (closures, higher-order functions, implicits), and collection classes in the standard library. We’ll see how a new concurrency model, such as actors, can be added to the language through a library.

Transcript of Scala at GenevaJUG by Iulian Dragos

Page 1: Scala at GenevaJUG by Iulian Dragos

Introduction to Scala

Iulian Dragos Scala Solutions

Page 2: Scala at GenevaJUG by Iulian Dragos

What is Scala

A programming language that

•  combines functional programming and object-oriented programming

•  is statically typed yet concise

•  runs on the JVM and is fully interoperable with Java

•  as fast as Java

•  created at EPFL by Martin Odersky

2

Page 3: Scala at GenevaJUG by Iulian Dragos

3

Where it comes from Scala has established itself as one of the main alternative languages

on the JVM.

Prehistory:

1996 – 1997: Pizza 1998 – 2000: GJ, Java generics, javac

( “make Java better” )

Timeline:

2003 – 2006: The Scala “Experiment” 2006 – 2009: An industrial strength programming language

( “make a better Java” )

Page 4: Scala at GenevaJUG by Iulian Dragos

Momentum

4

Open-source language with

 Site scala-lang.org: 100K+ visitors/month

  40,000 downloads/month, 10x growth last year

  16 books in print  Two conferences: Scala Liftoff and ScalaDays   33+ active user groups

  60% USA, 30% Europe, 10% rest

Page 5: Scala at GenevaJUG by Iulian Dragos

5

Page 6: Scala at GenevaJUG by Iulian Dragos

6

Why Scala?

Page 7: Scala at GenevaJUG by Iulian Dragos

7

Scala is a Unifier

Agile, with lightweight syntax

Object-Oriented Scala Functional

Safe and performant, with strong static tpying

Page 8: Scala at GenevaJUG by Iulian Dragos

8

Let’s see an example:

Page 9: Scala at GenevaJUG by Iulian Dragos

9

A class ... public  class  Person  {  

   public  final  String  name;  

   public  final  int  age;  

   Person(String  name,  int  age)  {  

           this.name  =  name;  

           this.age  =  age;  

   }  

}  

class  Person(val  name:  String,                              val  age:  Int)  

... in Java:

... in Scala:

Page 10: Scala at GenevaJUG by Iulian Dragos

10

... and its usage import  java.util.ArrayList;  ...  Person[]  people;  Person[]  minors;  Person[]  adults;  {    ArrayList<Person>  minorsList  =  new  ArrayList<Person>();  

     ArrayList<Person>  adultsList  =  new  ArrayList<Person>();        for  (int  i  =  0;  i  <  people.length;  i++)                (people[i].age  <  18  ?  minorsList  :  adultsList)  

         .add(people[i]);        minors  =  minorsList.toArray(people);        adults  =  adultsList.toArray(people);  

}  

... in Java:

... in Scala: val  people:  Array[Person]  val  (minors,  adults)  =  people  partition  (_.age  <  18)  

A simple pattern match

An infix method call

A function value

Page 11: Scala at GenevaJUG by Iulian Dragos

Functions

Scala has first-class functions (closures)

11

val  f  =  (x:  Int)  =>  x  *  x  

x  =>  x  *  x  

f.apply(4)  or f(4)  

and you can call them using

Page 12: Scala at GenevaJUG by Iulian Dragos

Functions

12

xs.map(x  =>  x  *  x)  

ps.filter(p  =>  p.age  >  18)  

Control structures (think: loops) can be reused

ps.filter(_.age  >  18).map(_.name)  

Page 13: Scala at GenevaJUG by Iulian Dragos

For-comprehensions

More than a simple for loop

13

for  (x  <-­‐  xs)  println(x)   xs.foreach(println)  

for  (x  <-­‐  xs)  yield  x  *  x   xs.map(x  =>  x  *  x)  

for  (p  <-­‐  ps  if  p.age  >  18)  yield  (p.age,  p)  

ps.filter(_.age  >  18).map(p  =>  (p.age,  p))  

generator guard

==  

==  

Page 14: Scala at GenevaJUG by Iulian Dragos

Mix-in composition

14

Page 15: Scala at GenevaJUG by Iulian Dragos

Traits

Like Java interfaces, but may have concrete methods

15

trait  Ordered[T]  {      def  compare(that:  T):  Int  

   def  <  (that:  T):  Boolean  =              (this  compare  that)  <    0      def  <=(that:  T):  Boolean  =            (this  compare  that)  <=  0      …  }  

abstract method

Page 16: Scala at GenevaJUG by Iulian Dragos

Cells

Let’s define a class for mutable cells – with variants for logging and undoable cells.

16

Page 17: Scala at GenevaJUG by Iulian Dragos

Cells

17

class  Cell[T](init:  T)  {      private  var  v  =  init  

   def  get():  T  =  v      def  set(v1:  T):  Unit  =  {  v  =  v1  }  

   override  def  toString:  String  =          "Cell("+  v  +")”  }  

Page 18: Scala at GenevaJUG by Iulian Dragos

Logging

18

trait  LoggingCell[T]  extends  Cell[T]  {      override  def  get():  T  =  {          println("getting  "+  this)          super.get()      }      

   override  def  set(v1:  T)  {          println("setting  "+  this  +"  to  "+  v1)          super.set(v1)      }      

}  

Page 19: Scala at GenevaJUG by Iulian Dragos

Undoing

19

trait  UndoableCell[T]  extends  Cell[T]  {      private  var  hist  =  new  ArrayStack[T]()  

   override  def  set(v1:  T):  Unit  =  {          hist.push(super.get())          super.set(v1)      }      

   def  undo():  Unit  =  super.set(hist.pop)  }  

Page 20: Scala at GenevaJUG by Iulian Dragos

Mix-in composition

20

new  Cell(0)        with  UndoableCell[Int]    //  logging  and  undoing      with  LoggingCell[Int]      

new  Cell(0)            //  basic  integer  cell  

new  Cell(0)        with  LoggingCell[Int]  //  logging  cell  

new  Cell(0)        with  LoggingCell[Int]    //  logging  and  undoing      with  UndoableCell[Int]      

Page 21: Scala at GenevaJUG by Iulian Dragos

21

But there’s more to it

Page 22: Scala at GenevaJUG by Iulian Dragos

22

Embedding Domain-Specific Languages

Scala’s flexible syntax makes it easy to define high-level APIs & embedded DSLs

Examples: - Scala actors (the core of Twitter’s message queues) - specs, ScalaCheck - ScalaFX - ScalaQuery

scalac’s plugin architecture makes it easy to typecheck DSLs and to enrich their semantics.

//  asynchronous  message  send  actor  !  message  

//  message  receive  

receive  {  

   case  msgpat1  =>  action1      …          

   case  msgpatn  =>  actionn  }  

Page 23: Scala at GenevaJUG by Iulian Dragos

23

The Essence of Scala

The work on Scala was motivated by two hypotheses:

Hypothesis 1: A general-purpose language needs to be scalable; the same concepts should describe small as well as large parts.

Hypothesis 2: Scalability can be achieved by unifying and generalizing functional and object-oriented programming concepts.

Page 24: Scala at GenevaJUG by Iulian Dragos

24

Why unify FP and OOP?

Both have complementary strengths for composition:

Object-oriented programming:

Makes it easy to adapt and extend complex systems, using

•  subtyping and inheritance, •  dynamic configurations, •  classes as partial abstractions.

Functional programming:

Makes it easy to build interesting things from simple parts, using

•  higher-order functions, •  algebraic types and pattern matching, •  parametric polymorphism.

Page 25: Scala at GenevaJUG by Iulian Dragos

25

Scala

•  Scala is an object-oriented and functional language which is completely interoperable with Java. (the .NET version is currently under reconstruction.)

•  It removes some of the more arcane constructs of these environments and adds instead: (1) a uniform object model, (2) pattern matching and higher-order

functions, (3) novel ways to abstract and compose

programs.

Page 26: Scala at GenevaJUG by Iulian Dragos

26

Scala is interoperable

Scala programs interoperate seamlessly with Java class libraries: –  Method calls –  Field accesses –  Class inheritance –  Interface implementation

all work as in Java. Scala programs compile to JVM bytecodes.

Scala’s syntax resembles Java’s, but there are also some differences.

object Example1 { def main(args: Array[String]) { val b = new StringBuilder() for (i ← 0 until args.length) { if (i > 0) b.append(" ") b.append(args(i).toUpperCase) } Console.println(b.toString) }

}

object instead of static members Array[String] instead of

String[]

Scala’s version of the extended for loop

(use <- as an alias for ←) Arrays are indexed args

(i) instead of args[i]

Page 27: Scala at GenevaJUG by Iulian Dragos

27

Scala is functional

The last program can also be written in a completely different style: –  Treat arrays as instances of

general sequence abstractions. –  Use higher-order

functions instead of loops.

object Example2 { def main(args: Array[String]) { println(args .map(_.toUpperCase) .mkString(" ") } }

Arrays are instances of sequences with map and mkString methods.

A closure which applies the toUpperCase method to its

String argument

map is a method of Array which applies the function on its right

to each array element.

mkString is a method of Array which forms a string of all elements with a

given separator between them.

Page 28: Scala at GenevaJUG by Iulian Dragos

28

Scala is concise

Scala’s syntax is lightweight and concise.

Contributors: –  semicolon inference, –  type inference, –  lightweight classes, –  extensible API’s, –  closures as

control abstractions.

Average reduction in LOC wrt Java: ≥ 2 due to concise syntax and better abstraction capabilities

***** Guy Steele: Scala led to a 4 times LOC reduction in the Fortress typechecker *****

var capital = Map( "US" → "Washington", "France" → "paris", "Japan" → "tokyo" )

capital += ( "Russia" → "Moskow" )

for ( (country, city) ← capital ) capital += ( country → city.capitalize )

assert ( capital("Japan") == "Tokyo" )

Page 29: Scala at GenevaJUG by Iulian Dragos

29

Scala is precise

All code on the previous slide used library abstractions, not special syntax.

Advantage: Libraries are extensible and give fine- grained control.

Elaborate static type system catches many errors early.

import scala.collection.mutable._

val capital = new HashMap[String, String] with SynchronizedMap[String, String] { override def default(key: String) = "?" }

capital += ( "US" → "Washington", "France" → "Paris", "Japan" → "Tokyo" )

assert( capital("Russia") == "?" )

Specify kind of collections: mutable Specify map implementation: HashMap Specify map type: String to String

Mixin trait SynchronizedMap to make capital map thread-safe

Provide a default value: "?"

Page 30: Scala at GenevaJUG by Iulian Dragos

30

Big or small? Every language design faces the tension whether it should be big or small:

–  Big is good: expressive, easy to use.

–  Small is good: elegant, easy to learn.

Can a language be both big and small?

Scala’s approach: concentrate on abstraction and composition capabilities instead of basic language constructs.

Scala adds Scala removes

+ a pure object system

- static members

+ operator overloading

- special treatment of primitive types

+ closures as control abstractions

- break, continue

+ mixin composition with traits

- special treatment of interfaces

+ abstract type members

- wildcards

+ pattern matching

Page 31: Scala at GenevaJUG by Iulian Dragos

31

Implicits are Poor Man’s Type Classes

/** A “type class” */ class Ord[T] { def < (x: T, y: T): Boolean }

/** An “instance definition” */ implicit object intOrd extends Ord[Int] { def < (x: Int, y: Int) = x < y }

/** Another instance definition */ implicit def listOrd[T](implicit tOrd: Ord[T]) = new Ord { def < (xs: List[T], ys: List[T]) = (xs, ys) match { case (_, Nil) => false case (Nil, _) => true case (x :: xs, y :: ts) => x < y || x == y && xs < ys } }

Page 32: Scala at GenevaJUG by Iulian Dragos

32

The Bottom Line When going from Java to Scala, expect at least a factor of 2 reduction in LOC.

But does it matter? Doesn’t Eclipse write these extra lines for me?

This does matter. Eye-tracking experiments* show that for program comprehension, average time spent per word of source code is constant.

So, roughly, half the code means half the time necessary to understand it.

*G. Dubochet. Computer Code as a Medium for Human Communication: Are Programming Languages Improving? In 21st Annual Psychology of Programming Interest Group Conference, pages 174-187, Limerick, Ireland, 2009.

Page 33: Scala at GenevaJUG by Iulian Dragos

33

Extensibility

Take numeric data types: –  Today's languages support int,  long,  float,  double. –  Should they also support BigInt,  BigDecimal,  Complex,  Rational,  

Interval,  Polynomial? There are good reasons for each of these types But a language combining them all would be too complex.

Better alternative: Let users grow their language according to their needs.

Page 34: Scala at GenevaJUG by Iulian Dragos

34

Scala is extensible

Guy Steele has formulated a benchmark for measuring language extensibility [Growing a Language, OOPSLA 98]:

Can you add a type of complex numbers to the library and make it work as if it was a native number type?

Similar problems: Adding type BigInt, Decimal, Intervals, Polynomials...

scala> import Complex._ import Complex._

scala> val x = 1 + 1 * i x: Complex = 1.0+1.0*i

scala> val y = x * i y: Complex = -1.0+1.0*i

scala> val z = y + 1 z: Complex = 0.0+1.0*i

Page 35: Scala at GenevaJUG by Iulian Dragos

object  Complex  {      val  i  =  new  Complex(0,  1)      implicit  def  double2complex(x:  Double):  Complex  =            new  Complex(x,  0)      ...  }  class  Complex(val  re:  Double,  val  im:  Double)  {      def  +(that:  Complex):  Complex  =            new  Complex(this.re  +  that.re,  this.im  +  that.im)      def  -­‐(that:  Complex):  Complex  =            new  Complex(this.re  -­‐  that.re,  this.im  -­‐  that.im)  

   override  def  toString  =            re+(if  (im  <  0)  "-­‐"+(-­‐im)  else  "+"+im)+"*I"      ...    }   35

Implementing complex numbers

+ is an identifier; can be used as a method name

Infix operations are method calls: a + b is the same as a.+(b)

Objects replace static class members

Implicit conversions for mixed arithmetic Class parameters instead of fields+ explicit constructor

Page 36: Scala at GenevaJUG by Iulian Dragos

36

Adding new datatypes - seamlessly

For instance type BigInt:

def  factorial(x:  BigInt):  BigInt  =        if  (x  ==  0)  1  else  x  *  factorial(x  -­‐  1)  

Compare with using Java's class:

import  java.math.BigInteger  def  factorial(x:  BigInteger):  BigInteger  =      if  (x  ==  BigInteger.ZERO)          BigInteger.ONE      else          x.multiply(factorial(x.subtract(BigInteger.ONE)))  }  

Page 37: Scala at GenevaJUG by Iulian Dragos

37

Implementing new datatypes - seamlessly

Here's how BigInt is implemented

import  java.math.BigInteger  

class  BigInt(val  bigInteger:  BigInteger)    extends  java.lang.Number  {  

   def  +  (that:  BigInt)  =            new  BigInt(this.bigInteger  add  that.bigInteger)  

   def  -­‐  (that:  BigInt)  =            new  BigInt(this.bigInteger  subtract  that.bigInteger)  

   …      //  other  methods  implemented  analogously  }  

+ is an identifier; can be used as a method name

Infix operations are method calls: a + b is the same as a.+(b)

a add b is the same as a.add(b)

Page 38: Scala at GenevaJUG by Iulian Dragos

38

Adding new control structures

•  For instance using for resource control (in Java 7)

•  Instead of:

using  (new  BufferedReader(new  FileReader(path)))  {      f  =>  println(f.readLine())  }  

val  f  =  new  BufferedReader(new  FileReader(path))  try  {      println(f.readLine())  }  finally  {      if  (f  !=  null)            try  f.close()          catch  {  case  ex:  IOException  =>  }  }  

Page 39: Scala at GenevaJUG by Iulian Dragos

39

Implementing new control structures: Here's how one would go about implementing using:

def  using[T  <:  {  def  close()  }]                    (resource:  T)                    (block:  T  =>  Unit)  =      try  {          block(resource)      }  finally  {          if  (resource  !=  null)                try  resource.close()              catch  {  case  ex:  IOException  =>  }      }  

T is a type parameter... … supporting a close method

A closure that takes a T parameter

Page 40: Scala at GenevaJUG by Iulian Dragos

Producer or Consumer?

Scala feels radically different for producers and consumers of advanced libraries.

For the consumer: –  Really easy –  Things work intuitively –  Can concentrate on domain, not implementation

For the producer: –  Sophisticated tool set –  Can push the boundaries of what’s possible –  Requires expertise and taste

40

Page 41: Scala at GenevaJUG by Iulian Dragos

41

Scalability at work: Scala 2.8 Collections

Page 42: Scala at GenevaJUG by Iulian Dragos

42

Collection Properties

•  object-oriented •  generic: List[T],  Map[K,  V]  •  optionally persistent, e.g.

collection.immutable.Seq  •  higher-order, with methods

such as foreach,  map,  filter.  

•  Uniform return type principle: Operations return collections of the same type (constructor) as their left operand, as long as this makes sense.

scala> val ys = List(1, 2, 3) ys: List[Int] = List(1, 2, 3)

scala> val xs: Seq[Int] = ys xs: Seq[Int] = List(1, 2, 3)

scala> xs map (_ + 1) res0: Seq[Int] = List(2, 3, 4)

scala> ys map (_ + 1) res1: List[Int] = List(2, 3, 4)

This makes a very elegant and powerful combination.

Page 43: Scala at GenevaJUG by Iulian Dragos

Using Collections: Map and filter scala> val xs = List(1, 2, 3)

xs: List[Int] = List(1, 2, 3)

scala> val ys = xs map (x => x + 1)

ys: List[Int] = List(2, 3, 4)

scala> val ys = xs map (_ + 1)

ys: List[Int] = List(2, 3, 4)

scala> val zs = ys filter (_ % 2 == 0)

zs: List[Int] = List(2, 4)

scala> val as = ys map (0 to _)

as: List(Range(0, 1, 2), Range(0, 1, 2, 3), Range(0, 1, 2, 3, 4))

43

Page 44: Scala at GenevaJUG by Iulian Dragos

scala> val bs = as.flatten

bs: List[Int] = List(0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4)

scala> val bs = ys flatMap (0 to _)

bs: List[Int] = List(0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4)

44

Using Collections: Flatmap

Page 45: Scala at GenevaJUG by Iulian Dragos

scala> for (x <- xs) yield x + 1 // same as map

res14: List[Int] = List(2, 3, 4)

scala> for (x <- res14 if x % 2 == 0) yield x // ~ filter

res15: List[Int] = List(2, 4)

scala> for (x <- xs; y <- 0 to x) yield y // same as flatMap res17: List[Int] = List(0, 1, 0, 1, 2, 0, 1, 2, 3)

45

Using Collections: For Notation

Page 46: Scala at GenevaJUG by Iulian Dragos

scala> val m = Map('1' -> "ABC", 2 -> "DEF", 3 -> "GHI")

m: Map[AnyVal, String] = Map((1,ABC), (2,DEF), (3,GHI))

scala> val m = Map(1 -> "ABC", 2 -> "DEF", 3 -> "GHI")

m: Map[Int, String] = Map((1,ABC), (2,DEF), (3,GHI))

scala> m(2)

res0: String = DEF

scala> m + (4 -> "JKL")

res1: Map[Int, String] = Map((1,ABC), (2,DEF), (3,GHI), (4,JKL))

scala> m map { case (k, v) => (v, k) }

res8: Map[String,Int] = Map((ABC,1), (DEF,2), (GHI,3))

46

Using Maps

Page 47: Scala at GenevaJUG by Iulian Dragos

2-47

An Example

•  Task: Phone keys have mnemonics assigned to them. val  mnemonics  =  Map(  

           '2'  -­‐>  "ABC",  '3'  -­‐>  "DEF",  '4'  -­‐>  "GHI",  '5'  -­‐>  "JKL",                '6'  -­‐>  "MNO",  '7'  -­‐>  "PQRS",  '8'  -­‐>  "TUV",  '9'  -­‐>  "WXYZ")  

•  Assume you are given a dictionary dict as a list of words. Design a class Coder with a method translate such that

new  Coder(dict).translate(phoneNumber)     produces all phrases of words in dict that can serve as mnemonics for the phone number.

•  Example: The phone number “7225276257” should have the mnemonic Scala  rocks  

as one element of the list of solution phrases.

Page 48: Scala at GenevaJUG by Iulian Dragos

2-48

Program Example: Phone Mnemonics

•  This example was taken from: Lutz Prechelt: An Empirical Comparison of Seven Programming

Languages. IEEE Computer 33(10): 23-29 (2000)

•  Tested with Tcl, Python, Perl, Rexx, Java, C++, C

•  Code size medians: –  100 loc for scripting languages –  200-300 loc for the others

Page 49: Scala at GenevaJUG by Iulian Dragos

2-49

Outline of Class Coder  

import  collection.mutable.HashMap    

class  Coder(words:  List[String])  {  

   private  val  mnemonics  =  Map(              '2'  -­‐>  "ABC",  '3'  -­‐>  "DEF",  '4'  -­‐>  "GHI",  '5'  -­‐>  "JKL",                '6'  -­‐>  "MNO",  '7'  -­‐>  "PQRS",  '8'  -­‐>  "TUV",  '9'  -­‐>  "WXYZ")  

   /**  Invert  the  mnemonics  map  to  give  a  map  from  chars  'A'  ...  'Z'  to  '2'  ...  '9'  */      private  val  upperCode:  Map[Char,  Char]  =  ??  

   /**  Maps  a  word  to  the  digit  string  it  can  represent  */      private  def  wordCode(word:  String):  String  =  ??  

   /**  A  map  from  digit  strings  to  the  words  that  represent  them  */      private  val  wordsForNum  =  new  HashMap[String,  Set[String]]  {          override  def  default(number:  String)  =  Set()      }      for  (word  <-­‐  words)  wordsForNum(wordCode(word))  +=  word  

   /**  Return  all  ways  to  encode  a  number  as  a  list  of  words  */      def  encode(number:  String):  List[List[String]]  =  ??  

   /**  Maps  a  number  to  a  list  of  all  word  phrases  that  can  represent  it  */      def  translate(number:  String):  List[String]  =  encode(number)  map  (_  mkString  "  ")  }

Page 50: Scala at GenevaJUG by Iulian Dragos

2-50

Class Coder  (1)  import  collection.mutable.HashMap    

class  Coder(words:  List[String])  {  

   private  val  mnemonics  =  Map(              '2'  -­‐>  "ABC",  '3'  -­‐>  "DEF",  '4'  -­‐>  "GHI",  '5'  -­‐>  "JKL",                '6'  -­‐>  "MNO",  '7'  -­‐>  "PQRS",  '8'  -­‐>  "TUV",  '9'  -­‐>  "WXYZ")  

   /**  Invert  the  mnemonics  map  to  give  a  map  from  chars  'A'  ...  'Z'  to  '2'  ...  '9'  */      private  val  upperCode:  Map[Char,  Char]  =       for  ((digit,  str)  <-­‐  m;  letter  <-­‐  str)  yield  (letter  -­‐>  digit)  

   /**  Maps  a  word  to  the  digit  string  it  can  represent  */      private  def  wordCode(word:  String):  String  =  word  map  (c  =>  upperCode(c.toUpper))  

   /**  A  map  from  digit  strings  to  the  words  that  represent  them  */      private  val  wordsForNum  =  new  HashMap[String,  Set[String]]  {          override  def  default(number:  String)  =  Set()      }      for  (word  <-­‐  words)  wordsForNum(wordCode(word))  +=  word  

   /**  Return  all  ways  to  encode  a  number  as  a  list  of  words  */      def  encode(number:  String):  List[List[String]]  =  ??  

   /**  Maps  a  number  to  a  list  of  all  word  phrases  that  can  represent  it  */      def  translate(number:  String):  List[String]  =  encode(number)  map  (_  mkString  "  ")  }

Page 51: Scala at GenevaJUG by Iulian Dragos

2-51

Class Coder  (2)  

import  collection.mutable.HashMap    

class  Coder(words:  List[String])  {  

   ...  

   /**  Return  all  ways  to  encode  a  number  as  a  list  of  words  */      def  encode(number:  String):  List[List[String]]  =    

 if  (number.isEmpty)              List(List())          else  

           for  {            splitPoint  <-­‐  (1  to  number.length).toList  

               word  <-­‐  wordsForNum(number  take  splitPoint)                  rest  <-­‐  encode(number  drop  splitPoint)  

           }  yield  word  ::  rest  

   /**  Maps  a  number  to  a  list  of  all  word  phrases  that  can  represent  it  */      def  translate(number:  String):  List[String]  =  encode(number)  map  (_  mkString  "  ")  }

Page 52: Scala at GenevaJUG by Iulian Dragos

52

Going Further

•  In Scala 2.9, collections will support parallel operations.

•  Will be out by February 2011.

•  The right tool for addressing the PPP (popular parallel programming) challenge.

•  I expect this to be the cornerstone for making use of multicores for the rest of us.

Page 53: Scala at GenevaJUG by Iulian Dragos

53

But how long will it take me to switch?

Page 54: Scala at GenevaJUG by Iulian Dragos

54

100%

200%

0%

4-6 weeks 8-12 weeks

Learning Curves

Scala

Keeps familiar environment: :

IDE’s: Eclipse, IDEA, Netbeans, ...

Tools: JavaRebel, FindBugs, Maven, ...

Libraries: nio, collections, FJ, ...

Frameworks; Spring, OSGI, J2EE, ...

...all work out of the box. .

Alex Payne, Twitter:

“Ops doesn’t know it’s not Java”

Productivity

Alex McGuire, EDF, who replaced majority of 300K lines Java with Scala: “Picking up Scala was really easy.” “Begin by writing Scala in Java style.” “With Scala you can mix and match with your old Java.” “You can manage risk really well.”

Page 55: Scala at GenevaJUG by Iulian Dragos

55

How to get started

100s of resources on the web.

Here are three great entry points:

•  Scala for Java refugees •  Simply Scala •  Scalazine @ artima.com

Page 56: Scala at GenevaJUG by Iulian Dragos

56

How to find out more Scala site: www.scala-lang.org 16 books

Page 57: Scala at GenevaJUG by Iulian Dragos

57

Support

Open Source Ecosystem ...

akka scalable actors sbt simple build tool lift, play web frameworks kestrel, querulous middleware from Twitter Migrations middleware from Sony ScalaTest, specs, ScalaCheck testing support ScalaModules OSGI integration

... complemented by commercial support

Page 58: Scala at GenevaJUG by Iulian Dragos

58

Thank You

Page 59: Scala at GenevaJUG by Iulian Dragos

59

Page 60: Scala at GenevaJUG by Iulian Dragos

60

Scala cheat sheet (1): Definitions

Scala method definitions:

def  fun(x:  Int):  Int  =  {      result  }  

or  def  fun(x:  Int)  =  result  

   def  fun  =  result  

Scala variable definitions:

var  x:  Int  =  expression  val  x:  String  =  expression  

or    var  x  =  expression  val  x  =  expression  

Java method definition:

int  fun(int  x)  {        return  result;  }  

(no parameterless methods)

Java variable definitions:

int  x  =  expression  final  String  x  =  expression  

Page 61: Scala at GenevaJUG by Iulian Dragos

61

Scala cheat sheet (2): Expressions

Scala method calls:

obj.meth(arg)  or obj  meth  arg  

Scala choice expressions:

if  (cond)  expr1  else  expr2

expr  match  {      case  pat1  =>  expr1      ....  

     case  patn  =>  exprn    }  

Java method call:

obj.meth(arg)   (no operator overloading)

Java choice expressions, stats:

cond  ?  expr1  :  expr2

if  (cond)  return  expr1;     else  return  expr2;  

switch  (expr)  {          case  pat1  :  return  expr1;            ...            case  patn  :  return  exprn  ;    }    //  statement  only  

Page 62: Scala at GenevaJUG by Iulian Dragos

62

Scala cheat sheet (3): Objects and Classes

Scala Class and Object

class  Sample(x:  Int)  {      def  instMeth(y:  Int)  =  x  +  y  }  

object  Sample  {      def  staticMeth(x:Int,  y:Int)          =  x  *  y  }  

Java Class with static

class  Sample  {      final  int  x;      Sample(int  x)  {            this.x  =  x        }  

   int  instMeth(int  y)  {            return  x  +  y;        }  

   static        int  staticMeth(int  x,int  y)  {              return  x  *  y;      }  }  

Page 63: Scala at GenevaJUG by Iulian Dragos

63

Scala cheat sheet (4): Traits

Scala Trait

trait  T  {      def  absMeth(x:String):String  

   def  concreteMeth(x:  String)  =            x+field  

   var  field  =  “!”  

 }  

Scala mixin composition:

class  C  extends  Super  with  T          

Java Interface

interface  T  {      String  absMeth(String  x)  

   (no concrete methods)

(no fields) }  

Java extension + implementation:

class  C  extends  Super                    implements  T