SlideShare a Scribd company logo
By : Adi Baron, “Tikal”  For Java Programmers
"Which Programming Language would you use  *now* on top of JVM, except Java?" “ Scala”
Since   2003 Runs on   JVM Pragmatic High Level Statically  Typed Seamless  Java   interoperability Scalable EPFL Object Oriented Functional Production
A language that grows on you To the Point Not cluttered Not syntax var  capital =  Map( "US"  ->  "Washington" ,  "France"  ->  "Paris" ) capital += ( "Japan"  ->  "Tokyo" ) println(capital( "France" ))
Growing new types import  java.math.BigInteger; public  BigInteger  factorial (BigInteger x) { if  (x == BigInteger. ZERO ) { return  BigInteger. ONE ; } return  x.multiply(factorial( x.subtract(BigInteger. ONE ))); } def  factorial(x:  BigInt ):  BigInt  = if  (x == 0) 1  else  x * factorial(x - 1)
Growing new control constructs Scala Actors Implemented on top of threads Two basic operations – Send / Receive recipient ! msg ←  async receive { case   Msg1  =>  … // handle Msg1 case   Msg2  =>  … // handle Msg2 // …  } ←  mailbox
Growing new control constructs val  checksum = actor { var  sum = 0 loop { receive { case   Data (bytes)  => sum += hash(bytes) case   GetSum (requester) => requester ! sum } } }
High-Level boolean  nameHasUpperCase =  false ; for  ( int  i = 0; i < name.length(); ++i) { if  (Character.isUpperCase(name.charAt(i))) { nameHasUpperCase =  true ; break ; } } val  nameHasUpperCase = name.exists(_.isUpperCase)
Concise public  class MyClass { private   int   id ; private  String  description ; public  MyClass( int  id, String description) { this . id  = id; this . description  = description; } public   int  getId() { return   id ; } public   void  setId( int  id) { this . id  = id; } public  String getDescription() { return   description ; } public   void  setDescription(String description) { this . description  = description; } } class   MyClass (id:  Int , description:  String )
What makes it scalable?
is Object Oriented
Pure Object Oriented 1 + 2 1.+(2) 123.toString
Example – Rational Number A number that can be expressed a ratio  n (numerator) & d (denominator) are integers Operations – Add, Subtract, Multiply, Divide n _ d class   Rational (n:  Int , d:  Int ) class   Rational (n:  Int , d:  Int ) { println( “Created “  + n +  “/”  + d) } scala>  new   Rational (1, 2) Created 1/2 res0: Rational = Rational@90110a
Example – Rational Number Implementing toString class   Rational (n:  Int , d:  Int ) { override   def  toString = n +  “/”  + d } scala>  val  x =  new   Rational (1, 3) x: Rational = 1/3 scala>  val  x =  new   Rational (5, 7) y: Rational = 5/7
Example – Rational Number Input Validation class   Rational (n:  Int , d:  Int ) { require(d != 0) override   def  toString = n +  “/”  + d } scala>  new   Rational (5, 0) res0: Rational = 5/0
Example – Rational Number Add Fields class   Rational (n:  Int , d:  Int ) { require(d != 0) val  numer:  Int  = n val  denom:  Int  = d override   def  toString = n +  “/”  + d def  add(that:  Rational ):  Rational  = new   Rational ( numer * that.denom + that.numer * denom, denom * that.denom ) } class   Rational (n:  Int , d:  Int ) {  // This won’t compile require(d != 0) override   def  toString = n +  “/”  + d def  add(that:  Rational ):  Rational  = new   Rational (n * that.d + that.n * d, d * that.d) }
Example – Rational Number Adding scala>  val  oneHalf =  new   Rational (1, 2) oneHalf: Rational = 1/2 scala>  val  twoThirds =  new   Rational (2, 3) twoThirds: Rational = 2/3 scala> oneHalf add twoThirds res3: Rational = 7/6
Example – Rational Number A better version class   Rational (n:  Int , d:  Int ) { require(d != 0) val  numer:  Int  = n val  denom:  Int  = d def   this (n:  Int ) =  this (n, 1) def  +(that:  Rational ):  Rational  = new   Rational ( numer * that.denom + that.numer * denom, denom * that.denom ) override   def  toString = n +  “/”  + d }
Example – Rational Number Finally scala>  val  x =  new   Rational (1, 2) x: Rational = 1/2 scala>  val  y =  new   Rational (2, 3) y: Rational = 2/3 scala> x + y res8: Rational = 7/6
Traits
Trait trait   Dad  { private var  children:  List [ Child ] =  Nil def  addChild(child:  Child ) = children = child :: children def  getChildren = children.clone }
Base class   Man ( val  name:  String )  extends   Human
Static mixin composition class   Man ( val  name:  String )  extends   Human  with  Dad val  adi =  new   Man ( “Adi” ) adi.addChild( new   Child ( “Yehonatan” )) adi.addChild( new   Child ( “Lior” ))
Dynamic mixin composition class   Man ( val  name:  String )  extends   Human val  adi =  new   Man ( “Adi” )  with  Dad adi.addChild( new   Child ( “Yehonatan” )) adi.addChild( new   Child ( “Lior” ))
Composition class   MrPotato (name:  String )  extends   MrPotatoHead with  Eyes with  Ears with  Mouth with  Nose with  Hands with  Hat with  Shoes
is Functional
First Class Functions (x:  Int ) => x + 1 Function literal Compilation Function class Runtime – function value
Functions as values scala>  val  increase = (x:  Int ) => x + 1 increase: (Int) => Int = <function> scala> increase(10) res0: Int = 11 => converts the “thing” on the left (any integer x) to the thing pm the right (x + 1)
Functions as parameters scala>  val  someNumbers =  List (-11, -10, -5, 0, 5, 10) someNumbers: List[Int] = List(-11, -10, -5, 0, 5, 10) scala> someNumbers.foreach((x:  Int ) => println(x)) -11 -10 -5 0 5 10 scala> someNumbers.filter((x:  Int ) => x > 0) res6: List[Int] = List(5, 10)
Short form of function literals scala> someNumbers.filter((x) => x > 0) res7: List[Int] = List(5, 10) scala> someNumbers.filter(x => x > 0) res8: List[Int] = List(5, 10) Target typing Leave the parentheses out
Placeholder syntax scala> someNumbers.filter(_ > 0) res9: List[Int] = List(5, 10) “ Fill in” the missing... scala>  val  f = _ + _ <console>:4: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2)) val f = _ + _ ˆ Type inference caution scala>  val  f = (_:  Int ) + (_:  Int ) f: (Int, Int) => Int = <function>
Functions as closures (x:  Int ) => x + more  // how much more?
Functions as closures scala> (x:  Int ) => x + more <console>:5: error: not found: value more (x: Int) => x + more ˆ scala>  var  more = 1 more: Int = 1 scala>  val  addMore = (x:  Int ) => x + more addMore: (Int) => Int = <function> scala> addMore(10) res19: Int = 11
Functions as closures def  makeIncreaser(more:  Int ) = (x:  Int ) => x + more scala>  val  inc1 = makeIncreaser(1) inc1: (Int) => Int = <function> scala>  val  inc9999 = makeIncreaser(9999) inc9999: (Int) => Int = <function> scala> inc1(10) res24: Int = 11 scala> inc9999(10) res25: Int = 10009
Functional Data Structures
List - Creating Prepends new elements Append time grows linearly List (1, 2, 3) 1 :: 2 :: 3 ::  Nil
List - Basics scala>  val  list =  List (1, 2, 3) list: List[Int] = List(1, 2, 3) scala> list.head res0: Int = 1 scala> list.tail res1: List[Int] = List(2, 3) scala> list.isEmpty res2: Boolean = false
List – High level operations scala>  val  list =  List (1, 2, 3) list: List[Int] = List(1, 2, 3) scala> list.map(_ + 1) res0: List[Int] = List(2, 3, 4) scala> list.filter(_ < 2) res1: List[Int] = List(1) scala> list.exists(_ == 3) res2: Boolean = true scala> list.drop(2) res3: List[Int] = List(3) scala> list.reverse res4: List[Int] = List(3, 2, 1)
Other  Maps Sets Trees Stacks
& Java
Unit Testing - JUnit import  junit.framework.TestCase import  junit.framework.Assert.assertEquals import  junit.framework.Assert.fail import  Element.elem class   ElementTestCase   extends   TestCase  { def  testUniformElement() { val  ele = elem( 'x' , 2, 3) assertEquals(2, ele.width) assertEquals(3, ele.height) try  { elem('x', -2, 3) fail() } catch  { case  e:  IllegalArgumentException  =>  // expected } } }
Unit Testing - TestNG import  org.testng.annotations.Test import  org.testng.Assert.assertEquals import  Element.elem class   ElementTests  { @ Test   def  verifyUniformElement() { val  ele = elem( 'x' , 2, 3) assertEquals(ele.width, 2) assertEquals(ele.height, 3) } @ Test  { val  expectedExceptions =  Array (classOf[ IllegalArgumentException ]) } def  elemShouldThrowIAE() { elem( 'x' , -2, 3) } }
Credits
Jonas Bonér Scalable Solutions &

More Related Content

JBUG 11 - Scala For Java Programmers

  • 1. By : Adi Baron, “Tikal” For Java Programmers
  • 2. &quot;Which Programming Language would you use *now* on top of JVM, except Java?&quot; “ Scala”
  • 3. Since 2003 Runs on JVM Pragmatic High Level Statically Typed Seamless Java interoperability Scalable EPFL Object Oriented Functional Production
  • 4. A language that grows on you To the Point Not cluttered Not syntax var capital = Map( &quot;US&quot; -> &quot;Washington&quot; , &quot;France&quot; -> &quot;Paris&quot; ) capital += ( &quot;Japan&quot; -> &quot;Tokyo&quot; ) println(capital( &quot;France&quot; ))
  • 5. Growing new types import java.math.BigInteger; public BigInteger factorial (BigInteger x) { if (x == BigInteger. ZERO ) { return BigInteger. ONE ; } return x.multiply(factorial( x.subtract(BigInteger. ONE ))); } def factorial(x: BigInt ): BigInt = if (x == 0) 1 else x * factorial(x - 1)
  • 6. Growing new control constructs Scala Actors Implemented on top of threads Two basic operations – Send / Receive recipient ! msg ← async receive { case Msg1 => … // handle Msg1 case Msg2 => … // handle Msg2 // … } ← mailbox
  • 7. Growing new control constructs val checksum = actor { var sum = 0 loop { receive { case Data (bytes) => sum += hash(bytes) case GetSum (requester) => requester ! sum } } }
  • 8. High-Level boolean nameHasUpperCase = false ; for ( int i = 0; i < name.length(); ++i) { if (Character.isUpperCase(name.charAt(i))) { nameHasUpperCase = true ; break ; } } val nameHasUpperCase = name.exists(_.isUpperCase)
  • 9. Concise public class MyClass { private int id ; private String description ; public MyClass( int id, String description) { this . id = id; this . description = description; } public int getId() { return id ; } public void setId( int id) { this . id = id; } public String getDescription() { return description ; } public void setDescription(String description) { this . description = description; } } class MyClass (id: Int , description: String )
  • 10. What makes it scalable?
  • 12. Pure Object Oriented 1 + 2 1.+(2) 123.toString
  • 13. Example – Rational Number A number that can be expressed a ratio n (numerator) & d (denominator) are integers Operations – Add, Subtract, Multiply, Divide n _ d class Rational (n: Int , d: Int ) class Rational (n: Int , d: Int ) { println( “Created “ + n + “/” + d) } scala> new Rational (1, 2) Created 1/2 res0: Rational = Rational@90110a
  • 14. Example – Rational Number Implementing toString class Rational (n: Int , d: Int ) { override def toString = n + “/” + d } scala> val x = new Rational (1, 3) x: Rational = 1/3 scala> val x = new Rational (5, 7) y: Rational = 5/7
  • 15. Example – Rational Number Input Validation class Rational (n: Int , d: Int ) { require(d != 0) override def toString = n + “/” + d } scala> new Rational (5, 0) res0: Rational = 5/0
  • 16. Example – Rational Number Add Fields class Rational (n: Int , d: Int ) { require(d != 0) val numer: Int = n val denom: Int = d override def toString = n + “/” + d def add(that: Rational ): Rational = new Rational ( numer * that.denom + that.numer * denom, denom * that.denom ) } class Rational (n: Int , d: Int ) { // This won’t compile require(d != 0) override def toString = n + “/” + d def add(that: Rational ): Rational = new Rational (n * that.d + that.n * d, d * that.d) }
  • 17. Example – Rational Number Adding scala> val oneHalf = new Rational (1, 2) oneHalf: Rational = 1/2 scala> val twoThirds = new Rational (2, 3) twoThirds: Rational = 2/3 scala> oneHalf add twoThirds res3: Rational = 7/6
  • 18. Example – Rational Number A better version class Rational (n: Int , d: Int ) { require(d != 0) val numer: Int = n val denom: Int = d def this (n: Int ) = this (n, 1) def +(that: Rational ): Rational = new Rational ( numer * that.denom + that.numer * denom, denom * that.denom ) override def toString = n + “/” + d }
  • 19. Example – Rational Number Finally scala> val x = new Rational (1, 2) x: Rational = 1/2 scala> val y = new Rational (2, 3) y: Rational = 2/3 scala> x + y res8: Rational = 7/6
  • 21. Trait trait Dad { private var children: List [ Child ] = Nil def addChild(child: Child ) = children = child :: children def getChildren = children.clone }
  • 22. Base class Man ( val name: String ) extends Human
  • 23. Static mixin composition class Man ( val name: String ) extends Human with Dad val adi = new Man ( “Adi” ) adi.addChild( new Child ( “Yehonatan” )) adi.addChild( new Child ( “Lior” ))
  • 24. Dynamic mixin composition class Man ( val name: String ) extends Human val adi = new Man ( “Adi” ) with Dad adi.addChild( new Child ( “Yehonatan” )) adi.addChild( new Child ( “Lior” ))
  • 25. Composition class MrPotato (name: String ) extends MrPotatoHead with Eyes with Ears with Mouth with Nose with Hands with Hat with Shoes
  • 27. First Class Functions (x: Int ) => x + 1 Function literal Compilation Function class Runtime – function value
  • 28. Functions as values scala> val increase = (x: Int ) => x + 1 increase: (Int) => Int = <function> scala> increase(10) res0: Int = 11 => converts the “thing” on the left (any integer x) to the thing pm the right (x + 1)
  • 29. Functions as parameters scala> val someNumbers = List (-11, -10, -5, 0, 5, 10) someNumbers: List[Int] = List(-11, -10, -5, 0, 5, 10) scala> someNumbers.foreach((x: Int ) => println(x)) -11 -10 -5 0 5 10 scala> someNumbers.filter((x: Int ) => x > 0) res6: List[Int] = List(5, 10)
  • 30. Short form of function literals scala> someNumbers.filter((x) => x > 0) res7: List[Int] = List(5, 10) scala> someNumbers.filter(x => x > 0) res8: List[Int] = List(5, 10) Target typing Leave the parentheses out
  • 31. Placeholder syntax scala> someNumbers.filter(_ > 0) res9: List[Int] = List(5, 10) “ Fill in” the missing... scala> val f = _ + _ <console>:4: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2)) val f = _ + _ ˆ Type inference caution scala> val f = (_: Int ) + (_: Int ) f: (Int, Int) => Int = <function>
  • 32. Functions as closures (x: Int ) => x + more // how much more?
  • 33. Functions as closures scala> (x: Int ) => x + more <console>:5: error: not found: value more (x: Int) => x + more ˆ scala> var more = 1 more: Int = 1 scala> val addMore = (x: Int ) => x + more addMore: (Int) => Int = <function> scala> addMore(10) res19: Int = 11
  • 34. Functions as closures def makeIncreaser(more: Int ) = (x: Int ) => x + more scala> val inc1 = makeIncreaser(1) inc1: (Int) => Int = <function> scala> val inc9999 = makeIncreaser(9999) inc9999: (Int) => Int = <function> scala> inc1(10) res24: Int = 11 scala> inc9999(10) res25: Int = 10009
  • 36. List - Creating Prepends new elements Append time grows linearly List (1, 2, 3) 1 :: 2 :: 3 :: Nil
  • 37. List - Basics scala> val list = List (1, 2, 3) list: List[Int] = List(1, 2, 3) scala> list.head res0: Int = 1 scala> list.tail res1: List[Int] = List(2, 3) scala> list.isEmpty res2: Boolean = false
  • 38. List – High level operations scala> val list = List (1, 2, 3) list: List[Int] = List(1, 2, 3) scala> list.map(_ + 1) res0: List[Int] = List(2, 3, 4) scala> list.filter(_ < 2) res1: List[Int] = List(1) scala> list.exists(_ == 3) res2: Boolean = true scala> list.drop(2) res3: List[Int] = List(3) scala> list.reverse res4: List[Int] = List(3, 2, 1)
  • 39. Other Maps Sets Trees Stacks
  • 41. Unit Testing - JUnit import junit.framework.TestCase import junit.framework.Assert.assertEquals import junit.framework.Assert.fail import Element.elem class ElementTestCase extends TestCase { def testUniformElement() { val ele = elem( 'x' , 2, 3) assertEquals(2, ele.width) assertEquals(3, ele.height) try { elem('x', -2, 3) fail() } catch { case e: IllegalArgumentException => // expected } } }
  • 42. Unit Testing - TestNG import org.testng.annotations.Test import org.testng.Assert.assertEquals import Element.elem class ElementTests { @ Test def verifyUniformElement() { val ele = elem( 'x' , 2, 3) assertEquals(ele.width, 2) assertEquals(ele.height, 3) } @ Test { val expectedExceptions = Array (classOf[ IllegalArgumentException ]) } def elemShouldThrowIAE() { elem( 'x' , -2, 3) } }
  • 44. Jonas Bonér Scalable Solutions &