SlideShare uma empresa Scribd logo
1 de 108
Baixar para ler offline
Pragmatic
Real-World Scala

             Jonas Bonér
       Scalable Solutions
“If I were to pick a language
to use today other than Java,
it would be Scala”
                 James Gosling
Chat app in Lift
   Build a multi-user, comet-based chat app
   About 30 lines of code
   Three slides worth
   Slides By David Pollak, creator of Lift
Define Messages
case class Add(who: Actor)
case class Remove(who: Actor)
case class Messages(msgs: List[String])
Chat Server
object ChatServer extends Actor {
  private var listeners: List[Actor] = Nil
  private var msgs: List[String] = Nil
  def act = loop {
    react {
      case s: String =>
        msgs = s :: msgs
        listeners.foreach(l => l ! Messages(msgs))
      case Add(who) =>
        listeners = who :: listeners
        who ! Messages(msgs)
      case Remove(who) => listeners -= who
    }
  }
  this.start
}
Chat Comet Component
class Chat extends CometActor {
  private var msgs: List[String] = Nil
  def render =
    <div>
      <ul>{ msgs.reverse.map(m => <li>{ m }</li>) }</ul>
      { ajaxText("", s => { ChatServer ! s; Noop }) }
    </div>
  override def localSetup = ChatServer ! Add(this)
  override def localShutdown = ChatServer ! Remove(this)
  override def lowPriority = {
    case Messages(m) => msgs = m; reRender(false)
  }
}
Demo
Scalable language
Unique and elegant blend of



OO FP           +
Pragmatic     Since   2003
                 Sponsored by EPFL
Martin Odersky
      Seamless Java interoperability
Friendly and supportive      Production
community                    ready

Runs on the   JVM         Statically typed
Unique and elegant blend of



       is...
Expressive &
       light-weight
val phonebook = Map(
  “Jonas” -> “123456”,
  “Sara” -> “654321”)
phonebook += (“Jacob” -> “987654”)
println(phonebook(“Jonas”))
High-level
            Java version
boolean hasUpperCase = false;
for (int i = 0; i < name.length(); i++) {
  if (Character.isUpperCase(name.charAt(i)))
  {
    hasUpperCase = true;
    break;
  }
}
High-level
             Scala version

val hasUpperCase = name.exists(_.isUpperCase)
Concise
// Java
public class Person {
 private String name;
 private int age;
 public Person(String name,
                int age) {
   this.name = name;
   this.age = age;                    // Scala
 }
 public String getName() {            class Person(
   return name;                         var name: String,
 }
 public int getAge() {                  var age: Int)
   return age;
 }
 public void setName(String name) {
   this.name = name;
 }
 public void setAge(age: int) {
   this.age = age;
 }
}
Pure OO
1 + 2
1.+(2)

123.toString()
Extensible
val service = actor {
  loop {
    receive {
      case Add(x,y) => reply(x+y)
      case Sub(x,y) => reply(x-y)
    }
  }
}
service ! Add(4, 2)    6
Pragmatic
def users =
  <users>
    <user role=”customer”>
      <name>{ user.name }</name>
      <password>{ user.password }</password>
      <email>{ user.email }</email>
    </user>
    ...
  </users>
Pragmatic
users match {
  case <users>{users @ _*}</users> =>
    for (user <- users)
      println(“User “ + (user  “name”).text)
}
Great for DSLs
     Apache Camel
“direct:a“ ==> {
  loadbalance roundrobin {
    to (“mock:a“)
    to (“mock:b“)
    to (“mock:c“)
  }
}
deep
 Scala is
But you don’t need to go very deep
to still have fun and be productive
Java
Tastier Java
Different beast
Composition
Composition

in   large
2
building blocks
Traits
   &   &

  Self-type
annotations
Trait
trait Dad {
  private var children: List[Child] = Nil

    def addChild(child: Child) =
      children = child :: children

    def getChildren = children.clone
}
Base

class Man(val name: String) extends Human
Plumbing
Static mixin composition

class Man(val name: String) extends Human with Dad
Static mixin composition
          usage
