scala for java programmers

46
Intro to Scala for Java Devs Sungard– 4/17/2012

Upload: eric-pederson

Post on 10-May-2015

814 views

Category:

Technology


2 download

DESCRIPTION

Introduction to Scala for Java developers

TRANSCRIPT

Page 1: Scala for Java Programmers

Intro to Scala for Java Devs

Sungard– 4/17/2012

Page 2: Scala for Java Programmers

Intro

•  Eric Pederson –  [email protected] – Twitter @ericacm –  Sourcedelica.com/blog – Background in Java, Groovy, Javascript, PHP, etc.

•  Using Scala for last two years •  Two Scala apps developed for NYSE in

Production

Page 3: Scala for Java Programmers

Platform at NYSE

•  Scala 2.9.1 •  JDK 1.6 •  Tomcat / JBoss •  Maven •  Using lots of Java libraries

– Spring, Hibernate, CXF, Mule, ApacheMQ – Bouncycastle, OpenSAML, Velocity, etc, etc.

Page 4: Scala for Java Programmers

What is Scala?

•  Hybrid Object-Functional language •  Statically typed •  Developed by Martin Odersky

– Java Generics – Java Compiler (1.3+)

•  First release in 2003

Page 5: Scala for Java Programmers

What is Scala?

•  Designed for general purpose programming

•  Performance on par with Java* •  Scalable

– Designed to write programs ranging from scripts up to huge systems

– You don’t have to use all of the features to be productive

*  There  are  some  gotchas  you  have  to  watch  out  for  

Page 6: Scala for Java Programmers

Why Should I Use Scala?

•  Allows you to write very concise code – Productivity on the level of Groovy / Ruby

•  Concurrency-ready •  Excellent interoperability with Java code •  Lots of other reasons…

Page 7: Scala for Java Programmers

Conciseness

•  Code size reduced by 2-3x compared to Java

•  Less code == easier to read •  Less code == fewer bugs

Page 8: Scala for Java Programmers

Conciseness

•  Type Inference •  Expressions, not statements •  Higher-ordered functions •  Case classes •  Pattern matching

Page 9: Scala for Java Programmers

Type Inference

•  Variables

•  Method return types

•  Generic type parameters

val  subscrip7onEvents  =  foo()    

def  listOfPeople  =  List(“Paul”,  “Eric”,  “John”,  “Mar7n”)    

case  class  MyPair[A,  B](x:  A,  y:  B)  val  p  =  MyPair(1,  “foo”)          //  p  is  MyPair[Int,  String]  

Page 10: Scala for Java Programmers

Type inference

•  Java

•  Scala

