Scala for Java Developers
Ramnivas Laddad
@ramnivas
@ramnivas
•  Author of books and articles
–  AspectJ in Action (1st and 2nd edition)
•  Spring framework, Cloud Foundry
• ...
What is Scala
3
“a general purpose programming language designed to
express common programming patterns in a concise,
eleg...
Object-oriented
•  Everything is an object
–  No “primitives”
•  Classes
–  Same as Java, but concise
•  Traits
–  Interfa...
Statically typed
•  Rich type system (by Java’s standard)
–  Higher-kinded types
–  Implicit conversions
–  Type evidence
...
Functional Programming
•  Functions as values
–  May be
•  Saved
•  Passed to other functions (higher-order functions)
 N...
Java Interoperability
•  Compiles to Java byte code
–  Jars, wars, …
–  No special operational change
•  Scala calling Jav...
Hello World: Scripting Style
$ scala hello-script.scala	
Hello World
	
println("Hello World")	
No compilation
Hello World: Porting of Java Code
$ scalac hello-java.scala	
$ scala example.Main	
Hello World
// hello-java.scala	
packag...
Hello World: Using the App trait
$ scalac hello-app.scala	
$ scala example.Main	
Hello World
// hello-app.scala	
package e...
Simple Class
class Person	
val p = new Person	
Type
Inferred
Default
access: public
No curly
braces needed
(but allowed)
Simple Class
class Person	
val p: Person = new Person	
Explicit type
specification
Class with constructor
class Person(firstName: String, 	
lastName: String)	
val p = new Person("Ramnivas", "Laddad")	
prin...
Class with “getters”
class Person(val firstName: String, 	
val lastName: String)	
val p = new Person("Ramnivas", "Laddad")...
Class with “getters” and “setters”
class Person(var firstName: String, 	
var lastName: String)	
val p = new Person("Ramniv...
Extending a class
class Student(firstName: String, 	
lastName: String, 	
val grade: Int)	
extends Person(firstName, lastNa...
Defining methods
class Person(val firstName: String, 	
val lastName: String) {	
def name = firstName + " " + lastName	
	
o...
Uniform access principle
class Person(val firstName: String, 	
val lastName: String) {	
val name = firstName + " " + lastN...
Names in Scala
•  Class, method, field names can contain non alpha-
numeric characters
–  ::
–  :::
–  ~>
–  f@#:
•  Valua...
More about methods and fields
•  Declaring abstract methods and fields
–  Just don’t provide definition
def learn(subject:...
Finer access control levels
•  Default access level: public
•  Protected: protected
–  Same as Java
•  Private:
–  private...
Traits: Interfaces done right
22
trait PartyGoer {	
val age: Int	
val yearsUntilLegalDrinking = 	
if (age >= 21) 0 else 21...
Collections
val people = List("John", "Jacob", 	
"Mike")	
val firstPerson = people(0)	
println(firstPerson) // John
Collections
val people = Array("John", "Jacob", 	
"Mike")	
val firstPerson = people(0)	
println(firstPerson) // John
Working with collections: for comprehension
25
for (person <- people) {	
println(person)	
}
Working with collections: for comprehension
26
for (person <- people if person startsWith "J") {	
println("""Lucky one to ...
Working with collections: for comprehension
27
for (person <- people if person startsWith "J") {	
println(s"""Lucky one to...
Working with collections: filter
val student1 = new Student("first1", "last1", 1)	
val student2 = new Student("first2", "l...
Working with collections: filter
val student1 = new Student("first1", "last1", 1)	
val student2 = new Student("first2", "l...
Working with collections: using _
val student1 = new Student("first1", "last1", 1)	
val student2 = new Student("first2", "...
Working with collections: passing method as function
val student1 = new Student("first1", "last1", 1)	
val student2 = new ...
Working with collections: partition
val student1 = new Student("first1", "last1", 1)	
val student2 = new Student("first2",...
Working with collections: transforming
val student1 = new Student("first1", "last1", 1)	
val student2 = new Student("first...
Map
// student1, student2, student3, student4	
val studentSchools = Map(student1 -> "Miller", 	
student2 -> "Lawson",	
stu...
More collections
•  Set
•  IndexedSeq
•  Vector (good one!)
•  Range
–  1 to 100
–  1 until 100
–  2 until 100 by 2
•  …
•...
Putting it together: Quicksort
def quicksort[T](input: Traversable[T])	
(ordering: Ordering[T]) : Traversable[T] = 	
if (i...
Putting it together: Quicksort
def quicksort[T](input: Traversable[T])	
(implicit ordering: Ordering[T]) 	
: Traversable[T...
Pattern matching: Basics
val a:Any = "foo"	
	
a match {	
case str: String => println("A string: " + str)	
case i: Int => p...
Pattern matching: with collections
val l = List("a", "b", "c")	
	
l match {	
case Nil => println("Empty!")	
case head :: N...
Quicksort with pattern matching
def quicksort[T](input: Traversable[T])	
(implicit ordering: Ordering[T]) : Traversable[T]...
Destutter using Pattern matching
41
def destutter[A](lst: List[A]): List[A] = lst match {	
case h1 :: h2 :: tail if (h1 ==...
Case classes
•  Useful in pattern matching
–  “case”
•  Offer many useful common methods
–  equals()
–  hashCode()
–  toSt...
Case classes
43
case class Human(name: String)	
case class SuperHero(name: String, power: String)	
val characters = List(H...
Case classes and pattern matching
44
val actions = for (character <- characters) 	
yield character match {	
case Human(nam...
Pattern matching and extracting just enough
45
val actions = for (character <- characters) 	
yield character match {	
case...
Regular expressions
46
val text = "Ramnivas Laddad" 	
	
val Name = """(w+)s+(w+)""".r	
	
val person = text match {	
case N...
Options
47
val texts = 	
List("Ramnivas Laddad", "foo", "Martin Odersky")	
	
val peopleOptions = texts.map {	
_ match {	
c...
Options: flattening
48
val texts = 	
List("Ramnivas Laddad", "foo", "Martin Odersky")	
	
val peopleOptions = texts.map {	
...
Options: flatMap
49
val texts = 	
List("Ramnivas Laddad", "foo", "Martin Odersky")	
	
val people = texts.flatMap {	
_ matc...
Higher order functions
def process() : Unit = {	
retry(5) {	
...	
}	
}
def retry[T](maxRetry: Int)(thunk: => T) = {	
def l...
Caching using Scala
def getQuoteGraph(stock: Stock, 	
days: Int) : Array[Byte] = {	
cached("chart", stock.ticker + ":" + d...
Caching higher-order function
abstract class Caching(val cacheManager: CacheManager) {	
def cached[T](region: String, key:...
Transaction management
def findOrder(orderId: Long) : Order = {	
transactional(readOnly=true) {	
//...	
}	
}	
	
def update...
Transaction management function
def transactional[T](propgation: Propagation = Propagation.REQUIRED,	
isolation: Isolation...
Transaction management implementation
abstract class TransactionManagement(val txManager: PlatformTransactionManager) {	
	...
There is more… a lot more
•  Methods/functions
–  Default parameters
–  Named parameters
–  Curried parameters
–  Partial,...
Learning Scala
•  Read a Scala book
–  Get the whole picture
•  May feel complex at first
–  Java-style Scala may serve be...
Scala for Java Developers
Ramnivas Laddad
@ramnivas
Upcoming SlideShare
Loading in...5
×

Scala for Java Developers (Silicon Valley Code Camp 13)

2,005

Published on

My presentation at Silicon Valley Code Camp 13 (http://www.siliconvalley-codecamp.com/Session/2013/scala-for-java-developers). The target audience is Java developers who wants to get started with Scala.

Published in: Technology, News & Politics
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,005
On Slideshare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
29
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Scala for Java Developers (Silicon Valley Code Camp 13)

  1. 1. Scala for Java Developers Ramnivas Laddad @ramnivas
  2. 2. @ramnivas •  Author of books and articles –  AspectJ in Action (1st and 2nd edition) •  Spring framework, Cloud Foundry •  Main interests –  Cloud computing –  Aspect-oriented programming –  Scala and functional programming •  Speaker at many professional conferences –  JavaOne, JavaPolis, SpringOne, Software Development, No Fluff Just Stuff, EclipseCon, O’Reilly OSCON etc. •  Active involvement in AspectJ, Spring, and Cloud Foundry since their early form
  3. 3. What is Scala 3 “a general purpose programming language designed to express common programming patterns in a concise, elegant, and type-safe way. It smoothly integrates features of object-oriented and functional languages, enabling Java and other programmers to be more productive.” http://www.scala-lang.org
  4. 4. Object-oriented •  Everything is an object –  No “primitives” •  Classes –  Same as Java, but concise •  Traits –  Interfaces done right •  Singletons –  Language-level concept 4
  5. 5. Statically typed •  Rich type system (by Java’s standard) –  Higher-kinded types –  Implicit conversions –  Type evidence •  Expressive type system •  Inferred types 5
  6. 6. Functional Programming •  Functions as values –  May be •  Saved •  Passed to other functions (higher-order functions)  No need to write ugly anonymous classes –  Advanced pattern matching –  Expressions return a value •  if/else, try/catch, match, … •  Promotes immutability –  But doesn’t force it 6
  7. 7. Java Interoperability •  Compiles to Java byte code –  Jars, wars, … –  No special operational change •  Scala calling Java, Java calling Scala code is fine •  Whole Java eco-system at your service •  You can write apps using Scala and Spring, today 7
  8. 8. Hello World: Scripting Style $ scala hello-script.scala Hello World println("Hello World") No compilation
  9. 9. Hello World: Porting of Java Code $ scalac hello-java.scala $ scala example.Main Hello World // hello-java.scala package example object Main { def main(args: Array[String]) { println("Hello World") } } ‘static’ Inferred semicolons
  10. 10. Hello World: Using the App trait $ scalac hello-app.scala $ scala example.Main Hello World // hello-app.scala package example object Main extends App { println("Hello World") }
  11. 11. Simple Class class Person val p = new Person Type Inferred Default access: public No curly braces needed (but allowed)
  12. 12. Simple Class class Person val p: Person = new Person Explicit type specification
  13. 13. Class with constructor class Person(firstName: String, lastName: String) val p = new Person("Ramnivas", "Laddad") println(p.firstName) // Error Primary constructor Fields – accessible in class body
  14. 14. Class with “getters” class Person(val firstName: String, val lastName: String) val p = new Person("Ramnivas", "Laddad") println(p.firstName) Value (Java ‘final’)
  15. 15. Class with “getters” and “setters” class Person(var firstName: String, var lastName: String) val p = new Person("Ramnivas", "Laddad") println(p.firstName) p.firstName = "Ramnivas2” Variable (Java non-final)
  16. 16. Extending a class class Student(firstName: String, lastName: String, val grade: Int) extends Person(firstName, lastName) val s = new Student("Ramnivas", "Laddad", 1) println(s.firstName) println(s.grade)
  17. 17. Defining methods class Person(val firstName: String, val lastName: String) { def name = firstName + " " + lastName override def toString = name } val p = new Person("Ramnivas", "Laddad") println(p.name) // Ramnivas Laddad println(p) // Ramnivas Laddad Not optional
  18. 18. Uniform access principle class Person(val firstName: String, val lastName: String) { val name = firstName + " " + lastName override def toString = name } val p = new Person("Ramnivas", "Laddad") println(p.name) // Ramnivas Laddad println(p) // Ramnivas Laddad
  19. 19. Names in Scala •  Class, method, field names can contain non alpha- numeric characters –  :: –  ::: –  ~> –  f@#: •  Valuable if used judiciously –  DSLs 19
  20. 20. More about methods and fields •  Declaring abstract methods and fields –  Just don’t provide definition def learn(subject: String) val knowledge •  Classes with abstract method must be declared abstract –  Just as in Java •  Methods can be defined inside methods •  Methods may be marked @tailrec to check for tail- recursiveness 20
  21. 21. Finer access control levels •  Default access level: public •  Protected: protected –  Same as Java •  Private: –  private –  private[this] Access only from this instance –  private[package-name] Access from package and its subpackages 21
  22. 22. Traits: Interfaces done right 22 trait PartyGoer { val age: Int val yearsUntilLegalDrinking = if (age >= 21) 0 else 21-age } class Student(firstName: String, lastName: String, val age: Int, val grade: Int) extends Person(firstName, lastName) with PartyGoer val s = new Student("a", "b", 17, 12) s.yearsUntilLegalDrinking // 4
  23. 23. Collections val people = List("John", "Jacob", "Mike") val firstPerson = people(0) println(firstPerson) // John
  24. 24. Collections val people = Array("John", "Jacob", "Mike") val firstPerson = people(0) println(firstPerson) // John
  25. 25. Working with collections: for comprehension 25 for (person <- people) { println(person) }
  26. 26. Working with collections: for comprehension 26 for (person <- people if person startsWith "J") { println("""Lucky one to start name in "J" """ + person) } // You are lucky one to start name in "J" John // You are lucky one to start name in "J" Jacob
  27. 27. Working with collections: for comprehension 27 for (person <- people if person startsWith "J") { println(s"""Lucky one to start name in "J" $person""") } // You are lucky one to start name in "J" John // You are lucky one to start name in "J" Jacob
  28. 28. Working with collections: filter val student1 = new Student("first1", "last1", 1) val student2 = new Student("first2", "last2", 1) val student3 = new Student("first3", "last3", 2) val student4 = new Student("first4", "last4", 6) val students = List(student1, student2, student3, student4) val firstGraders = students.filter( s => s.grade == 1) println(firstGraders) // List(first1 last1, first2 last2)
  29. 29. Working with collections: filter val student1 = new Student("first1", "last1", 1) val student2 = new Student("first2", "last2", 1) val student3 = new Student("first3", "last3", 2) val student4 = new Student("first4", "last4", 6) val students = List(student1, student2, student3, student4) val inFirstGrade: Student => Boolean = s => s.grade == 1 val firstGraders = students.filter(inFirstGrade) // List(first1 last1, first2 last2)
  30. 30. Working with collections: using _ val student1 = new Student("first1", "last1", 1) val student2 = new Student("first2", "last2", 1) val student3 = new Student("first3", "last3", 2) val student4 = new Student("first4", "last4", 6) val students = List(student1, student2, student3, student4) val firstGraders = students.filter(_.grade == 1) println(firstGraders) // List(first1 last1, first2 last2)
  31. 31. Working with collections: passing method as function val student1 = new Student("first1", "last1", 1) val student2 = new Student("first2", "last2", 1) val student3 = new Student("first3", "last3", 2) val student4 = new Student("first4", "last4", 6) val students = List(student1, student2, student3, student4) def inFirstGrade(s: Student) : Boolean = s.grade == 1 val firstGraders = students.filter(inFirstGrade) // List(first1 last1, first2 last2)
  32. 32. Working with collections: partition val student1 = new Student("first1", "last1", 1) val student2 = new Student("first2", "last2", 1) val student3 = new Student("first3", "last3", 2) val student4 = new Student("first4", "last4", 6) val students = List(student1, student2, student3, student4) val (elementarySchoolers, middleSchoolers) = students.partition(_.grade < 6) println(elementarySchoolers) println(middleSchoolers) //List(first1 last1, first2 last2, first3 last3) //List(first4 last4) Tuple
  33. 33. Working with collections: transforming val student1 = new Student("first1", "last1", 1) val student2 = new Student("first2", "last2", 1) val student3 = new Student("first3", "last3", 2) val student4 = new Student("first4", "last4", 6) val students = List(student1, student2, student3, student4) val rollCall = students.map(_.firstName) println(rollCall) // List(first1, first2, first3, first4)
  34. 34. Map // student1, student2, student3, student4 val studentSchools = Map(student1 -> "Miller", student2 -> "Lawson", student3 -> "Lawson", student4 -> "Miller") println(studentSchools(student1)) // Miller
  35. 35. More collections •  Set •  IndexedSeq •  Vector (good one!) •  Range –  1 to 100 –  1 until 100 –  2 until 100 by 2 •  … •  Mutable versions •  Parallel versions 35
  36. 36. Putting it together: Quicksort def quicksort[T](input: Traversable[T]) (ordering: Ordering[T]) : Traversable[T] = if (input.isEmpty) { input } else { val (low, high) = input.tail.partition(ordering.lt(_, input.head)) quicksort(low)(ordering) ++ List(input.head) ++ quicksort(high)(ordering) } println(quicksort(List(1, 3, 4, 5, 1))(Ordering.Int))
  37. 37. Putting it together: Quicksort def quicksort[T](input: Traversable[T]) (implicit ordering: Ordering[T]) : Traversable[T] = if (input.isEmpty) { input } else { val (low, high) = input.tail.partition(ordering.lt(_, input.head)) quicksort(low) ++ List(input.head) ++ quicksort(high) } println(quicksort(List(1, 3, 4, 5, 1)))
  38. 38. Pattern matching: Basics val a:Any = "foo" a match { case str: String => println("A string: " + str) case i: Int => println("An int: " + i) case _ => println("Something else") }
  39. 39. Pattern matching: with collections val l = List("a", "b", "c") l match { case Nil => println("Empty!") case head :: Nil => println("Only one item " + head) case head :: tail => println("Item " + head + " followed by " + tail) }
  40. 40. Quicksort with pattern matching def quicksort[T](input: Traversable[T]) (implicit ordering: Ordering[T]) : Traversable[T] = input match { case head :: tail => val (low, high) = tail.partition(ordering.lt(_, head)) quicksort(low) ++ List(head) ++ quicksort(high) case _ => input } println(quicksort(List(1, 3, 4, 5, 1)))
  41. 41. Destutter using Pattern matching 41 def destutter[A](lst: List[A]): List[A] = lst match { case h1 :: h2 :: tail if (h1 == h2) => destutter(h2 :: tail) case h1 :: h2 :: tail => h1 :: destutter(h2 :: tail) case _ => lst } // destutter(List(1,1,1,1,1,1)) => List(1) // destutter(List(1,1,4,3,3,2)) => List(1,4,3,2) // destutter(List())=> List()
  42. 42. Case classes •  Useful in pattern matching –  “case” •  Offer many useful common methods –  equals() –  hashCode() –  toString –  copy() 42
  43. 43. Case classes 43 case class Human(name: String) case class SuperHero(name: String, power: String) val characters = List(Human("Programmer"), SuperHero("Customer", "money"), SuperHero("QA", "testing"))
  44. 44. Case classes and pattern matching 44 val actions = for (character <- characters) yield character match { case Human(name) => name + " needs to be saved" case SuperHero(name, power) => name + " will save using " + power } actions.foreach(println)
  45. 45. Pattern matching and extracting just enough 45 val actions = for (character <- characters) yield character match { case Human(name) => name + " needs to be saved" case SuperHero(_, power) => "Could be saved using " + power } actions.foreach(println) // Programmer needs to be saved // Could be saved using money // Could be saved using testing
  46. 46. Regular expressions 46 val text = "Ramnivas Laddad" val Name = """(w+)s+(w+)""".r val person = text match { case Name(first, last) => Some(new Person(first, last)) case _ => None } println(person) // Some(Ramnivas Laddad)
  47. 47. Options 47 val texts = List("Ramnivas Laddad", "foo", "Martin Odersky") val peopleOptions = texts.map { _ match { case Name(first, last) => Some(new Person(first, last)) case _ => None } } println(peopleOptions) // List(Some(Ramnivas Laddad), None, Some(Martin Odersky))
  48. 48. Options: flattening 48 val texts = List("Ramnivas Laddad", "foo", "Martin Odersky") val peopleOptions = texts.map { _ match { case Name(first, last) => Some(new Person(first, last)) case _ => None } } println(peopleOptions.flatten) // List(Ramnivas Laddad, Martin Odersky)
  49. 49. Options: flatMap 49 val texts = List("Ramnivas Laddad", "foo", "Martin Odersky") val people = texts.flatMap { _ match { case Name(first, last) => Some(new Person(first, last)) case _ => None } } println(people) // List(Ramnivas Laddad, Martin Odersky)
  50. 50. Higher order functions def process() : Unit = { retry(5) { ... } } def retry[T](maxRetry: Int)(thunk: => T) = { def loop(thunk: => T, attempt: Int): T = { try { thunk } catch { case ex if (attempt < maxRetry) => loop(thunk, attempt + 1) } } loop(thunk, 0) } Thunk
  51. 51. Caching using Scala def getQuoteGraph(stock: Stock, days: Int) : Array[Byte] = { cached("chart", stock.ticker + ":" + days) { ! ... Expensive calculation ! ! } }
  52. 52. Caching higher-order function abstract class Caching(val cacheManager: CacheManager) { def cached[T](region: String, key: Any) (thunk: => T): T = { val cache = ... if (cache.containsKey(key)) { cache.get(key).asInstanceOf[T] } else { val thunkVal: T = thunk cache.put(key, thunkVal) thunkVal } } }
  53. 53. Transaction management def findOrder(orderId: Long) : Order = { transactional(readOnly=true) { //... } } def updateOrder(order: Order) { transactional() { //... } } 53
  54. 54. Transaction management function def transactional[T](propgation: Propagation = Propagation.REQUIRED, isolation: Isolation = Isolation.DEFAULT, readOnly: Boolean = false, timeout: Int =TransactionDefinition.TIMEOUT_DEFAULT, rollbackFor: List[Throwable] = List(), noRollbackFor: List[Throwable] = List()) (thunk: => T) : T
  55. 55. Transaction management implementation abstract class TransactionManagement(val txManager: PlatformTransactionManager) { def transactional[T](...)(thunk: => T) : T = { val txAttribute = new TransactionAttributeWithRollbackRules(...) val status = txManager.getTransaction(txAttribute) try { val ret = thunk txManager.commit(status) ret } catch { case ex => { if (txAttribute.rollbackOn(ex)) { txManager.rollback(status) } else { txManager.commit(status) } throw ex } } } }
  56. 56. There is more… a lot more •  Methods/functions –  Default parameters –  Named parameters –  Curried parameters –  Partial, partially-applied functions •  Type system –  Higher-kinded types –  Bounded types –  Implicit type conversion –  Type parameter evidence –  Type aliasing •  Lazy values •  Partial imports •  Actors •  Extractors •  Scala ecosystem •  Combinator/parser •  Continuations •  Compiler plugin •  … 56
  57. 57. Learning Scala •  Read a Scala book –  Get the whole picture •  May feel complex at first –  Java-style Scala may serve best during initial exploration –  Over time you will appreciate its simplicity –  Will affect your non-Scala programming deeply 57 Be ready to be humbled Be ready to have fun!
  58. 58. Scala for Java Developers Ramnivas Laddad @ramnivas
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×