class Man(val name: String) extends Human with Dad


val jonas = new Man(“Jonas”)
jonas.addChild(new Child(“Jacob”))
Dynamic mixin composition


val jonas = new Man(“Jonas”) with Dad
Dynamic mixin composition
         usage
val jonas = new Man(“Jonas”) with Dad


jonas.addChild(new Child(“Jacob”))
3   different type of traits
1
Rich interface
trait RichIterable[A] {
  def iterator: Iterator[A] // contract method

    def foreach(f: A => Unit) = {
      val iter = iterator
      while (iter.hasNext) f(iter.next)
    }

    def foldLeft[B](seed: B)(f: (B, A) => B) = {
       var result = seed
       foreach(e => result = f(result, e))
       result
     }
}
Rich interface
val richSet =
    new java.util.HashSet[Int]
    with RichIterable[Int]

richSet.add(1)
richSet.add(2)

richSet.foldLeft(0)((x, y) => x + y)
    3
2
Stackable modifications
trait IgnoreCaseSet
  extends java.util.Set[String] {

    abstract override def add(e: String) = {
      super.add(e.toLowerCase)
    }
    abstract override def contains(e: String) = {
      super.contains(e.toLowerCase)
    }
    abstract override def remove(e: String) = {
      super.remove(e.toLowerCase)
    }
}
Stackable modifications
val set =
    new java.util.HashSet[String]
    with IgnoreCaseSet

set.add(“HI THERE“)      // uppercase

set.contains(“hi there“) // lowercase
     true
Add another trait interceptor
trait LoggableSet
  extends java.util.Set[String] {

    abstract override def add(e: String) = {
      println(“Add :“ + e)
      super.add(e)
    }

    abstract override def remove(e: String) = {
      println(“Remove :“ + e)
      super.remove(e)
    }
}
Run the stack of interceptors
  val set =
    new java.util.HashSet[String]
    with IgnoreCaseSet
    with LoggableSet

  set.add(“HI THERE“)
     “Add: HI THERE”


      Prints in uppercase
Change the order
val set =
  new java.util.HashSet[String]
  with LoggableSet
  with IgnoreCaseSet

set.add(“HI THERE“)
   “Add: hi there”


     Prints in lowercase
3
Multiple views
    Trait                   Trait




Trait        Base             Trait




                    Trait
Multiple views
    Trait                   Trait




Trait        Base             Trait




                    Trait
Traits
 Multiple
personalities
Traits


          Multiple
         facets
Base
class Order(val cust: Customer)
Facets
trait   Entity { ... }
trait   InventoryItemSet { ... }
trait   Invoicable { ... }
trait   PurchaseLimiter { ... }
trait   MailNotifier { ... }
trait   ACL { ... }
trait   Versioned { ... }
trait   Transactional { ... }
Composition
val order = new Order(customer)
    with Entity
    with InventoryItemSet
    with Invoicable
    with PurchaseLimiter
    with MailNotifier
    with ACL
    with Versioned
    with Transactional
What do you
  need?
DI
this: <deps> =>
this: <deps> =>
Dependency declaration
trait UserService {
  this: UserRepository =>
  ...
  // provided with composition
  userRepository.merge(user)
}

…using self-type annotation
Duck typing
walks like a duck…
   if it

   and talks like a duck…

   then it’s a duck

Duck typing
Structural Typing:
      Duck-typing done right
def authorize(target: { def getACL: ACL }) = {

    val acl = target.getACL
    ... //authorize
}



          Statically enforced
Composition

   in small
“It's Time to Get Good at
 Functional Programming”
                   Dr Dobb’s Journal
                Issue December 2008
What’s
all the

buzz
about?
Deterministic
High-level     Reusable

        FP      Referentially
                transparent

Immutable    Declarative
    Orthogonal
Lego
FP is like
Small reusable pieces

with   input
and    output
Unix pipes

cat File | grep 'println' | wc
Functions

(x: Int) => x + 1
Functions as values
  val inc = (x: Int) => x + 1


  inc(1)   2
Functions as parameters
         high-order
List(1, 2, 3).map((x: Int) => x + 1)

    List(2, 3, 4)
