KEMBAR78
Scala for Java Programmers | PDF
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 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	
  
Expressions, not statements
val	
  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 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)	
  
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	
  
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>	
  
	
  
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	
  
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	
  
	
  
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 methods
case	
  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()	
  
Actors
import	
  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 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)	
  {}	
  
}	
  
	
  
More Information
•  My Scala Links gist
  –  https://gist.github.com/1249298

Scala for Java Programmers

  • 1.
    Intro to Scalafor Java Devs Sungard– 4/17/2012
  • 2.
    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
  • 3.
    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.
  • 4.
    What is Scala? • Hybrid Object-Functional language •  Statically typed •  Developed by Martin Odersky –  Java Generics –  Java Compiler (1.3+) •  First release in 2003
  • 5.
    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  
  • 6.
    Why Should IUse 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…
  • 7.
    Conciseness •  Code sizereduced by 2-3x compared to Java •  Less code == easier to read •  Less code == fewer bugs
  • 8.
    Conciseness •  Type Inference •  Expressions, not statements •  Higher-ordered functions •  Case classes •  Pattern matching
  • 9.
    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]  
  • 10.
    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"))    
  • 11.
    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  
  • 12.
    Expressions, not statements val  n  =  try  {          userInput.toInt   }  catch  {          case  _  =>  0   }     //  n  is  an  Int,  0  if  unable  to  parse  userInput  
  • 13.
    Collections API •  Verycomprehensive –  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
  • 14.
    Collection Literals •  val  l1  =  List(1,  2,  3)   •  val  m1  =  Map(“name”  -­‐>  “Eric”,  “city”  -­‐>  “NYC”)   •  val  s1  =  Set(Car(“Ford”),  Car(“Isuzu”),  Car(“VW”))  
  • 15.
    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);   }    
  • 16.
    Count characters indocuments 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)  
  • 17.
    Count characters indocuments 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  
  • 18.
    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>    
  • 19.
    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  
  • 20.
    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    
  • 21.
    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)  
  • 22.
    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   }      
  • 23.
    Case Classes •  Case classes can also have mutable fields and methods case  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
  • 24.
    Pattern Matching •  CaseClasses // 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 }
  • 25.
    Pattern Matching •  Matchon constants  def  describe(x:  Any)  =  x  match  {          case  5  =>  "five"          case  true  =>  "truth"          case  "hello"  =>  "hi!”        case  Nil  =>  "the  empty  list"          case  _  =>  "something  else”    }  
  • 26.
    Pattern Matching •  Typedpatterns def  generalSize(x:  Any)  =  x  match  {        case  s:  String  =>  s.length          case  m:  Map[_,  _]  =>  m.size          case  _  =>  -­‐1    }  
  • 27.
    No Checked Exceptions //  Look  ma,  no  throws  clause!   def  foo()  {          throw  new  java.lang.Excep7on   }  
  • 28.
    Concurrency-readiness •  The futurepresent is many cores •  Writing thread-safe code in Java is very difficult –  Mostly due to shared, mutable state
  • 29.
    Concurrency-readiness •  Scala –  Excellent support for immutability –  Actors / Futures –  Parallel collections
  • 30.
    Immutability •  Case classes • Immutable collections are default –  Copies of collections share data •  val vs. var, val is encouraged •  Method parameters are vals
  • 31.
    Actors •  Included instandard Scala library •  Simplified multithreading and coordination •  Based on message passing –  Each actor has a mailbox queue of messages •  Implementation based on Erlang
  • 32.
    Actors         object  Coun7ngActor  extends  Actor  {            def  act()  {                    for  (i  <-­‐  1  to  10)  {                            println("Number:  "+i)                          Thread.sleep(1000)                    }            }     }       Coun7ngActor.start()  
  • 33.
    Actors import  scala.actors.Actor._       val  echoActor  =  actor  {          while  (true)  {                  receive  {                          case  msg  =>  println("received:  ”  +  msg)                  }          }   }   echoActor  !  "hello"     echoActor  !  "world!"    
  • 34.
    Futures   Return aFuture 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  
  • 35.
    Actors / Futures/ STM •  Akka provides more robust Actors and Futures •  Also provides –  Distributed (Remote) Actors –  Software Transactional Memory –  Java API
  • 36.
    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
  • 37.
    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
  • 38.
    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  }   }  
  • 39.
    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”               }    
  • 40.
    JavaConversions •  Add Scalacollection 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)      
  • 41.
    Named and DefaultParams •  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)  
  • 42.
    By-name Parameters •  Methodparameters can be lazily evaluated class  Logger  {          def  debug(msg:  =>  String)  {            if  (isDebug)  doLog(DEBUG,  msg)          }   }     log.debug(“this  “  +  “  is  “  +  “expensive”)    
  • 43.
    Type Conveniences •  TypeAliases type  MyMap  =            mutable.HashMap[String,  mutable.HashMap[String,  Int]]     •  Import Aliases            import  com.nyx.domain.no7fica7on.{Topic=>DomainTopic}    
  • 44.
    Mixins •  Multiple implementationinheritance   trait  UserIden7fierCmd  extends  ApiKeyCmd  {            var  userId:  String  =  _          def  getUser  =  {…}   }     trait  RoleIdCmd  extends  ApiKeyCmd  {  var…    def…  }     object  cmd  extends  UserIden7fierCmd  with  RoleIdCmd  {..}  
  • 45.
    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)  {}   }    
  • 46.
    More Information •  MyScala Links gist –  https://gist.github.com/1249298