HashMap<String,  Customer>  customers  =                  new  HashMap<String,  Customer>();  customers.add("id1",    

   new  Customer("Eric",  "917-­‐444-­‐1234");  customers.add("id2",    

   new  Customer("Paul",  "718-­‐666-­‐9876");  

val  customers  =  HashMap(                      "id1"-­‐>Customer("Eric",  "917-­‐434-­‐1852"),                        "id2"-­‐>Customer("Paul",  "718-­‐666-­‐9876"))    

Page 11: Scala for Java Programmers

Expressions, not statements

val  server  =  if  (environment  ==  "development”)  {              val  factory  =  new  MBeanServerFactoryBean              factory.aberProper7esSet()              factory.getObject.asInstanceOf[MbeanServer]  }  else  {              val  clazz  =                            Class.forName("org.jboss.mx.u7l.MBeanServerLocator")              clazz.getMethod("locateJBoss”).invoke(null)  }    //  server is assigned one of the bold values  

Page 12: Scala for Java Programmers

Expressions, not statements

val  n  =  try  {          userInput.toInt  }  catch  {          case  _  =>  0  }    //  n  is  an  Int,  0  if  unable  to  parse  userInput  

Page 13: Scala for Java Programmers

Collections API

•  Very comprehensive – For example, over 200 methods on List  

•  Higher ordered functions –  foreach,  map,  flatMap,  exists,  forall,  find,  findAll,  filter,  groupBy,  par77on, etc.

•  Concise literals •  Immutable and mutable variations

Page 14: Scala for Java Programmers

Collection Literals

•  val  l1  =  List(1,  2,  3)  

•  val  m1  =  Map(“name”  -­‐>  “Eric”,  “city”  -­‐>  “NYC”)  

•  val  s1  =  Set(Car(“Ford”),  Car(“Isuzu”),  Car(“VW”))  

Page 15: Scala for Java Programmers

Collections API

•  Scala

•  Java

val  groups  =      subscrip7onEvents.groupBy(e  =>  e.subscrip7on.id)  

 

Map<String,  List<SubscripLonEvent>>  groups  =            new  HashMap<String,  ArrayList<Subscrip7onEvent>();  for  (Subscrip7onEvent  se  :  subscrip7onEvents)  {          ArrayList<Subscrip7onEvent>  seList  =  groups.get(se.subscrip7on.id)          if  (seList  ==  null)  {                  seList  =  new  ArrayList<Subscrip7onEvent>();                  groups.put(se.subscrip7on.id,  seList)          }          seList.add(se);  }          

Page 16: Scala for Java Programmers

Count characters in documents

Try #1 – Java-esque Scala

       var  total  =  0          for  (doc  <-­‐  docs)  {              total  +=  doc.length          }  

Try #2 – Use higher order functions        var  total  =  0          docs.foreach(doc  =>  total  +=  doc.length)  

Page 17: Scala for Java Programmers

Count characters in documents Try #3 – Use fold        docs.foldLeb(0)((accum,  current)  =>  accum  +  current.length)  

Try #4 – Use type-classes (eg. Numeric)        docs.map(_.length).sum  

Try #5 – Use the 'view' method to turn multiple passes into one

       docs.view.map(_.length).sum  

Page 18: Scala for Java Programmers

Variables scala>  var  i  =  0  i:  Int  =  0    scala>  i  =  2  i:  Int  =  2    scala>  val  j  =  0  j:  Int  =  0    scala>  j  =  3  <console>:8:  error:  reassignment  to  val    scala>  lazy  val  l  =  expensiveComputa7on()  l:  Double  =  <lazy>    

Page 19: Scala for Java Programmers

Uniform Access Principle scala>  object  Ints  {            |                  var  i  =  1            |                  val  j  =  2            |                  def  k  =  i  +  j            |  }    scala>  Ints.i  res8:  Int  =  1    scala>  Ints.j  res9:  Int  =  2    scala>  Ints.k  res10:  Int  =  3    

Page 20: Scala for Java Programmers

Uniform Access Principle scala>  object  M  {            |                    private  var  pm  =  0            |                    def  m  =  pm            |                    def  m_=(in:  Int)  {  pm  =  in  }            |  }  scala>  import  M._    scala>  m  res5:  Int  =  0    scala>  m  =  5  m:  Int  =  5    

Page 21: Scala for Java Programmers

Case Classes

•  Scala

scala>  case  class  Car(make:  String,  model:  String,  mpg:  Int)  defined  class  Car    scala>  val  c  =  Car("Honda",  "Civic",  40)  c:  Car  =  Car(Honda,Civic,40)  

     

Page 22: Scala for Java Programmers

Case Classes

•  Java public  class  Car  implements  scala.Product,  scala.Serializable    {          final  private  String  make,  model;          final  private  int  mpg;          Car(String  make,  String  model,  int  mpg)  {                  this.make  =  make;    this.model  =  model;  this.mpg  =  mpg;          }          public  String  getMake()  {  return  make;  }          public  String  getModel()  {  return  model;  }          public  int  getMpg()  {  return  mpg;  }          public  String  toString()  {  return  “Car(  “  +  make  +  ….  }          public  boolean  equals(Object  that)  {  if  (that  instanceOf  Car)  &&  ……  }          public  int  hashCode()  {  return  19  +  ……  }          public  Car  copy(String  make,  String  model,  int  mpg)  {  …..  }          //  plus  9  other  Scala-­‐specific  methods  }      

Page 23: Scala for Java Programmers

Case Classes

•  Case classes can also have mutable fields and methods

•  In Scala you can define multiple classes per source file

case  class  Car(make:  String,  model:  String,  mpg:  Int,  var  odometer)  {          def  driveMiles(miles:  Int)  {  odometer  +=  miles  }  }      

Page 24: Scala for Java Programmers

Pattern Matching

•  Case Classes

// Class hierarchy: trait Expr case class Num(value : int) extends Expr case class Var(name : String) extends Expr case class Mul(left : Expr, right : Expr) extends Expr // Simplification rule: e match { case Mul(x, Num(1)) ⇒ x case _ ⇒ e }

Page 25: Scala for Java Programmers

Pattern Matching

•  Match on constants

 def  describe(x:  Any)  =  x  match  {          case  5  =>  "five"          case  true  =>  "truth"          case  "hello"  =>  "hi!”        case  Nil  =>  "the  empty  list"          case  _  =>  "something  else”    }  

Page 26: Scala for Java Programmers

Pattern Matching

•  Typed patterns

def  generalSize(x:  Any)  =  x  match  {        case  s:  String  =>  s.length          case  m:  Map[_,  _]  =>  m.size          case  _  =>  -­‐1    }  

Page 27: Scala for Java Programmers

No Checked Exceptions

//  Look  ma,  no  throws  clause!  def  foo()  {          throw  new  java.lang.Excep7on  }  

Page 28: Scala for Java Programmers

Concurrency-readiness

•  The future present is many cores •  Writing thread-safe code in Java is very

difficult – Mostly due to shared, mutable state

Page 29: Scala for Java Programmers

Concurrency-readiness

•  Scala – Excellent support for immutability – Actors / Futures – Parallel collections

Page 30: Scala for Java Programmers

Immutability

•  Case classes •  Immutable collections are default

– Copies of collections share data

•  val vs. var, val is encouraged •  Method parameters are vals

Page 31: Scala for Java Programmers

Actors

•  Included in standard Scala library •  Simplified multithreading and

coordination •  Based on message passing

– Each actor has a mailbox queue of messages

•  Implementation based on Erlang

Page 32: Scala for Java Programmers

Actors        

object  Coun7ngActor  extends  Actor  {            def  act()  {                    for  (i  <-­‐  1  to  10)  {                            println("Number:  "+i)                          Thread.sleep(1000)                    }            }    }      Coun7ngActor.start()  

Page 33: Scala for Java Programmers

Actors

import  scala.actors.Actor._      val  echoActor  =  actor  {          while  (true)  {                  receive  {                          case  msg  =>  println("received:  ”  +  msg)                  }          }  }  echoActor  !  "hello"    echoActor  !  "world!"    

Page 34: Scala for Java Programmers

Futures  Return a Future immediately, run func in new thread  scala>  future  {  Thread.sleep(10000);  println("hi");  10  }  res2:  scala.actors.Future[Int]  =  <  func7on0>        Use the Future apply()  method to get the result  scala>  res2()          //  blocks  wai7ng  for  sleep()  to  finish  hi  res3:  Int  =  10  

Page 35: Scala for Java Programmers

Actors / Futures / STM

•  Akka provides more robust Actors and Futures

•  Also provides – Distributed (Remote) Actors – Software Transactional Memory – Java API

Page 36: Scala for Java Programmers

Parallel Collections

•  Add .par to collection to get parallel version

•  Uses JDK7 fork-join framework •  Example:

– Filter is run in parallel, results are collected, then map is run in parallel

myData.par.filter(_.expensiveTest()).map(_.expensiveComputa7on())  

Page 37: Scala for Java Programmers

Interoperability with Java

•  Scala classes are Java classes •  You can pass Scala objects to Java

methods and vice-versa •  For the most part, seamless interop

– Cannot use Scala-only features from Java

Page 38: Scala for Java Programmers

Java Interop Example @En7ty  class  Subscrip7onEvent  {          @Id  @GeneratedValue          var  id:  Long  =  _            @ManyToOne(op7onal=false)          var  subscrip7on:  Subscrip7on  =  _            var  address:  String  =  _            @Index(name="Subscrip7onEventStatus")          private  var  status:  String  =  _          def  deliveryStatus  =  DeliveryStatus.withName(status)          def  deliveryStatus_=(s:  DeliveryStatus)  {  status  =  s.toString  }  }  

Page 39: Scala for Java Programmers

Java Interop Example @Controller  @RequestMapping(Array("/report"))  class  ReportController  {        class  MessageDto(message:  Message)  {          @BeanProperty  val  id  =  message.id          @BeanProperty  val  address  =  message.address          //  …      }                  @RequestMapping(Array("/messages"))      def  messages(@RequestParam(value="fromDate”)  from:  String,                                                              map:  ExtendedModelMap):  String  =  {                    //…                map.put(“messages”,  asJavaCollec7on(messageDtos))                  “report/messages”              }    

Page 40: Scala for Java Programmers

JavaConversions

•  Add Scala collection API methods to Java collections

 import  collec7on.JavaConversions._            import  collec7on.Iterable            import  java.u7l.{List=>JList}      def  goodStudents(students:  JList[Student]):  Iterable[String]  =              students.filter(_.score  >  5).map(_.name)  

   

Page 41: Scala for Java Programmers

Named and Default Params

•  Named parameters

•  Default parameters

def  resize(width:  Int,  height:  Int)  =  {  ...  }  resize(width  =  120,  height  =  42)  

def  f(elems:  List[Int],  x:  Int  =  0,  cond:  Boolean  =  true)  f(List(1))  f(Nil,  cond  =  false)  

Page 42: Scala for Java Programmers

By-name Parameters

•  Method parameters can be lazily evaluated

class  Logger  {          def  debug(msg:  =>  String)  {  

         if  (isDebug)  doLog(DEBUG,  msg)          }  }    log.debug(“this  “  +  “  is  “  +  “expensive”)  

 

Page 43: Scala for Java Programmers

Type Conveniences

•  Type Aliases type  MyMap  =            mutable.HashMap[String,  mutable.HashMap[String,  Int]]  

 •  Import Aliases            import  com.nyx.domain.no7fica7on.{Topic=>DomainTopic}    

Page 44: Scala for Java Programmers

Mixins

•  Multiple implementation inheritance  trait  UserIden7fierCmd  extends  ApiKeyCmd  {            var  userId:  String  =  _          def  getUser  =  {…}  }    trait  RoleIdCmd  extends  ApiKeyCmd  {  var…    def…  }    object  cmd  extends  UserIden7fierCmd  with  RoleIdCmd  {..}  

Page 45: Scala for Java Programmers

Duck Typing

type  Closeable  =  {  def  close():  Unit  }    def  using[T  <:  Closeable,  S]  (obj:  T)(func:  T  =>  S):  S  =  {            val  result  =  func  (obj)            obj.close()            result  }    val  fis  =  new  FileInputStream(“data.txt”)    using(fis)  {  f  =>          while  (f.read()  !=  -­‐1)  {}  }    

Page 46: Scala for Java Programmers

More Information

•  My Scala Links gist – https://gist.github.com/1249298