Scala Springone 111031111747 Phpapp01

Embed Size (px)

Citation preview

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    1/56

    Scala for Java Developers

    Ramnivas Laddad

    @ramnivas

    2011 SpringOne 2GX. All rights reserved. Do not distribute without permission.

    http://localhost/var/www/apps/conversion/tmp/scratch_5/twitter.comhttp://localhost/var/www/apps/conversion/tmp/scratch_5/twitter.com
  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    2/56

    What is Scala

    2

    a general purposeprogramming language designed toexpress common programming patterns in a concise,elegant, and type-safeway. It smoothly integrates featuresof object-orientedand functionallanguages, enabling Javaand other programmers to be more productive.

    http://www.scala-lang.org

    http://www.scala-lang.org/http://www.scala-lang.org/http://www.scala-lang.org/http://www.scala-lang.org/
  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    3/56

    Object-oriented

    Everything is an object No primitives

    Classes

    Same as Java, but concise

    Traits Interfaces done right

    Singletons

    Language-level concept

    3

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    4/56

    Statically typed

    Rich type system (by Javas standard) Higher-kinded types

    Implicit conversions

    Type evidence

    Expressive type system Inferred types

    4

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    5/56

    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 doesnt force it

    5

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    6/56

    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

    6

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    7/56

    Hello World: Scripting Style

    $ scala hello-script.scalaHello World

    println("Hello World")

    No compilation

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    8/56

    Hello World: Porting of Java Code

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

    // hello-java.scalapackageexample

    objectMain {

    defmain(args: Array[String]) {println("Hello World")}

    }

    static

    Inferredsemicolons

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    9/56

    Hello World: Using the App trait

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

    // hello-app.scalapackageexample

    objectMain extendsApp {println("Hello World")}

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    10/56

    Simple Class

    classPerson

    valp = newPersonType

    Inferred

    Defaultaccess: public

    No curlybraces needed

    (but allowed)

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    11/56

    Simple Class

    classPerson

    valp: Person = newPersonExplicit typespecification

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    12/56

    Class with constructor

    classPerson(firstName: String,

    lastName: String)

    valp = newPerson("Ramnivas", "Laddad")

    println(p.firstName) // Error

    Primaryconstructor

    Fieldsaccessible in

    class body

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    13/56

    Class with getters

    classPerson(valfirstName: String,

    vallastName: String)

    valp = newPerson("Ramnivas", "Laddad")println(p.firstName)

    Value(Java final)

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    14/56

    Class with gettersand setters

    classPerson(varfirstName: String,

    varlastName: String)

    valp = newPerson("Ramnivas", "Laddad")println(p.firstName)p.firstName = "Ramnivas2

    Variable (Javanon-final)

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    15/56

    Extending a class

    classStudent(firstName: String,

    lastName: String,

    valgrade: Int)

    extendsPerson(firstName, lastName)

    vals = newStudent("Ramnivas", "Laddad", 1)println(s.firstName)println(s.grade)

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    16/56

    Defining methods

    classPerson(valfirstName: String,vallastName: String) {

    defname = firstName + " "+ lastName

    overridedeftoString = name}

    valp = newPerson("Ramnivas", "Laddad")

    println(p.name) // Ramnivas Laddadprintln(p) // Ramnivas Laddad

    Not optional

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    17/56

    Uniform access principle

    classPerson(valfirstName: String,vallastName: String) {

    valname = firstName + " "+ lastName

    overridedeftoString = name}

    valp = newPerson("Ramnivas", "Laddad")

    println(p.name) // Ramnivas Laddadprintln(p) // Ramnivas Laddad

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    18/56

    Names in Scala

    Class, method, field names can contain non alpha-numeric characters

    ::

    :::

    ~>

    f@#:

    Valuable if used judiciously

    DSLs

    18

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    19/56

    More about methods and fields

    Declaring abstract methods and fields

    Just dont provide definition

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

    19

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    20/56

    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 itssubpackages

    20

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    21/56

    Traits: Interfaces done right

    21

    traitPartyGoer {

    valage: IntvalyearsUntilLegalDrinking =

    if(age >= 18) 0 else18-age

    }

    classStudent(firstName: String, lastName: String,

    valage: Int, valgrade: Int)

    extendsPerson(firstName, lastName)

    withPartyGoer

    vals = newStudent("a", "b", 17, 12)

    s.yearsUntilLegalDrinking // 1

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    22/56

    Collections

    valpeople = List("John", "Jacob",

    "Mike")

    valfirstPerson = people(0)

    println(firstPerson) // John

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    23/56

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    24/56

    Working with collections: for comprehension

    24

    for(person

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    25/56

    Working with collections: for comprehension

    25

    for(person

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    26/56

    Working with collections: filter

    valstudent1 = newStudent("first1", "last1", 1)

    valstudent2 = newStudent("first2", "last2", 1)

    valstudent3 = newStudent("first3", "last3", 2)

    valstudent4 = newStudent("first4", "last4", 6)

    valstudents = List(student1, student2,student3, student4)

    valfirstGraders = students.filter(_.grade == 1)println(firstGraders)// List(first1 last1, first2 last2)

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    27/56

    Working with collections: filter

    valstudent1 = newStudent("first1", "last1", 1)

    valstudent2 = newStudent("first2", "last2", 1)

    valstudent3 = newStudent("first3", "last3", 2)

    valstudent4 = newStudent("first4", "last4", 6)

    valstudents = List(student1, student2,student3, student4)

    valinFirstGrade: Student => Boolean

    = s => s.grade == 1

    valfirstGraders = students.filter(inFirstGrade)

    // List(first1 last1, first2 last2)

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    28/56

    Working with collections: using _

    valstudent1 = newStudent("first1", "last1", 1)

    valstudent2 = newStudent("first2", "last2", 1)

    valstudent3 = newStudent("first3", "last3", 2)

    valstudent4 = newStudent("first4", "last4", 6)

    valstudents = List(student1, student2,student3, student4)

    valfirstGraders

    = students.filter(_.grade == 1)println(firstGraders)// List(first1 last1, first2 last2)

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    29/56

    Working with collections: passing method as function

    valstudent1 = newStudent("first1", "last1", 1)

    valstudent2 = newStudent("first2", "last2", 1)

    valstudent3 = newStudent("first3", "last3", 2)

    valstudent4 = newStudent("first4", "last4", 6)

    valstudents = List(student1, student2,student3, student4)

    definFirstGrade(s: Student) : Boolean

    = s.grade == 1valfirstGraders = students.filter(inFirstGrade)

    // List(first1 last1, first2 last2)

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    30/56

    Working with collections: partition

    valstudent1 = newStudent("first1", "last1", 1)

    valstudent2 = newStudent("first2", "last2", 1)

    valstudent3 = newStudent("first3", "last3", 2)

    valstudent4 = newStudent("first4", "last4", 6)

    valstudents = 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

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    31/56

    Working with collections: transforming

    valstudent1 = newStudent("first1", "last1", 1)

    valstudent2 = newStudent("first2", "last2", 1)

    valstudent3 = newStudent("first3", "last3", 2)

    valstudent4 = newStudent("first4", "last4", 6)

    valstudents = List(student1, student2,student3, student4)

    valrollCall = students.map(_.firstName)

    println(rollCall)// List(first1, first2, first3, first4)

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    32/56

    Map

    // student1, student2, student3, student4

    valstudentSchools = Map(student1 -> "Miller",student2 -> "Lawson",student3 -> "Lawson",

    student4 -> "Miller")

    println(studentSchools(student1)) // Miller

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    33/56

    More collections

    Set

    IndexedSeq

    Vector (good one!)

    Range

    1 to 100 1 until 100

    2 until 100 by 2

    Mutable versions

    Parallel versions

    33

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    34/56

    Putting it together: Quicksort

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

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    35/56

    Putting it together: Quicksort

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

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    36/56

    Pattern matching: Basics

    vala:Any = "foo"

    a match{

    casestr: String => println("A string: "+ str)casei: Int => println("An int: "+ i)

    case_ => println("Something else")

    }

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    37/56

    Pattern matching: with collections

    vall = List("a", "b", "c")

    l match{

    caseNil => println("Empty!")casehead :: Nil =>

    println("Only one item "+ head)

    casehead :: tail =>

    println("Item "+ head +" followed by "+ tail)

    }

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    38/56

    Quicksort with pattern matching

    defquicksort[T](input: Traversable[T])(implicitordering: Ordering[T]) : Traversable[T] =

    input match{

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

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    39/56

    Destutter using Pattern matching

    39

    defdestutter[A](lst: List[A]): List[A] = lst match{caseh1 :: h2 :: tail if(h1 == h2)

    => destutter(h2 :: tail)

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

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    40/56

    Case classes

    Useful in pattern matching

    case

    Offer many useful common methods

    equals()

    hashCode()

    toString

    copy()

    40

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    41/56

    Case classes

    41

    caseclassHuman(name: String)caseclassSuperHero(name: String, power: String)

    valcharacters = List(Human("Programmer"),

    SuperHero("Customer", "money"),

    SuperHero("QA", "testing"))

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    42/56

    Case classes and pattern matching

    42

    valactions = for(character

    name + " needs to be saved"

    caseSuperHero(name, power) =>name + " will save using "+ power

    }

    actions.foreach(println)

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    43/56

    Pattern matching and extracting just enough

    43

    valactions = for(character

    name + " needs to be saved"

    caseSuperHero(_, power) =>

    "Could be saved using "+ power

    }

    actions.foreach(println)

    // Programmer needs to be saved// Could be saved using money// Could be saved using testing

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    44/56

    Regular expressions

    44

    valtext = "Ramnivas Laddad"

    valName = """(\w+)\s+(\w+)""".r

    valperson = text match{

    caseName(first, last) =>

    Some(newPerson(first, last))

    case_ =>

    None

    }

    println(person) // Some(Ramnivas Laddad)

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    45/56

    Options

    45

    valtexts =

    List("Ramnivas Laddad", "foo", "Scott Andrews")

    valpeopleOptions = texts.map {

    _ match{caseName(first, last) =>

    Some(newPerson(first, last))case_ => None

    }}

    println(peopleOptions)// List(Some(Ramnivas Laddad),

    None,Some(Scott Andrews))

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    46/56

    Options: flattening

    46

    valtexts =

    List("Ramnivas Laddad", "foo", "Scott Andrews")

    valpeopleOptions = texts.map {

    _ match{

    caseName(first, last) =>Some(newPerson(first, last))

    case_ => None

    }}

    println(peopleOptions.flatten)// List(Ramnivas Laddad, Scott Andrews)

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    47/56

    Options: flatMap

    47

    valtexts =

    List("Ramnivas Laddad", "foo", "Scott Andrews")

    valpeople = texts.flatMap {

    _ match{

    caseName(first, last) =>Some(newPerson(first, last))

    case_ => None

    }}

    println(people)// List(Ramnivas Laddad, Scott Andrews)

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    48/56

    Higher order functions

    defprocess() : Unit = {retry(5){

    ...}

    }

    defretry[T](maxRetry: Int)(thunk: => T) = {

    defretry(thunk: => T, attempt: Int): T = {try{thunk

    } catch{caseex if(attempt < maxRetry) =>retry(thunk, attempt + 1)

    }}retry(thunk, 0)

    }

    Thunk

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    49/56

    Caching using Scala

    defgetQuoteGraph(stock: Stock,

    days: Int) : Array[Byte] = {

    cached("chart", stock.ticker + ":" + days) {

    ... Expensive calculation

    }

    }

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    50/56

    Caching higher-order function

    abstractclassCaching(valcacheManager: CacheManager) {

    defcached[T](region: String, key: Any)(thunk: => T): T = {

    valcache = ...

    if(cache.containsKey(key)) {

    cache.get(key).asInstanceOf[T]

    } else{

    valthunkVal: T = thunk

    cache.put(key, thunkVal)

    thunkVal

    }

    }

    }

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    51/56

    Transaction management

    deffindOrder(orderId: Long) : Order = {

    transactional(readOnly=true) {

    //...

    }

    }

    defupdateOrder(order: Order) {

    transactional() {

    //...}

    }

    51

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    52/56

    Transaction management function

    deftransactional[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

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    53/56

    Transaction management implementation

    abstractclassTransactionManagement(valtxManager: PlatformTransactionManager) {

    deftransactional[T](...)(thunk: => T) : T= {

    valtxAttribute = newTransactionAttributeWithRollbackRules(...)

    valstatus = txManager.getTransaction(txAttribute)

    try{

    valret = thunk

    txManager.commit(status)ret

    } catch{

    caseex => {

    if(txAttribute.rollbackOn(ex)) {

    txManager.rollback(status)

    } else{

    txManager.commit(status)}

    throwex

    }

    }

    }

    }

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    54/56

    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

    54

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    55/56

    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

    55

    Be ready to be humbled

  • 8/13/2019 Scala Springone 111031111747 Phpapp01

    56/56

    Scala for Java Developers

    Ramnivas Laddad

    @ramnivas

    http://localhost/var/www/apps/conversion/tmp/scratch_5/twitter.comhttp://localhost/var/www/apps/conversion/tmp/scratch_5/twitter.com