Functions as parameters
          with sugar
List(1, 2, 3).map((x: Int) => x + 1)


List(1, 2, 3).map(x => x + 1)


List(1, 2, 3).map(_ + 1)
Functions as closures

val addMore = (x: Int) => x + more
What is   more?
Some value outside
the function’s lexical scope
 var more = 7
 val addMore = (x: Int) => x + more


 addMore(3)  10
 more = 8
 addMore(3)  11
Functional
Data Structures
Immutable
The almighty




List
Lists
Grow at the front
Insert at front  O(1)
Insert at end  O(n)
List creation
  List(1, 2, 3)


1 :: 2 :: 3 :: Nil
Basics
val list = List(1, 2, 3)
list.head     1
list.tail     List(2, 3)
list.isEmpty  false
High-level operations
val list = List(1, 2, 3)
list.map(_ + 1)      List(2,   3, 4)
list.filter(_ < 2)  List(3)
list.exists(_ == 3)  true
list.drop(2)         List(3)
list.reverse         List(3,   2, 1)
list.sort(_ > _)     List(3,   2, 1)
List.flatten(list)  List(1,    2, 3)
list.slice(2, 3)     List(3)
...
115
functions defined on   List
Tuples
def getNameAndAge: Tuple2[String, Int] = {
  val name = ...
  val age = ...
  (name, age)
}


val (name, age) = getNameAndAge
println(“Name: “ + name)
println(“Age: “ + age)
Other
functional data structures:
                   Maps
                    Sets
                  Trees
                  Stacks
For comprehensions

  for (n <- names)
    println(n)
Like SQL queries
for {
  att <- attendees
  if att.name == “Fred”
  lang <- att.spokenLanguages
  if lang == “Danish”
} println(att)

Find all attendees named Fred that speaks Danish
for / yield
val companiesForAttendeesFromLondon =
  for {
    att <- attendees
    if att.address.city == “London”
  } yield att.company
Everything returns a value


    for (thing <- thingsFromHere)
    yield getRealThing(thing)
Everything returns a value


   val things =
     for (thing <- thingsFromHere)
     yield getRealThing(thing)
Everything returns a value


   if (fromHere) {
     for (thing <- thingsFromHere)
     yield getRealThing(thing)
   } else {
     for (thing <- thingsFromThere)
     yield thing
   }
Everything returns a value

 val things =
   if (fromHere) {
     for (thing <- thingsFromHere)
     yield getRealThing(thing)
   } else {
     for (thing <- thingsFromThere)
     yield thing
   }
Everything returns a value

  try {
    if (fromHere) {
      for (thing <- thingsFromHere)
      yield getRealThing(thing)
    } else {
      for (thing <- thingsFromThere)
      yield thing
    }
  } catch {
    case e => error(e); Nil
  }
Everything returns a value
val things =
  try {
    if (fromHere) {
      for (thing <- thingsFromHere)
      yield getRealThing(thing)
    } else {
      for (thing <- thingsFromThere)
      yield thing
    }
  } catch {
    case e => error(e); Nil
  }
Everything returns a value
def getThingsFromSomewhere(
  fromHere: Boolean): List[Thing] = {
  try {
    if (fromHere) {
      for (thing <- thingsFromHere)
      yield getRealThing(thing)
    } else {
      for (thing <- thingsFromThere)
      yield thing
    }
  } catch {
    case e => error(e); Nil
  }
}
Pattern
matching
Pattern matching
def matchAny(a: Any): Any = a match {
  case 1                => “one”
  case “two”            => 2
  case i: Int           => “scala.Int”
  case <tag>{ t }</tag> => t
  case head :: tail     => head
  case _                => “default”
}
Tools
Tools: scala/bin
            scala
           scalac
               fsc
        scaladoc
             sbaz
Tools: IDEs
        Eclipse
    NetBeans
 IntelliJ IDEA
         Emacs
           JEdit
Building
             Maven
               Ant
SBT (Simple Build Tool )
Tools: Testing
          Specs
    ScalaCheck
      ScalaTest
          SUnit
