Scala for Java Programmers
Upcoming SlideShare
Loading in...5
×
 

Scala for Java Programmers

on

  • 901 views

Introduction to Scala for Java developers

Introduction to Scala for Java developers

Statistics

Views

Total Views
901
Views on SlideShare
901
Embed Views
0

Actions

Likes
0
Downloads
14
Comments
0

0 Embeds 0

No embeds

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Scala for Java Programmers Scala for Java Programmers Presentation Transcript

  • Intro to Scala for Java Devs Sungard– 4/17/2012
  • Intro•  Eric Pederson –  eric@cpextechnology.com –  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
  • 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.
  • What is Scala?•  Hybrid Object-Functional language•  Statically typed•  Developed by Martin Odersky –  Java Generics –  Java Compiler (1.3+)•  First release in 2003
  • 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  
  • 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…
  • Conciseness•  Code size reduced by 2-3x compared to Java•  Less code == easier to read•  Less code == fewer bugs
  • Conciseness•  Type Inference•  Expressions, not statements•  Higher-ordered functions•  Case classes•  Pattern matching
  • Type Inference•  Variables val  subscrip7onEvents  =  foo()    •  Method return types def  listOfPeople  =  List(“Paul”,  “Eric”,  “John”,  “Mar7n”)    •  Generic type parameters case  class  MyPair[A,  B](x:  A,  y:  B)   val  p  =  MyPair(1,  “foo”)          //  p  is  MyPair[Int,  String]  
  • Type inference•  Java 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");  •  Scala val  customers  =  HashMap(                      "id1"-­‐>Customer("Eric",  "917-­‐434-­‐1852"),                        "id2"-­‐>Customer("Paul",  "718-­‐666-­‐9876"))    
  • Expressions, not statementsval  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  
  • Expressions, not statementsval  n  =  try  {          userInput.toInt  }  catch  {          case  _  =>  0  }    //  n  is  an  Int,  0  if  unable  to  parse  userInput  
  • 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
  • Collection Literals•  val  l1  =  List(1,  2,  3)  •  val  m1  =  Map(“name”  -­‐>  “Eric”,  “city”  -­‐>  “NYC”)  •  val  s1  =  Set(Car(“Ford”),  Car(“Isuzu”),  Car(“VW”))  
  • Collections API•  Scala val  groups  =      subscrip7onEvents.groupBy(e  =>  e.subscrip7on.id)    •  Java 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);   }    
  • Count characters in documentsTry #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)  
  • Count characters in documentsTry #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  
  • Variablesscala>  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>    
  • Uniform Access Principlescala>  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  
  • Uniform Access Principlescala>  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    
  • 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)  
  • 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   }      
  • Case Classes •  Case classes can also have mutable fields and methodscase  class  Car(make:  String,  model:  String,  mpg:  Int,  var  odometer)  {          def  driveMiles(miles:  Int)  {  odometer  +=  miles  }  }       •  In Scala you can define multiple classes per source file
  • 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 }
  • 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”    }  
  • Pattern Matching•  Typed patterns def  generalSize(x:  Any)  =  x  match  {        case  s:  String  =>  s.length          case  m:  Map[_,  _]  =>  m.size          case  _  =>  -­‐1    }  
  • No Checked Exceptions//  Look  ma,  no  throws  clause!  def  foo()  {          throw  new  java.lang.Excep7on  }  
  • Concurrency-readiness•  The future present is many cores•  Writing thread-safe code in Java is very difficult –  Mostly due to shared, mutable state
  • Concurrency-readiness•  Scala –  Excellent support for immutability –  Actors / Futures –  Parallel collections
  • Immutability•  Case classes•  Immutable collections are default –  Copies of collections share data•  val vs. var, val is encouraged•  Method parameters are vals
  • 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
  • Actors        object  Coun7ngActor  extends  Actor  {            def  act()  {                    for  (i  <-­‐  1  to  10)  {                            println("Number:  "+i)                          Thread.sleep(1000)                    }            }    }      Coun7ngActor.start()  
  • Actorsimport  scala.actors.Actor._      val  echoActor  =  actor  {          while  (true)  {                  receive  {                          case  msg  =>  println("received:  ”  +  msg)                  }          }  }  echoActor  !  "hello"    echoActor  !  "world!"    
  • 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  
  • Actors / Futures / STM•  Akka provides more robust Actors and Futures•  Also provides –  Distributed (Remote) Actors –  Software Transactional Memory –  Java API
  • Parallel Collections •  Add .par to collection to get parallel version •  Uses JDK7 fork-join framework •  Example:myData.par.filter(_.expensiveTest()).map(_.expensiveComputa7on())   –  Filter is run in parallel, results are collected, then map is run in parallel
  • 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
  • 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  }  }  
  • 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”              }    
  • 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)      
  • Named and Default Params•  Named parameters def  resize(width:  Int,  height:  Int)  =  {  ...  }   resize(width  =  120,  height  =  42)  •  Default parameters def  f(elems:  List[Int],  x:  Int  =  0,  cond:  Boolean  =  true)   f(List(1))   f(Nil,  cond  =  false)  
  • 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”)    
  • Type Conveniences•  Type Aliases type  MyMap  =            mutable.HashMap[String,  mutable.HashMap[String,  Int]]    •  Import Aliases            import  com.nyx.domain.no7fica7on.{Topic=>DomainTopic}    
  • 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  {..}  
  • Duck Typingtype  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)  {}  }    
  • More Information•  My Scala Links gist –  https://gist.github.com/1249298