scala for java developers (silicon valley code camp 13)

58
Scala for Java Developers Ramnivas Laddad @ramnivas

Upload: ramnivas-laddad

Post on 10-May-2015

1.392 views

Category:

Technology


1 download

DESCRIPTION

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.

TRANSCRIPT

Page 1: Scala for Java Developers (Silicon Valley Code Camp 13)

Scala for Java Developers

Ramnivas Laddad @ramnivas

Page 2: Scala for Java Developers (Silicon Valley Code Camp 13)

@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

Page 3: Scala for Java Developers (Silicon Valley Code Camp 13)

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

Page 4: Scala for Java Developers (Silicon Valley Code Camp 13)

Object-oriented

•  Everything is an object –  No “primitives”

•  Classes –  Same as Java, but concise

•  Traits –  Interfaces done right

•  Singletons –  Language-level concept

4

Page 5: Scala for Java Developers (Silicon Valley Code Camp 13)

Statically typed

•  Rich type system (by Java’s standard) –  Higher-kinded types –  Implicit conversions –  Type evidence

•  Expressive type system •  Inferred types

5

Page 6: Scala for Java Developers (Silicon Valley Code Camp 13)

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

Page 7: Scala for Java Developers (Silicon Valley Code Camp 13)

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

Page 8: Scala for Java Developers (Silicon Valley Code Camp 13)

Hello World: Scripting Style

$ scala hello-script.scalaHello World

println("Hello World")

No compilation

Page 9: Scala for Java Developers (Silicon Valley Code Camp 13)

Hello World: Porting of Java Code

$ scalac hello-java.scala$ scala example.MainHello World

// hello-java.scalapackage exampleobject Main { def main(args: Array[String]) {

println("Hello World") }}

‘static’

Inferred semicolons

Page 10: Scala for Java Developers (Silicon Valley Code Camp 13)

Hello World: Using the App trait

$ scalac hello-app.scala$ scala example.MainHello World

// hello-app.scalapackage exampleobject Main extends App { println("Hello World") }

Page 11: Scala for Java Developers (Silicon Valley Code Camp 13)

Simple Class

class Person

val p = new Person

Type Inferred

Default access: public

No curly braces needed (but allowed)

Page 12: Scala for Java Developers (Silicon Valley Code Camp 13)

Simple Class

class Person

val p: Person = new PersonExplicit type specification

Page 13: Scala for Java Developers (Silicon Valley Code Camp 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

Page 14: Scala for Java Developers (Silicon Valley Code Camp 13)

Class with “getters”

class Person(val firstName: String, val lastName: String)

val p = new Person("Ramnivas", "Laddad") println(p.firstName)

Value (Java ‘final’)

Page 15: Scala for Java Developers (Silicon Valley Code Camp 13)

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)

Page 16: Scala for Java Developers (Silicon Valley Code Camp 13)

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)

Page 17: Scala for Java Developers (Silicon Valley Code Camp 13)

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 Laddadprintln(p) // Ramnivas Laddad

Not optional

Page 18: Scala for Java Developers (Silicon Valley Code Camp 13)

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 Laddadprintln(p) // Ramnivas Laddad

Page 19: Scala for Java Developers (Silicon Valley Code Camp 13)

Names in Scala

•  Class, method, field names can contain non alpha-numeric characters –  :: –  ::: –  ~> –  f@#:

•  Valuable if used judiciously –  DSLs

19

Page 20: Scala for Java Developers (Silicon Valley Code Camp 13)

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

Page 21: Scala for Java Developers (Silicon Valley Code Camp 13)

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

Page 22: Scala for Java Developers (Silicon Valley Code Camp 13)

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

Page 23: Scala for Java Developers (Silicon Valley Code Camp 13)

Collections

val people = List("John", "Jacob", "Mike")

val firstPerson = people(0)println(firstPerson) // John

Page 24: Scala for Java Developers (Silicon Valley Code Camp 13)

Collections

val people = Array("John", "Jacob", "Mike")

val firstPerson = people(0)println(firstPerson) // John

Page 25: Scala for Java Developers (Silicon Valley Code Camp 13)