Frameworks: Web
            Lift
           Sweet
           Slinky
            Pinky
Learn more
jonas@jonasboner.com
  http://jonasboner.com
     http://scala-lang.org
Professional help
Consulting Training Mentoring

    http://scalablesolutions.se
Pragmatic
Real-World Scala

              Jonas Bonér
       Scalable Solutions


        Copyright 2009 Scalable Solutions

Mais conteúdo relacionado

Mais procurados

Functional Objects & Function and Closures
Functional Objects  & Function and ClosuresFunctional Objects  & Function and Closures
Functional Objects & Function and Closures
Sandip Kumar
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
Hiroshi Ono
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
pramode_ce
 

Mais procurados (17)

Getting Started With Scala
Getting Started With ScalaGetting Started With Scala
Getting Started With Scala
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
 
Functional Objects & Function and Closures
Functional Objects  & Function and ClosuresFunctional Objects  & Function and Closures
Functional Objects & Function and Closures
 
scala
scalascala
scala
 
A Tour Of Scala
A Tour Of ScalaA Tour Of Scala
A Tour Of Scala
 
A Brief Intro to Scala
A Brief Intro to ScalaA Brief Intro to Scala
A Brief Intro to Scala
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
Introducing scala
Introducing scalaIntroducing scala
Introducing scala
 
Scala coated JVM
Scala coated JVMScala coated JVM
Scala coated JVM
 
Scala eXchange opening
Scala eXchange openingScala eXchange opening
Scala eXchange opening
 
Scala categorytheory
Scala categorytheoryScala categorytheory
Scala categorytheory
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
 
Scala fundamentals
Scala fundamentalsScala fundamentals
Scala fundamentals
 
Scala for curious
Scala for curiousScala for curious
Scala for curious
 
Scala collections api expressivity and brevity upgrade from java
Scala collections api  expressivity and brevity upgrade from javaScala collections api  expressivity and brevity upgrade from java
Scala collections api expressivity and brevity upgrade from java
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 World
 

Destaque

scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
Hiroshi Ono
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
Hiroshi Ono
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
Hiroshi Ono
 
program_draft3.pdf
program_draft3.pdfprogram_draft3.pdf
program_draft3.pdf
Hiroshi Ono
 
Canonical and robotos (2)
Canonical and robotos (2)Canonical and robotos (2)
Canonical and robotos (2)
panchaloha
 
SACSIS2009_TCP.pdf
SACSIS2009_TCP.pdfSACSIS2009_TCP.pdf
SACSIS2009_TCP.pdf
Hiroshi Ono
 
kademlia-1227143905867010-8.pdf
kademlia-1227143905867010-8.pdfkademlia-1227143905867010-8.pdf
kademlia-1227143905867010-8.pdf
Hiroshi Ono
 

Destaque (8)

scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
program_draft3.pdf
program_draft3.pdfprogram_draft3.pdf
program_draft3.pdf
 
Canonical and robotos (2)
Canonical and robotos (2)Canonical and robotos (2)
Canonical and robotos (2)
 
SACSIS2009_TCP.pdf
SACSIS2009_TCP.pdfSACSIS2009_TCP.pdf
SACSIS2009_TCP.pdf
 
kademlia-1227143905867010-8.pdf
kademlia-1227143905867010-8.pdfkademlia-1227143905867010-8.pdf
kademlia-1227143905867010-8.pdf
 

Semelhante a pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf

Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scala
parag978978
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
Tomasz Wrobel
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
Loïc Descotte
 

Semelhante a pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf (20)

Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scala
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
 
Scala
ScalaScala
Scala
 
From Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risksFrom Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risks
 
A bit about Scala
A bit about ScalaA bit about Scala
A bit about Scala
 
Scala Quick Introduction
Scala Quick IntroductionScala Quick Introduction
Scala Quick Introduction
 
Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
Softshake 2013: 10 reasons why java developers are jealous of Scala developersSoftshake 2013: 10 reasons why java developers are jealous of Scala developers
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Language
 
