Scala for Java Developers

  • 1,681 views
Uploaded on

My presentation at SpringOne. The target audience is Java developers who haven't started with Scala yet.

My presentation at SpringOne. The target audience is Java developers who haven't started with Scala yet.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,681
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
48
Comments
0
Likes
6

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • No access spec (default: public), no parentheses, type inference
  • How constructor params can be used in body

Transcript

  • 1. Scala for Java Developers © 2011 SpringOne 2GX. All rights reserved. Do not distribute without permission.
  • 2. What is Scala “ 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
  • 3. Object-oriented
    • Everything is an object
      • No “primitives”
    • Classes
      • Same as Java, but concise
    • Traits
      • Interfaces done right
    • Singletons
      • Language-level concept
  • 4. Statically typed
    • Rich type system (by Java’s standard)
      • Higher-kinded types
      • Implicit conversions
      • Type evidence
    • Expressive type system
    • Inferred types
  • 5. 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 Scala doesn’t force it
  • 6. 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. Hello World: Scripting Style $ scala hello-script.scala Hello World No compilation
  • 8. Hello World: Porting of Java Code $ scalac hello-java.scala $ scala example.Main Hello World ‘ static’ Inferred semicolons
  • 9. Hello World: Using the App trait $ scalac hello-app.scala $ scala example.Main Hello World
  • 10. Simple Class class Person val p = new Person Type Inferred Default access: public No curly braces needed (but allowed)
  • 11. Simple Class class Person val p: Person = new Person Explicit type specification
  • 12. 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
  • 13. Class with “getters” class Person( val firstName: String, val lastName: String) val p = new Person( "Ramnivas" , "Laddad" ) println(p.firstName) Value (Java ‘final’)
  • 14. 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)
  • 15. Extending a class val s = new Student( "Ramnivas" , "Laddad" , 1) println(s.firstName) println(s.grade)
  • 16. 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
  • 17. 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
  • 18. Names in Scala
    • Class, method, field names can contain non alpha-numeric characters
      • ::
      • :::
      • ~>
      • f@#:
    • Valuable if used judiciously
      • DSLs
  • 19. 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. 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. Traits: Interfaces done right trait PartyGoer { val age: Int val yearsUntilLegalDrinking = if (age >= 18) 0 else 18-age }
  • 22. Collections val people = List( "John" , "Jacob" , "Mike" )
  • 23. Collections val people = Array( "John" , "Jacob" , "Mike" )
  • 24. Working with collections: for comprehension for (person <- people) { println(person) }
  • 25. Working with collections: for comprehension for (person <- people if person startsWith &quot;J&quot; ) { println( &quot;&quot;&quot;Lucky one to start name in &quot;J&quot; &quot;&quot;&quot; + person) } // You are lucky one to start name in &quot;J&quot; John // You are lucky one to start name in &quot;J&quot; Jacob
  • 26. Working with collections: filter val student1 = new Student( &quot;first1&quot; , &quot;last1&quot; , 1) val student2 = new Student( &quot;first2&quot; , &quot;last2&quot; , 1) val student3 = new Student( &quot;first3&quot; , &quot;last3&quot; , 2) val student4 = new Student( &quot;first4&quot; , &quot;last4&quot; , 6) val students = List(student1, student2, student3, student4)
  • 27. Working with collections: filter val student1 = new Student( &quot;first1&quot; , &quot;last1&quot; , 1) val student2 = new Student( &quot;first2&quot; , &quot;last2&quot; , 1) val student3 = new Student( &quot;first3&quot; , &quot;last3&quot; , 2) val student4 = new Student( &quot;first4&quot; , &quot;last4&quot; , 6) val students = List(student1, student2, student3, student4)
  • 28. Working with collections: using _ val student1 = new Student( &quot;first1&quot; , &quot;last1&quot; , 1) val student2 = new Student( &quot;first2&quot; , &quot;last2&quot; , 1) val student3 = new Student( &quot;first3&quot; , &quot;last3&quot; , 2) val student4 = new Student( &quot;first4&quot; , &quot;last4&quot; , 6) val students = List(student1, student2, student3, student4)
  • 29. Working with collections: passing method as function val student1 = new Student( &quot;first1&quot; , &quot;last1&quot; , 1) val student2 = new Student( &quot;first2&quot; , &quot;last2&quot; , 1) val student3 = new Student( &quot;first3&quot; , &quot;last3&quot; , 2) val student4 = new Student( &quot;first4&quot; , &quot;last4&quot; , 6) val students = List(student1, student2, student3, student4)
  • 30. Working with collections: partition val student1 = new Student( &quot;first1&quot; , &quot;last1&quot; , 1) val student2 = new Student( &quot;first2&quot; , &quot;last2&quot; , 1) val student3 = new Student( &quot;first3&quot; , &quot;last3&quot; , 2) val student4 = new Student( &quot;first4&quot; , &quot;last4&quot; , 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
  • 31. Working with collections: transforming val student1 = new Student( &quot;first1&quot; , &quot;last1&quot; , 1) val student2 = new Student( &quot;first2&quot; , &quot;last2&quot; , 1) val student3 = new Student( &quot;first3&quot; , &quot;last3&quot; , 2) val student4 = new Student( &quot;first4&quot; , &quot;last4&quot; , 6) val students = List(student1, student2, student3, student4)
  • 32. Map println(studentSchools(student1)) // Miller
  • 33. More collections
    • Set
    • IndexedSeq
    • Vector (good one!)
    • Range
      • 1 to 100
      • 1 until 100
      • 2 until 100 by 2
    • Mutable versions
    • Parallel versions
  • 34. 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))
  • 35. Putting it together: Quicksort println(quicksort(List(1, 3, 4, 5, 1)))
  • 36. Pattern matching: Basics val a:Any = &quot;foo&quot; a match { case str: String => println( &quot;A string: &quot; + str) case i: Int => println( &quot;An int: &quot; + i) case _ => println( &quot;Something else&quot; ) }
  • 37. Pattern matching: with collections val l = List( &quot;a&quot; , &quot;b&quot; , &quot;c&quot; ) l match { case Nil => println( &quot;Empty!&quot; ) case head :: Nil => println( &quot;Only one item &quot; + head) case head :: tail => println( &quot;Item &quot; + head + &quot; followed by &quot; + tail) }
  • 38. 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)))
  • 39. Destutter using Pattern matching 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()
  • 40. Case classes
    • Useful in pattern matching
      • “ case”
    • Offer many useful common methods
      • equals()
      • hashCode()
      • toString
      • copy()
  • 41. Case classes case class Human(name: String) case class SuperHero(name: String, power: String) val characters = List(Human( &quot;Programmer&quot; ), SuperHero( &quot;Customer&quot; , &quot;money&quot; ), SuperHero( &quot;QA&quot; , &quot;testing&quot; ))
  • 42. Case classes and pattern matching val actions = for (character <- characters) yield character match { case Human(name) => name + &quot; needs to be saved&quot; case SuperHero(name, power) => name + &quot; will save using &quot; + power } actions.foreach(println)
  • 43. Pattern matching and extracting just enough val actions = for (character <- characters) yield character match { case Human(name) => name + &quot; needs to be saved&quot; case SuperHero(_, power) => &quot;Could be saved using &quot; + power } actions.foreach(println) // Programmer needs to be saved // Could be saved using money // Could be saved using testing
  • 44. Regular expressions val text = &quot;Ramnivas Laddad&quot; val Name = &quot;&quot;&quot;(w+)s+(w+)&quot;&quot;&quot; .r val person = text match { case Name(first, last) => Some( new Person(first, last)) case _ => None } println(person) // Some(Ramnivas Laddad)
  • 45. Options val texts = List( &quot;Ramnivas Laddad&quot; , &quot;foo&quot; , &quot;Scott Andrews&quot; ) val peopleOptions = texts.map { _ match { case Name(first, last) => Some( new Person(first, last)) case _ => None } } println(peopleOptions) // List(Some(Ramnivas Laddad), None, Some(Scott Andrews))
  • 46. Options: flattening val texts = List( &quot;Ramnivas Laddad&quot; , &quot;foo&quot; , &quot;Scott Andrews&quot; ) val peopleOptions = texts.map { _ match { case Name(first, last) => Some( new Person(first, last)) case _ => None } } println(peopleOptions.flatten) // List(Ramnivas Laddad, Scott Andrews)
  • 47. Options: flatMap val texts = List( &quot;Ramnivas Laddad&quot; , &quot;foo&quot; , &quot;Scott Andrews&quot; ) val people = texts.flatMap { _ match { case Name(first, last) => Some( new Person(first, last)) case _ => None } } println(people) // List(Ramnivas Laddad, Scott Andrews)
  • 48. Higher order functions def process() : Unit = { retry(5) { ... } } def retry[T](maxRetry: Int)(thunk: => T) = { def retry(thunk: => T, attempt: Int): T = { try { thunk } catch { case ex if (attempt < maxRetry) => retry(thunk, attempt + 1) } } retry(thunk, 0) } Thunk
  • 49. Caching using Scala
    • def getQuoteGraph(stock: Stock,
    • days: Int) : Array[Byte] = {
    • cached( &quot;chart&quot; , stock.ticker + &quot;:&quot; + days) {
    • ... Expensive calculation
    • }
    • }
  • 50. 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
    • }
    • }
    • }
  • 51. Transaction management
    • def findOrder(orderId: Long) : Order = {
    • transactional(readOnly= true ) {
    • //...
    • }
    • }
    • def updateOrder(order: Order) {
    • transactional() {
    • //...
    • }
    • }
  • 52. 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
  • 53. 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
    • }
    • }
    • }
    • }
  • 54. There is more… a lot more
    • Methods/functions
      • Default parameters
      • Named parameters
      • Curried parameters
      • Partial 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
  • 55. 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
    • Learn Haskell first!
      • Might help to break from the Java way of thinking
    Be ready to be humbled
  • 56. Scala for Java Developers © 2011 SpringOne 2GX. All rights reserved. Do not distribute without permission.