Working with collections: for comprehension

25

for (person <- people) { println(person)}

Page 26: Scala for Java Developers (Silicon Valley Code Camp 13)

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

Page 27: Scala for Java Developers (Silicon Valley Code Camp 13)

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

Page 28: Scala for Java Developers (Silicon Valley Code Camp 13)

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)

Page 29: Scala for Java Developers (Silicon Valley Code Camp 13)

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)

Page 30: Scala for Java Developers (Silicon Valley Code Camp 13)

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)

Page 31: Scala for Java Developers (Silicon Valley Code Camp 13)

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)

Page 32: Scala for Java Developers (Silicon Valley Code Camp 13)

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

Page 33: Scala for Java Developers (Silicon Valley Code Camp 13)

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)

Page 34: Scala for Java Developers (Silicon Valley Code Camp 13)

Map

// student1, student2, student3, student4val studentSchools = Map(student1 -> "Miller", student2 -> "Lawson", student3 -> "Lawson", student4 -> "Miller")

println(studentSchools(student1)) // Miller

Page 35: Scala for Java Developers (Silicon Valley Code Camp 13)

More collections

•  Set •  IndexedSeq •  Vector (good one!) •  Range

–  1 to 100 –  1 until 100 –  2 until 100 by 2

•  …

•  Mutable versions •  Parallel versions

35

Page 36: Scala for Java Developers (Silicon Valley Code Camp 13)

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))

Page 37: Scala for Java Developers (Silicon Valley Code Camp 13)

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)))

Page 38: Scala for Java Developers (Silicon Valley Code Camp 13)

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")}

Page 39: Scala for Java Developers (Silicon Valley Code Camp 13)

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) }

Page 40: Scala for Java Developers (Silicon Valley Code Camp 13)

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)))

Page 41: Scala for Java Developers (Silicon Valley Code Camp 13)

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()

Page 42: Scala for Java Developers (Silicon Valley Code Camp 13)

Case classes

•  Useful in pattern matching –  “case”

•  Offer many useful common methods –  equals() –  hashCode() –  toString –  copy()

42

Page 43: Scala for Java Developers (Silicon Valley Code Camp 13)

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"))

Page 44: Scala for Java Developers (Silicon Valley Code Camp 13)

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)

Page 45: Scala for Java Developers (Silicon Valley Code Camp 13)

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

Page 46: Scala for Java Developers (Silicon Valley Code Camp 13)

Regular expressions

46

val text = "Ramnivas Laddad" val Name = """(\w+)\s+(\w+)""".rval person = text match { case Name(first, last) => Some(new Person(first, last)) case _ => None}println(person) // Some(Ramnivas Laddad)

Page 47: Scala for Java Developers (Silicon Valley Code Camp 13)

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))

Page 48: Scala for Java Developers (Silicon Valley Code Camp 13)

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)

Page 49: Scala for Java Developers (Silicon Valley Code Camp 13)

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)

Page 50: Scala for Java Developers (Silicon Valley Code Camp 13)

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

Page 51: Scala for Java Developers (Silicon Valley Code Camp 13)

Caching using Scala

def getQuoteGraph(stock: Stock, days: Int) : Array[Byte] = { cached("chart", stock.ticker + ":" + days) {! ... Expensive calculation !! }}

Page 52: Scala for Java Developers (Silicon Valley Code Camp 13)

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 } }}

Page 53: Scala for Java Developers (Silicon Valley Code Camp 13)

Transaction management

def findOrder(orderId: Long) : Order = { transactional(readOnly=true) { //... }} def updateOrder(order: Order) { transactional() { //... }}

53

Page 54: Scala for Java Developers (Silicon Valley Code Camp 13)

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

Page 55: Scala for Java Developers (Silicon Valley Code Camp 13)

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 } } }}

Page 56: Scala for Java Developers (Silicon Valley Code Camp 13)

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

Page 57: Scala for Java Developers (Silicon Valley Code Camp 13)

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!

Page 58: Scala for Java Developers (Silicon Valley Code Camp 13)

Scala for Java Developers

Ramnivas Laddad @ramnivas