Meet scala
Meet scalaMeet scala
Meet scala
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
Functional programming in Scala
Functional programming in ScalaFunctional programming in Scala
Functional programming in Scala
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 

Mais de Hiroshi Ono

Voltdb - wikipedia
Voltdb - wikipediaVoltdb - wikipedia
Voltdb - wikipedia
Hiroshi Ono
 
Gamecenter概説
Gamecenter概説Gamecenter概説
Gamecenter概説
Hiroshi Ono
 
EventDrivenArchitecture
EventDrivenArchitectureEventDrivenArchitecture
EventDrivenArchitecture
Hiroshi Ono
 
program_draft3.pdf
program_draft3.pdfprogram_draft3.pdf
program_draft3.pdf
Hiroshi Ono
 
nodalities_issue7.pdf
nodalities_issue7.pdfnodalities_issue7.pdf
nodalities_issue7.pdf
Hiroshi Ono
 
genpaxospublic-090703114743-phpapp01.pdf
genpaxospublic-090703114743-phpapp01.pdfgenpaxospublic-090703114743-phpapp01.pdf
genpaxospublic-090703114743-phpapp01.pdf
Hiroshi Ono
 
kademlia-1227143905867010-8.pdf
kademlia-1227143905867010-8.pdfkademlia-1227143905867010-8.pdf
kademlia-1227143905867010-8.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
downey08semaphores.pdf
downey08semaphores.pdfdowney08semaphores.pdf
downey08semaphores.pdf
Hiroshi Ono
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 
TwitterOct2008.pdf
TwitterOct2008.pdfTwitterOct2008.pdf
TwitterOct2008.pdf
Hiroshi Ono
 
stateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdf
stateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdfstateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdf
stateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdf
Hiroshi Ono
 
stateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdf
stateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdfstateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdf
stateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdf
Hiroshi Ono
 
nodalities_issue7.pdf
nodalities_issue7.pdfnodalities_issue7.pdf
nodalities_issue7.pdf
Hiroshi Ono
 
genpaxospublic-090703114743-phpapp01.pdf
genpaxospublic-090703114743-phpapp01.pdfgenpaxospublic-090703114743-phpapp01.pdf
genpaxospublic-090703114743-phpapp01.pdf
Hiroshi Ono
 
kademlia-1227143905867010-8.pdf
kademlia-1227143905867010-8.pdfkademlia-1227143905867010-8.pdf
kademlia-1227143905867010-8.pdf
Hiroshi Ono
 
downey08semaphores.pdf
downey08semaphores.pdfdowney08semaphores.pdf
downey08semaphores.pdf
Hiroshi Ono
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 
TwitterOct2008.pdf
TwitterOct2008.pdfTwitterOct2008.pdf
TwitterOct2008.pdf
Hiroshi Ono
 

Mais de Hiroshi Ono (20)

Voltdb - wikipedia
Voltdb - wikipediaVoltdb - wikipedia
Voltdb - wikipedia
 
Gamecenter概説
Gamecenter概説Gamecenter概説
Gamecenter概説
 
EventDrivenArchitecture
EventDrivenArchitectureEventDrivenArchitecture
EventDrivenArchitecture
 
program_draft3.pdf
program_draft3.pdfprogram_draft3.pdf
program_draft3.pdf
 
nodalities_issue7.pdf
nodalities_issue7.pdfnodalities_issue7.pdf
nodalities_issue7.pdf
 
genpaxospublic-090703114743-phpapp01.pdf
genpaxospublic-090703114743-phpapp01.pdfgenpaxospublic-090703114743-phpapp01.pdf
genpaxospublic-090703114743-phpapp01.pdf
 
kademlia-1227143905867010-8.pdf
kademlia-1227143905867010-8.pdfkademlia-1227143905867010-8.pdf
kademlia-1227143905867010-8.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
downey08semaphores.pdf
downey08semaphores.pdfdowney08semaphores.pdf
downey08semaphores.pdf
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
TwitterOct2008.pdf
TwitterOct2008.pdfTwitterOct2008.pdf
TwitterOct2008.pdf
 
camel-scala.pdf
camel-scala.pdfcamel-scala.pdf
camel-scala.pdf
 
stateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdf
stateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdfstateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdf
stateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdf
 
stateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdf
stateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdfstateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdf
stateyouredoingitwrongjavaone2009-090617031310-phpapp02.pdf
 
nodalities_issue7.pdf
nodalities_issue7.pdfnodalities_issue7.pdf
nodalities_issue7.pdf
 
genpaxospublic-090703114743-phpapp01.pdf
genpaxospublic-090703114743-phpapp01.pdfgenpaxospublic-090703114743-phpapp01.pdf
genpaxospublic-090703114743-phpapp01.pdf
 
kademlia-1227143905867010-8.pdf
kademlia-1227143905867010-8.pdfkademlia-1227143905867010-8.pdf
kademlia-1227143905867010-8.pdf
 
downey08semaphores.pdf
downey08semaphores.pdfdowney08semaphores.pdf
downey08semaphores.pdf
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
TwitterOct2008.pdf
TwitterOct2008.pdfTwitterOct2008.pdf
TwitterOct2008.pdf
 

pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf

  • 1. Pragmatic Real-World Scala Jonas Bonér Scalable Solutions
  • 2. “If I were to pick a language to use today other than Java, it would be Scala” James Gosling
  • 3. Chat app in Lift  Build a multi-user, comet-based chat app  About 30 lines of code  Three slides worth  Slides By David Pollak, creator of Lift
  • 4. Define Messages case class Add(who: Actor) case class Remove(who: Actor) case class Messages(msgs: List[String])
  • 5. Chat Server object ChatServer extends Actor { private var listeners: List[Actor] = Nil private var msgs: List[String] = Nil def act = loop { react { case s: String => msgs = s :: msgs listeners.foreach(l => l ! Messages(msgs)) case Add(who) => listeners = who :: listeners who ! Messages(msgs) case Remove(who) => listeners -= who } } this.start }
  • 6. Chat Comet Component class Chat extends CometActor { private var msgs: List[String] = Nil def render = <div> <ul>{ msgs.reverse.map(m => <li>{ m }</li>) }</ul> { ajaxText("", s => { ChatServer ! s; Noop }) } </div> override def localSetup = ChatServer ! Add(this) override def localShutdown = ChatServer ! Remove(this) override def lowPriority = { case Messages(m) => msgs = m; reRender(false) } }
  • 9. Unique and elegant blend of OO FP +
  • 10. Pragmatic Since 2003 Sponsored by EPFL Martin Odersky Seamless Java interoperability Friendly and supportive Production community ready Runs on the JVM Statically typed
  • 11. Unique and elegant blend of is...
  • 12. Expressive & light-weight val phonebook = Map( “Jonas” -> “123456”, “Sara” -> “654321”) phonebook += (“Jacob” -> “987654”) println(phonebook(“Jonas”))
  • 13. High-level Java version boolean hasUpperCase = false; for (int i = 0; i < name.length(); i++) { if (Character.isUpperCase(name.charAt(i))) { hasUpperCase = true; break; } }
  • 14. High-level Scala version val hasUpperCase = name.exists(_.isUpperCase)
  • 15. Concise // Java public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; // Scala } public String getName() { class Person( return name; var name: String, } public int getAge() { var age: Int) return age; } public void setName(String name) { this.name = name; } public void setAge(age: int) { this.age = age; } }
  • 16. Pure OO 1 + 2 1.+(2) 123.toString()
  • 17. Extensible val service = actor { loop { receive { case Add(x,y) => reply(x+y) case Sub(x,y) => reply(x-y) } } } service ! Add(4, 2)  6
  • 18. Pragmatic def users = <users> <user role=”customer”> <name>{ user.name }</name> <password>{ user.password }</password> <email>{ user.email }</email> </user> ... </users>
  • 19. Pragmatic users match { case <users>{users @ _*}</users> => for (user <- users) println(“User “ + (user “name”).text) }
  • 20. Great for DSLs Apache Camel “direct:a“ ==> { loadbalance roundrobin { to (“mock:a“) to (“mock:b“) to (“mock:c“) } }
  • 22. But you don’t need to go very deep to still have fun and be productive
  • 23. Java
  • 27. Composition in large
  • 29. Traits & & Self-type annotations
  • 30. Trait trait Dad { private var children: List[Child] = Nil def addChild(child: Child) = children = child :: children def getChildren = children.clone }
  • 31. Base class Man(val name: String) extends Human
  • 33. Static mixin composition class Man(val name: String) extends Human with Dad
  • 34. Static mixin composition usage class Man(val name: String) extends Human with Dad val jonas = new Man(“Jonas”) jonas.addChild(new Child(“Jacob”))
  • 35. Dynamic mixin composition val jonas = new Man(“Jonas”) with Dad
  • 36. Dynamic mixin composition usage val jonas = new Man(“Jonas”) with Dad jonas.addChild(new Child(“Jacob”))
  • 37. 3 different type of traits
  • 38. 1
  • 39. Rich interface trait RichIterable[A] { def iterator: Iterator[A] // contract method def foreach(f: A => Unit) = { val iter = iterator while (iter.hasNext) f(iter.next) } def foldLeft[B](seed: B)(f: (B, A) => B) = { var result = seed foreach(e => result = f(result, e)) result } }
  • 40. Rich interface val richSet = new java.util.HashSet[Int] with RichIterable[Int] richSet.add(1) richSet.add(2) richSet.foldLeft(0)((x, y) => x + y)  3
  • 41. 2
  • 42. Stackable modifications trait IgnoreCaseSet extends java.util.Set[String] { abstract override def add(e: String) = { super.add(e.toLowerCase) } abstract override def contains(e: String) = { super.contains(e.toLowerCase) } abstract override def remove(e: String) = { super.remove(e.toLowerCase) } }
  • 43. Stackable modifications val set = new java.util.HashSet[String] with IgnoreCaseSet set.add(“HI THERE“) // uppercase set.contains(“hi there“) // lowercase  true
  • 44. Add another trait interceptor trait LoggableSet extends java.util.Set[String] { abstract override def add(e: String) = { println(“Add :“ + e) super.add(e) } abstract override def remove(e: String) = { println(“Remove :“ + e) super.remove(e) } }
  • 45. Run the stack of interceptors val set = new java.util.HashSet[String] with IgnoreCaseSet with LoggableSet set.add(“HI THERE“)  “Add: HI THERE” Prints in uppercase
  • 46. Change the order val set = new java.util.HashSet[String] with LoggableSet with IgnoreCaseSet set.add(“HI THERE“)  “Add: hi there” Prints in lowercase
  • 47. 3
  • 48. Multiple views Trait Trait Trait Base Trait Trait
  • 49. Multiple views Trait Trait Trait Base Trait Trait
  • 51. Traits Multiple facets
  • 53. Facets trait Entity { ... } trait InventoryItemSet { ... } trait Invoicable { ... } trait PurchaseLimiter { ... } trait MailNotifier { ... } trait ACL { ... } trait Versioned { ... } trait Transactional { ... }
  • 54. Composition val order = new Order(customer) with Entity with InventoryItemSet with Invoicable with PurchaseLimiter with MailNotifier with ACL with Versioned with Transactional
  • 55. What do you need?
  • 56. DI
  • 59. Dependency declaration trait UserService { this: UserRepository => ... // provided with composition userRepository.merge(user) } …using self-type annotation
  • 60.
  • 62. walks like a duck… if it and talks like a duck… then it’s a duck Duck typing
  • 63. Structural Typing: Duck-typing done right def authorize(target: { def getACL: ACL }) = { val acl = target.getACL ... //authorize } Statically enforced
  • 64. Composition in small
  • 65. “It's Time to Get Good at Functional Programming” Dr Dobb’s Journal Issue December 2008
  • 67. Deterministic High-level Reusable FP Referentially transparent Immutable Declarative Orthogonal
  • 69. Small reusable pieces with input and output
  • 70. Unix pipes cat File | grep 'println' | wc
  • 72. Functions as values val inc = (x: Int) => x + 1 inc(1) 2
  • 73. Functions as parameters high-order List(1, 2, 3).map((x: Int) => x + 1)  List(2, 3, 4)
  • 74. Functions as parameters with sugar List(1, 2, 3).map((x: Int) => x + 1) List(1, 2, 3).map(x => x + 1) List(1, 2, 3).map(_ + 1)
  • 75. Functions as closures val addMore = (x: Int) => x + more
  • 76. What is more?
  • 77. Some value outside the function’s lexical scope var more = 7 val addMore = (x: Int) => x + more addMore(3)  10 more = 8 addMore(3)  11
  • 81. Lists Grow at the front Insert at front  O(1) Insert at end  O(n)
  • 82. List creation List(1, 2, 3) 1 :: 2 :: 3 :: Nil
  • 83. Basics val list = List(1, 2, 3) list.head  1 list.tail  List(2, 3) list.isEmpty  false
  • 84. High-level operations val list = List(1, 2, 3) list.map(_ + 1)  List(2, 3, 4) list.filter(_ < 2)  List(3) list.exists(_ == 3)  true list.drop(2)  List(3) list.reverse  List(3, 2, 1) list.sort(_ > _)  List(3, 2, 1) List.flatten(list)  List(1, 2, 3) list.slice(2, 3)  List(3) ...
  • 86. Tuples def getNameAndAge: Tuple2[String, Int] = { val name = ... val age = ... (name, age) } val (name, age) = getNameAndAge println(“Name: “ + name) println(“Age: “ + age)
  • 87. Other functional data structures: Maps Sets Trees Stacks
  • 88. For comprehensions for (n <- names) println(n)
  • 89. Like SQL queries for { att <- attendees if att.name == “Fred” lang <- att.spokenLanguages if lang == “Danish” } println(att) Find all attendees named Fred that speaks Danish
  • 90. for / yield val companiesForAttendeesFromLondon = for { att <- attendees if att.address.city == “London” } yield att.company
  • 91. Everything returns a value for (thing <- thingsFromHere) yield getRealThing(thing)
  • 92. Everything returns a value val things = for (thing <- thingsFromHere) yield getRealThing(thing)
  • 93. Everything returns a value if (fromHere) { for (thing <- thingsFromHere) yield getRealThing(thing) } else { for (thing <- thingsFromThere) yield thing }
  • 94. Everything returns a value val things = if (fromHere) { for (thing <- thingsFromHere) yield getRealThing(thing) } else { for (thing <- thingsFromThere) yield thing }
  • 95. Everything returns a value try { if (fromHere) { for (thing <- thingsFromHere) yield getRealThing(thing) } else { for (thing <- thingsFromThere) yield thing } } catch { case e => error(e); Nil }
  • 96. Everything returns a value val things = try { if (fromHere) { for (thing <- thingsFromHere) yield getRealThing(thing) } else { for (thing <- thingsFromThere) yield thing } } catch { case e => error(e); Nil }
  • 97. Everything returns a value def getThingsFromSomewhere( fromHere: Boolean): List[Thing] = { try { if (fromHere) { for (thing <- thingsFromHere) yield getRealThing(thing) } else { for (thing <- thingsFromThere) yield thing } } catch { case e => error(e); Nil } }
  • 99. Pattern matching def matchAny(a: Any): Any = a match { case 1 => “one” case “two” => 2 case i: Int => “scala.Int” case <tag>{ t }</tag> => t case head :: tail => head case _ => “default” }
  • 100. Tools
  • 101. Tools: scala/bin scala scalac fsc scaladoc sbaz
  • 102. Tools: IDEs Eclipse NetBeans IntelliJ IDEA Emacs JEdit
  • 103. Building Maven Ant SBT (Simple Build Tool )
  • 104. Tools: Testing Specs ScalaCheck ScalaTest SUnit
  • 105. Frameworks: Web Lift Sweet Slinky Pinky
  • 106. Learn more jonas@jonasboner.com http://jonasboner.com http://scala-lang.org
  • 107. Professional help Consulting Training Mentoring http://scalablesolutions.se
  • 108. Pragmatic Real-World Scala Jonas Bonér Scalable Solutions Copyright 2009 Scalable Solutions