SlideShare una empresa de Scribd logo
1 de 124
Descargar para leer sin conexión
The Seductions of
       Scala
Dean Wampler
dean@deanwampler.com
@deanwampler
polyglotprogramming.com/talks

April 3, 2011

                           1
<shameless-plug/>

  Co-author,
 Programming
     Scala
programmingscala.com


                       2
Why do we
need a new
 language?
    3
#1
  We need
 Functional
Programming
     …
     4
… for concurrency.
… for concise code.
… for correctness.
          5
#2
We need a better
 Object Model
      …
       6
… for composability.
… for scalable designs.

          7
Scala’s Thesis:
Functional Prog.
 Complements
Object-Oriented
     Prog.
       8
Scala’s Thesis:
Functional Prog.
 Complements
Object-Oriented
     Prog.
 Despite surface contradictions...
                 8
But we want to
keep our investment
    in Java/C#.

         9
Scala is...

• A JVM and .NET language.
• Functional and object oriented.
• Statically typed.
• An improved Java/C#.

                10
Martin Odersky
• Helped design java generics.
• Co-wrote GJ that became
  javac (v1.3+).
• Understands Computer
  Science and Industry.
              11
Everything can
be a Function
      12
Objects
   as
Functions
    13
class Logger(val level:Level) {

 def apply(message: String) = {
   // pass to Log4J...
   Log4J.log(level, message)
 }
}



               14
class Logger(val level:Level) {

 def apply(message: String) = {
   // pass to Log4J...
   Log4J.log(level, message)
 }
}



               15
class Logger(val level:Level) {

 def apply(message: String) = {
   // pass to Log4J...
   Log4J.log(level, message)
 }
}
                      class body is the
                    “primary” constructor
               15
makes “level” a field
class Logger(val level:Level) {

 def apply(message: String) = {
   // pass to Log4J...
   Log4J.log(level, message)
 }
}
                      class body is the
                    “primary” constructor
               15
makes “level” a field
class Logger(val level:Level) {

 def apply(message: String) = {
   // pass to Log4J...
   Log4J.log(level, message)
 }                        method
}
                      class body is the
                    “primary” constructor
               15
class Logger(val level:Level) {

 def apply(message: String) = {
   // pass to Log4J...
   Log4J.log(level, message)
 }
}




               16
class Logger(val level:Level) {

 def apply(message: String) = {
   // pass to Log4J...
   Log4J.log(level, message)
 }
}
val error = new Logger(ERROR)



               16
class Logger(val level:Level) {

 def apply(message: String) = {
   // pass to Log4J...
   Log4J.log(level, message)
 }
}
val error = new Logger(ERROR)
…
error("Network error.")
               16
class Logger(val level:Level) {

 def apply(message: String) = {
   // pass to Log4J...
   Log4J.log(level, message)
 }
}


…
error("Network error.")
               17
class Logger(val level:Level) {

 def apply(message: String) = {
   // pass to Log4J...
   Log4J.log(level, message)
 }
}

    apply is called        “function object”
…
error("Network error.")
                      17
When you put
    an arg list
after any object,
 apply is called.
        18
Everything is
 an Object
      19
Int, Double, etc.
are true objects.

        20
Int, Double, etc.
are true objects.
But they are compiled to primitives.

                 20
Functions
   as
 Objects
    21
First, About Lists

val list = List(1, 2, 3, 4, 5)




               22
First, About Lists

val list = List(1, 2, 3, 4, 5)


    The same as this “list literal” syntax:

val list =
  1 :: 2 :: 3 :: 4 :: 5 :: Nil

                      22
val list =
  1 :: 2 :: 3 :: 4 :: 5 :: Nil




               23
“cons”
val list =
  1 :: 2 :: 3 :: 4 :: 5 :: Nil




               23
“cons”   empty list
val list =
  1 :: 2 :: 3 :: 4 :: 5 :: Nil




               23
“cons”   empty list
val list =
  1 :: 2 :: 3 :: 4 :: 5 :: Nil


head




               23
“cons”   empty list
val list =
  1 :: 2 :: 3 :: 4 :: 5 :: Nil


head                tail




               23
Baked into the
         Grammar?
val list =
  1 :: 2 :: 3 :: 4 :: 5 :: Nil




               24
Baked into the
         Grammar?
val list =
  1 :: 2 :: 3 :: 4 :: 5 :: Nil

        No, just method calls!

val list = Nil.::(5).::(4).::(
 3).::(2).::(1)


                  24
val list =
  1 :: 2 :: 3 :: 4 :: 5 :: Nil

val list = Nil.::(5).::(4).::(
 3).::(2).::(1)




               25
val list =
  1 :: 2 :: 3 :: 4 :: 5 :: Nil

val list = Nil.::(5).::(4).::(
 3).::(2).::(1)


   Method names can contain almost any
              character.

                    25
val list =
  1 :: 2 :: 3 :: 4 :: 5 :: Nil

val list = Nil.::(5).::(4).::(
 3).::(2).::(1)


  Any method ending in “:” binds to the right!


                       26
val list =
  1 :: 2 :: 3 :: 4 :: 5 :: Nil

val list = Nil.::(5).::(4).::(
 3).::(2).::(1)


 If a method takes one argument, you can drop
     the “.” and the parentheses, “(“ and “)”.

                       27
Infix Operator Notation
  "hello" + "world"




           28
Infix Operator Notation
  "hello" + "world"


       is actually just


  "hello".+("world")

              28
Similar mini-DSLs
have been defined
 for other types.

        29
Similar mini-DSLs
have been defined
 for other types.
 Also in many third-party libraries.

                 29
Back to
functions as objects...

           30
Classic Operations on
 “Container” Types
   List, Map, ...         map




                          filter



                          fold/
                         reduce




                    31
val list = "a" :: "b" :: Nil




              32
val list = "a" :: "b" :: Nil

list map {
  s => s.toUpperCase
}

// => "A" :: "B" :: Nil



              32
list map {
  s => s.toUpperCase
}




              33
map called on list
(dropping the “.”)

 list map {
   s => s.toUpperCase
 }




                     33
map called on list
(dropping the “.”)   argument to map
                     (using “{“ vs. “(“)
 list map {
   s => s.toUpperCase
 }




                     33
map called on list
(dropping the “.”)   argument to map
                     (using “{“ vs. “(“)
 list map {
   s => s.toUpperCase
 }
                               “function literal”




                     33
map called on list
(dropping the “.”)   argument to map
                     (using “{“ vs. “(“)
 list map {
   s => s.toUpperCase
 }
                               “function literal”
  function
argument list


                     33
map called on list
(dropping the “.”)         argument to map
                           (using “{“ vs. “(“)
 list map {
   s => s.toUpperCase
 }
                                     “function literal”
  function           function body
argument list


                           33
list map {
  s => s.toUpperCase
}




              34
list map {
  s => s.toUpperCase
}
   inferred type




              34
list map {
  s => s.toUpperCase
}
   inferred type
list map {
  (s:String) => s.toUpperCase
}
           Explicit type
              34
So far,
we have used
type inference
    a lot...
      35
How the Sausage Is Made

class List[A] {
  …
  def map[B](f: A => B): List[B]
 …
}


               36
How the Sausage Is Made
               Parameterized type

class List[A] {
  …
  def map[B](f: A => B): List[B]
 …
}


               36
How the Sausage Is Made
                   Parameterized type

class List[A] {
                    Declaration of map
  …
  def map[B](f: A => B): List[B]
 …
}      The function   map’s return type
        argument
                   36
How the Sausage Is Made

 trait Function1[-A,+R] {

  def apply(a:A): R
  …
 }

              37
How the Sausage Is Made
 like an “abstract” class

 trait Function1[-A,+R] {

  def apply(a:A): R
  …
 }

                      37
How the Sausage Is Made
  like an “abstract” class

 trait Function1[-A,+R] {

  def apply(a:A): R
  …
 }        No method body:
            => abstract

                       37
How the Sausage Is Made
                              “contravariant”,
  like an “abstract” class
                             “covariant” typing

 trait Function1[-A,+R] {

  def apply(a:A): R
  …
 }        No method body:
            => abstract

                       37
What the Compiler Does
 (s:String) => s.toUpperCase


new Function1[String,String] {
  def apply(s:String) = {
    s.toUpperCase
  }
}

               38
What the Compiler Does
 (s:String) => s.toUpperCase
               What you write.
new Function1[String,String] {
  def apply(s:String) = {
    s.toUpperCase
  }            What the compiler
}                 generates
                     An anonymous class
                38
What the Compiler Does
 (s:String) => s.toUpperCase
                What you write.
new Function1[String,String] {
  def apply(s:String) = {
    s.toUpperCase
  }             What the compiler
}                  generates
    No “return”
    needed            An anonymous class
                38
Recap
val list = "a" :: "b" :: Nil
list map {
  s => s.toUpperCase
}

// => "A" :: "B" :: Nil



              39
Recap
val list = "a" :: "b" :: Nil
list map {
  s => s.toUpperCase
}                 Function “object”
// => "A" :: "B" :: Nil



                 39
Recap
val list = "a" :: "b" :: Nil
list map {    {…} ok, instead of (…)
    s => s.toUpperCase
}                     Function “object”
// => "A" :: "B" :: Nil



                 39
More
Functional
 Hotness
    40
Avoiding Nulls
sealed abstract class Option[+T]
{…}

case class Some[+T](value: T)
  extends Option[T] {…}

case object None
  extends Option[Nothing] {…}

               41
Avoiding Nulls
sealed abstract class Option[+T]
{…}

case class Some[+T](value: T)
  extends Option[T] {…}

case object None
  extends Option[Nothing] {…}

               41
                    An Algebraic Data Type
// Java style (schematic)
class Map[K, V] {
 def get(key: K): V = {
  return value || null;
 }}




               42
// Java style (schematic)
class Map[K, V] {
 def get(key: K): V = {
  return value || null;
 }}




               42
// Java style (schematic)
class Map[K, V] {
 def get(key: K): V = {
  return value || null;
 }}
// Scala style
class Map[K, V] {
 def get(key: K): Option[V] = {
  return Some(value) || None;
 }}
                  Which is the better API?
                   42
In Use:
val m =
   Map("one" -> 1, "two" -> 2)
…
val n = m.get("four") match {
  case Some(i) => i
  case None    => 0 // default
}


               43
In Use:
val m =        Literal syntax for map creation
   Map("one" -> 1, "two" -> 2)
…
val n = m.get("four") match {
  case Some(i) => i
  case None    => 0 // default
}

Use pattern matching to extract the value (or not)
                      43
Option Details: sealed


sealed abstract class Option[+T]
{…}




               44
Option Details: sealed


sealed abstract class Option[+T]
{…}


              All children must be defined
                      in the same file
               44
Case Classes

case class Some[+T](value: T)




               45
Case Classes

case class Some[+T](value: T)



        ●Provides factory method, pattern
         matching, equals, toString, etc.
        ●Makes “value” a field without val
         keyword.
                  45
Object
case object None
  extends Option[Nothing] {…}




               46
Object
case object None
  extends Option[Nothing] {…}




      A “singleton”. Only one instance will exist.
                     46
Nothing
case object None
  extends Option[Nothing] {…}




               47
Nothing
case object None
  extends Option[Nothing] {…}



             Special child type of all other
              types. Used for this special
                 case where no actual
                  instances required.
               47
Succinct Code
      48
Succinct Code
  A few things we’ve seen so far.
                48
Infix Operator
   Notation
"hello" + "world"




        49
Infix Operator
   Notation
"hello" + "world"

      same as
"hello".+("world")




         49
Type Inference
// Java
HashMap<String,Person> persons =
 new HashMap<String,Person>();




               50
Type Inference
// Java
HashMap<String,Person> persons =
 new HashMap<String,Person>();
               vs.
// Scala
val persons
 = new HashMap[String,Person]
               50
Type Inference
// Java
HashMap<String,Person> persons =
 new HashMap<String,Person>();
               vs.
// Scala
val persons
 = new HashMap[String,Person]
               51
Type Inference
// Java
HashMap<String,Person> persons =
 new HashMap<String,Person>();
               vs.
// Scala
val persons
 = new HashMap[String,Person]
               51
// Scala
val persons
 = new HashMap[String,Person]




               52
// Scala
val persons
 = new HashMap[String,Person]


                      no () needed.
                    Semicolons inferred.

               52
User-defined Factory
         Methods

val words =
  List("Scala", "is", "fun!")




               53
User-defined Factory
         Methods

val words =
  List("Scala", "is", "fun!")


           no new needed.
         Can return a subtype!
                  53
class Person {
  private String firstName;
  private String lastName;
  private int    age;

    public Person(String firstName, String lastName, int age){
      this.firstName = firstName;
      this.lastName = lastName;
      this.age       = age;
    }

    public void String getFirstName() {return this.firstName;}
    public void setFirstName(String firstName) {
      this.firstName = firstName;
    }

    public void String getLastName() {return this.lastName;}
    public void setLastName(String lastName) {
      this.lastName = lastName;
    }

    public void int getAge() {return this.age;}
    public void setAge(int age) {
      this.age = age;
    }
}                               54
class Person {
  private String firstName;
  private String lastName;
  private int    age;

    public Person(String firstName, String lastName, int age){
      this.firstName = firstName;
      this.lastName = lastName;
      this.age       = age;
    }

    public void String getFirstName() {return this.firstName;}
    public void setFirstName(String firstName) {
      this.firstName = firstName;
    }

    public void String getLastName() {return this.lastName;}
    public void setLastName(String lastName) {
      this.lastName = lastName;
    }

    public void int getAge() {return this.age;}
    public void setAge(int age) {
      this.age = age;
    }                                             Typical Java
}                               54
class   Person(
  var   firstName: String,
  var   lastName: String,
  var   age: Int)




                 55
class   Person(
  var   firstName: String,
  var   lastName: String,
  var   age: Int)




                         Typical Scala!
                 55
class   Person(
  var   firstName: String,
  var   lastName: String,
  var   age: Int)




                 56
Class body is the
 “primary” constructor
                         Parameter list for c’tor
  class    Person(
    var    firstName: String,
    var    lastName: String,
    var    age: Int)
                                  No class body {…}.
Makes the arg a field              nothing else needed!
  with accessors

                            56
Even Better...
case class Person(
  firstName: String,
  lastName: String,
  age: Int)




               57
Even Better...
case class Person(
  firstName: String,
  lastName: String,
  age: Int)



          Constructor args are automatically
               vals, plus other goodies.
                 57
Scala’s Object
 Model: Traits
      58
Scala’s Object
 Model: Traits
  Composable Units of Behavior
               58
We would like to
compose objects
  from mixins.

       59
Java: What to Do?
class Server
 extends Logger { … }




            60
Java: What to Do?
class Server
 extends Logger { … }

             “Server is a Logger”?




            60
Java: What to Do?
class Server
 extends Logger { … }

             “Server is a Logger”?

class Server
 implements Logger { … }

           Logger isn’t an interface!
            60
Java’s object model




         61
Java’s object model
• Good
 • Promotes abstractions.
• Bad
 • No composition through
  reusable mixins.
             61
Traits

Like interfaces with
 implementations,


         62
Traits
     … or like
abstract classes +
multiple inheritance
 (if you prefer).
         63
Logger as a Mixin:
trait Logger {
 val level: Level // abstract

 def log(message: String) = {
   Log4J.log(level, message)
 }
}



                64
Logger as a Mixin:
trait Logger {
 val level: Level // abstract

  def log(message: String) = {
    Log4J.log(level, message)
  }
}                      Traits don’t have
                       constructors, but
                         you can still
                         define fields.
                    64
Logger as a Mixin:
trait Logger {
  val level: Level // abstract
  …
}




                65
Logger as a Mixin:
trait Logger {
  val level: Level // abstract
  …
}
val server =
  new Server(…) with Logger {
    val level = ERROR
  }
server.log("Internet down!!")
                65
Logger as a Mixin:
trait Logger {
  val level: Level // abstract
  …
}                   mixed in Logging
val server =
  new Server(…) with Logger {
    val level = ERROR
  }
server.log("Internet down!!")
                   65

Más contenido relacionado

La actualidad más candente

Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsJohn De Goes
 
Introduction To Lisp
Introduction To LispIntroduction To Lisp
Introduction To Lispkyleburton
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 
Programming in Scala: Notes
Programming in Scala: NotesProgramming in Scala: Notes
Programming in Scala: NotesRoberto Casadei
 
JavaOne 2016 - Learn Lambda and functional programming
JavaOne 2016 - Learn Lambda and functional programmingJavaOne 2016 - Learn Lambda and functional programming
JavaOne 2016 - Learn Lambda and functional programmingHenri Tremblay
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class PatternsJohn De Goes
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New GameJohn De Goes
 
TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsEelco Visser
 
Lambda выражения и Java 8
Lambda выражения и Java 8Lambda выражения и Java 8
Lambda выражения и Java 8Alex Tumanoff
 
Java patterns in Scala
Java patterns in ScalaJava patterns in Scala
Java patterns in ScalaRadim Pavlicek
 
New features in jdk8 iti
New features in jdk8 itiNew features in jdk8 iti
New features in jdk8 itiAhmed mar3y
 
Java 8, lambdas, generics: How to survive? - NYC Java Meetup Group
Java 8, lambdas, generics: How to survive? - NYC Java Meetup GroupJava 8, lambdas, generics: How to survive? - NYC Java Meetup Group
Java 8, lambdas, generics: How to survive? - NYC Java Meetup GroupHenri Tremblay
 
The Next Great Functional Programming Language
The Next Great Functional Programming LanguageThe Next Great Functional Programming Language
The Next Great Functional Programming LanguageJohn De Goes
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systemsleague
 
scala-gopher: async implementation of CSP for scala
scala-gopher:  async implementation of CSP  for  scalascala-gopher:  async implementation of CSP  for  scala
scala-gopher: async implementation of CSP for scalaRuslan Shevchenko
 
JavaScript Web Development
JavaScript Web DevelopmentJavaScript Web Development
JavaScript Web Developmentvito jeng
 

La actualidad más candente (20)

Joy of scala
Joy of scalaJoy of scala
Joy of scala
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
 
Introduction To Lisp
Introduction To LispIntroduction To Lisp
Introduction To Lisp
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Programming in Scala: Notes
Programming in Scala: NotesProgramming in Scala: Notes
Programming in Scala: Notes
 
JavaOne 2016 - Learn Lambda and functional programming
JavaOne 2016 - Learn Lambda and functional programmingJavaOne 2016 - Learn Lambda and functional programming
JavaOne 2016 - Learn Lambda and functional programming
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class Patterns
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
 
TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class Functions
 
Lambda выражения и Java 8
Lambda выражения и Java 8Lambda выражения и Java 8
Lambda выражения и Java 8
 
Java patterns in Scala
Java patterns in ScalaJava patterns in Scala
Java patterns in Scala
 
New features in jdk8 iti
New features in jdk8 itiNew features in jdk8 iti
New features in jdk8 iti
 
Java 8, lambdas, generics: How to survive? - NYC Java Meetup Group
Java 8, lambdas, generics: How to survive? - NYC Java Meetup GroupJava 8, lambdas, generics: How to survive? - NYC Java Meetup Group
Java 8, lambdas, generics: How to survive? - NYC Java Meetup Group
 
The Next Great Functional Programming Language
The Next Great Functional Programming LanguageThe Next Great Functional Programming Language
The Next Great Functional Programming Language
 
Java 8 Lambda Expressions
Java 8 Lambda ExpressionsJava 8 Lambda Expressions
Java 8 Lambda Expressions
 
Haskell
HaskellHaskell
Haskell
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
 
scala-gopher: async implementation of CSP for scala
scala-gopher:  async implementation of CSP  for  scalascala-gopher:  async implementation of CSP  for  scala
scala-gopher: async implementation of CSP for scala
 
Lisp
LispLisp
Lisp
 
JavaScript Web Development
JavaScript Web DevelopmentJavaScript Web Development
JavaScript Web Development
 

Similar a Seductions of Scala

Real Time Big Data Management
Real Time Big Data ManagementReal Time Big Data Management
Real Time Big Data ManagementAlbert Bifet
 
(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. Introduction to FP. Monads
Scala. Introduction to FP. MonadsScala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsKirill Kozlov
 
Scala for Java Developers - Intro
Scala for Java Developers - IntroScala for Java Developers - Intro
Scala for Java Developers - IntroDavid Copeland
 
The Kotlin Programming Language, Svetlana Isakova
The Kotlin Programming Language, Svetlana IsakovaThe Kotlin Programming Language, Svetlana Isakova
The Kotlin Programming Language, Svetlana IsakovaVasil Remeniuk
 
Светлана Исакова «Язык Kotlin»
Светлана Исакова «Язык Kotlin»Светлана Исакова «Язык Kotlin»
Светлана Исакова «Язык Kotlin»e-Legion
 
Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kirill Rozov
 
Type Classes in Scala and Haskell
Type Classes in Scala and HaskellType Classes in Scala and Haskell
Type Classes in Scala and HaskellHermann Hueck
 
Python programming: Anonymous functions, String operations
Python programming: Anonymous functions, String operationsPython programming: Anonymous functions, String operations
Python programming: Anonymous functions, String operationsMegha V
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming iiPrashant Kalkar
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Philip Schwarz
 
openCypher Technology Compatibility Kit (TCK)
openCypher Technology Compatibility Kit (TCK)openCypher Technology Compatibility Kit (TCK)
openCypher Technology Compatibility Kit (TCK)openCypher
 
Lecture 5: Functional Programming
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional ProgrammingEelco Visser
 
The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202Mahmoud Samir Fayed
 
Monadologie
MonadologieMonadologie
Monadologieleague
 

Similar a Seductions of Scala (20)

Real Time Big Data Management
Real Time Big Data ManagementReal Time Big Data Management
Real Time Big Data Management
 
Python Basics
Python BasicsPython Basics
Python Basics
 
(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. Introduction to FP. Monads
Scala. Introduction to FP. MonadsScala. Introduction to FP. Monads
Scala. Introduction to FP. Monads
 
Frp2016 3
Frp2016 3Frp2016 3
Frp2016 3
 
Scala for Java Developers - Intro
Scala for Java Developers - IntroScala for Java Developers - Intro
Scala for Java Developers - Intro
 
The Kotlin Programming Language, Svetlana Isakova
The Kotlin Programming Language, Svetlana IsakovaThe Kotlin Programming Language, Svetlana Isakova
The Kotlin Programming Language, Svetlana Isakova
 
Светлана Исакова «Язык Kotlin»
Светлана Исакова «Язык Kotlin»Светлана Исакова «Язык Kotlin»
Светлана Исакова «Язык Kotlin»
 
Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2
 
Java gets a closure
Java gets a closureJava gets a closure
Java gets a closure
 
Type Classes in Scala and Haskell
Type Classes in Scala and HaskellType Classes in Scala and Haskell
Type Classes in Scala and Haskell
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Python programming: Anonymous functions, String operations
Python programming: Anonymous functions, String operationsPython programming: Anonymous functions, String operations
Python programming: Anonymous functions, String operations
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3
 
openCypher Technology Compatibility Kit (TCK)
openCypher Technology Compatibility Kit (TCK)openCypher Technology Compatibility Kit (TCK)
openCypher Technology Compatibility Kit (TCK)
 
Lecture 5: Functional Programming
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional Programming
 
The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202
 
Monadologie
MonadologieMonadologie
Monadologie
 
Scala vs Ruby
Scala vs RubyScala vs Ruby
Scala vs Ruby
 

Más de Dean Wampler

Stream all the things
Stream all the thingsStream all the things
Stream all the thingsDean Wampler
 
Reactive Streams 1.0 and Akka Streams
Reactive Streams 1.0 and Akka StreamsReactive Streams 1.0 and Akka Streams
Reactive Streams 1.0 and Akka StreamsDean Wampler
 
Why Spark Is the Next Top (Compute) Model
Why Spark Is the Next Top (Compute) ModelWhy Spark Is the Next Top (Compute) Model
Why Spark Is the Next Top (Compute) ModelDean Wampler
 
Why Scala Is Taking Over the Big Data World
Why Scala Is Taking Over the Big Data WorldWhy Scala Is Taking Over the Big Data World
Why Scala Is Taking Over the Big Data WorldDean Wampler
 
Error Handling in Reactive Systems
Error Handling in Reactive SystemsError Handling in Reactive Systems
Error Handling in Reactive SystemsDean Wampler
 
Why Spark Is the Next Top (Compute) Model
Why Spark Is the Next Top (Compute) ModelWhy Spark Is the Next Top (Compute) Model
Why Spark Is the Next Top (Compute) ModelDean Wampler
 
Reactive design: languages, and paradigms
Reactive design: languages, and paradigmsReactive design: languages, and paradigms
Reactive design: languages, and paradigmsDean Wampler
 
Spark the next top compute model
Spark   the next top compute modelSpark   the next top compute model
Spark the next top compute modelDean Wampler
 
MapReduce and Its Discontents
MapReduce and Its DiscontentsMapReduce and Its Discontents
MapReduce and Its DiscontentsDean Wampler
 

Más de Dean Wampler (9)

Stream all the things
Stream all the thingsStream all the things
Stream all the things
 
Reactive Streams 1.0 and Akka Streams
Reactive Streams 1.0 and Akka StreamsReactive Streams 1.0 and Akka Streams
Reactive Streams 1.0 and Akka Streams
 
Why Spark Is the Next Top (Compute) Model
Why Spark Is the Next Top (Compute) ModelWhy Spark Is the Next Top (Compute) Model
Why Spark Is the Next Top (Compute) Model
 
Why Scala Is Taking Over the Big Data World
Why Scala Is Taking Over the Big Data WorldWhy Scala Is Taking Over the Big Data World
Why Scala Is Taking Over the Big Data World
 
Error Handling in Reactive Systems
Error Handling in Reactive SystemsError Handling in Reactive Systems
Error Handling in Reactive Systems
 
Why Spark Is the Next Top (Compute) Model
Why Spark Is the Next Top (Compute) ModelWhy Spark Is the Next Top (Compute) Model
Why Spark Is the Next Top (Compute) Model
 
Reactive design: languages, and paradigms
Reactive design: languages, and paradigmsReactive design: languages, and paradigms
Reactive design: languages, and paradigms
 
Spark the next top compute model
Spark   the next top compute modelSpark   the next top compute model
Spark the next top compute model
 
MapReduce and Its Discontents
MapReduce and Its DiscontentsMapReduce and Its Discontents
MapReduce and Its Discontents
 

Último

08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 

Último (20)

08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 

Seductions of Scala

  • 1. The Seductions of Scala Dean Wampler dean@deanwampler.com @deanwampler polyglotprogramming.com/talks April 3, 2011 1
  • 2. <shameless-plug/> Co-author, Programming Scala programmingscala.com 2
  • 3. Why do we need a new language? 3
  • 4. #1 We need Functional Programming … 4
  • 5. … for concurrency. … for concise code. … for correctness. 5
  • 6. #2 We need a better Object Model … 6
  • 7. … for composability. … for scalable designs. 7
  • 8. Scala’s Thesis: Functional Prog. Complements Object-Oriented Prog. 8
  • 9. Scala’s Thesis: Functional Prog. Complements Object-Oriented Prog. Despite surface contradictions... 8
  • 10. But we want to keep our investment in Java/C#. 9
  • 11. Scala is... • A JVM and .NET language. • Functional and object oriented. • Statically typed. • An improved Java/C#. 10
  • 12. Martin Odersky • Helped design java generics. • Co-wrote GJ that became javac (v1.3+). • Understands Computer Science and Industry. 11
  • 13. Everything can be a Function 12
  • 14. Objects as Functions 13
  • 15. class Logger(val level:Level) { def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) } } 14
  • 16. class Logger(val level:Level) { def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) } } 15
  • 17. class Logger(val level:Level) { def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) } } class body is the “primary” constructor 15
  • 18. makes “level” a field class Logger(val level:Level) { def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) } } class body is the “primary” constructor 15
  • 19. makes “level” a field class Logger(val level:Level) { def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) } method } class body is the “primary” constructor 15
  • 20. class Logger(val level:Level) { def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) } } 16
  • 21. class Logger(val level:Level) { def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) } } val error = new Logger(ERROR) 16
  • 22. class Logger(val level:Level) { def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) } } val error = new Logger(ERROR) … error("Network error.") 16
  • 23. class Logger(val level:Level) { def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) } } … error("Network error.") 17
  • 24. class Logger(val level:Level) { def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) } } apply is called “function object” … error("Network error.") 17
  • 25. When you put an arg list after any object, apply is called. 18
  • 26. Everything is an Object 19
  • 27. Int, Double, etc. are true objects. 20
  • 28. Int, Double, etc. are true objects. But they are compiled to primitives. 20
  • 29. Functions as Objects 21
  • 30. First, About Lists val list = List(1, 2, 3, 4, 5) 22
  • 31. First, About Lists val list = List(1, 2, 3, 4, 5) The same as this “list literal” syntax: val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil 22
  • 32. val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil 23
  • 33. “cons” val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil 23
  • 34. “cons” empty list val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil 23
  • 35. “cons” empty list val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil head 23
  • 36. “cons” empty list val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil head tail 23
  • 37. Baked into the Grammar? val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil 24
  • 38. Baked into the Grammar? val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil No, just method calls! val list = Nil.::(5).::(4).::( 3).::(2).::(1) 24
  • 39. val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil val list = Nil.::(5).::(4).::( 3).::(2).::(1) 25
  • 40. val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil val list = Nil.::(5).::(4).::( 3).::(2).::(1) Method names can contain almost any character. 25
  • 41. val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil val list = Nil.::(5).::(4).::( 3).::(2).::(1) Any method ending in “:” binds to the right! 26
  • 42. val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil val list = Nil.::(5).::(4).::( 3).::(2).::(1) If a method takes one argument, you can drop the “.” and the parentheses, “(“ and “)”. 27
  • 43. Infix Operator Notation "hello" + "world" 28
  • 44. Infix Operator Notation "hello" + "world" is actually just "hello".+("world") 28
  • 45. Similar mini-DSLs have been defined for other types. 29
  • 46. Similar mini-DSLs have been defined for other types. Also in many third-party libraries. 29
  • 47. Back to functions as objects... 30
  • 48. Classic Operations on “Container” Types List, Map, ... map filter fold/ reduce 31
  • 49. val list = "a" :: "b" :: Nil 32
  • 50. val list = "a" :: "b" :: Nil list map { s => s.toUpperCase } // => "A" :: "B" :: Nil 32
  • 51. list map { s => s.toUpperCase } 33
  • 52. map called on list (dropping the “.”) list map { s => s.toUpperCase } 33
  • 53. map called on list (dropping the “.”) argument to map (using “{“ vs. “(“) list map { s => s.toUpperCase } 33
  • 54. map called on list (dropping the “.”) argument to map (using “{“ vs. “(“) list map { s => s.toUpperCase } “function literal” 33
  • 55. map called on list (dropping the “.”) argument to map (using “{“ vs. “(“) list map { s => s.toUpperCase } “function literal” function argument list 33
  • 56. map called on list (dropping the “.”) argument to map (using “{“ vs. “(“) list map { s => s.toUpperCase } “function literal” function function body argument list 33
  • 57. list map { s => s.toUpperCase } 34
  • 58. list map { s => s.toUpperCase } inferred type 34
  • 59. list map { s => s.toUpperCase } inferred type list map { (s:String) => s.toUpperCase } Explicit type 34
  • 60. So far, we have used type inference a lot... 35
  • 61. How the Sausage Is Made class List[A] { … def map[B](f: A => B): List[B]  … } 36
  • 62. How the Sausage Is Made Parameterized type class List[A] { … def map[B](f: A => B): List[B]  … } 36
  • 63. How the Sausage Is Made Parameterized type class List[A] { Declaration of map … def map[B](f: A => B): List[B]  … } The function map’s return type argument 36
  • 64. How the Sausage Is Made trait Function1[-A,+R] {  def apply(a:A): R  … } 37
  • 65. How the Sausage Is Made like an “abstract” class trait Function1[-A,+R] {  def apply(a:A): R  … } 37
  • 66. How the Sausage Is Made like an “abstract” class trait Function1[-A,+R] {  def apply(a:A): R  … } No method body: => abstract 37
  • 67. How the Sausage Is Made “contravariant”, like an “abstract” class “covariant” typing trait Function1[-A,+R] {  def apply(a:A): R  … } No method body: => abstract 37
  • 68. What the Compiler Does (s:String) => s.toUpperCase new Function1[String,String] { def apply(s:String) = { s.toUpperCase } } 38
  • 69. What the Compiler Does (s:String) => s.toUpperCase What you write. new Function1[String,String] { def apply(s:String) = { s.toUpperCase } What the compiler } generates An anonymous class 38
  • 70. What the Compiler Does (s:String) => s.toUpperCase What you write. new Function1[String,String] { def apply(s:String) = { s.toUpperCase } What the compiler } generates No “return” needed An anonymous class 38
  • 71. Recap val list = "a" :: "b" :: Nil list map { s => s.toUpperCase } // => "A" :: "B" :: Nil 39
  • 72. Recap val list = "a" :: "b" :: Nil list map { s => s.toUpperCase } Function “object” // => "A" :: "B" :: Nil 39
  • 73. Recap val list = "a" :: "b" :: Nil list map { {…} ok, instead of (…) s => s.toUpperCase } Function “object” // => "A" :: "B" :: Nil 39
  • 75. Avoiding Nulls sealed abstract class Option[+T] {…} case class Some[+T](value: T) extends Option[T] {…} case object None extends Option[Nothing] {…} 41
  • 76. Avoiding Nulls sealed abstract class Option[+T] {…} case class Some[+T](value: T) extends Option[T] {…} case object None extends Option[Nothing] {…} 41 An Algebraic Data Type
  • 77. // Java style (schematic) class Map[K, V] { def get(key: K): V = { return value || null; }} 42
  • 78. // Java style (schematic) class Map[K, V] { def get(key: K): V = { return value || null; }} 42
  • 79. // Java style (schematic) class Map[K, V] { def get(key: K): V = { return value || null; }} // Scala style class Map[K, V] { def get(key: K): Option[V] = { return Some(value) || None; }} Which is the better API? 42
  • 80. In Use: val m = Map("one" -> 1, "two" -> 2) … val n = m.get("four") match { case Some(i) => i case None => 0 // default } 43
  • 81. In Use: val m = Literal syntax for map creation Map("one" -> 1, "two" -> 2) … val n = m.get("four") match { case Some(i) => i case None => 0 // default } Use pattern matching to extract the value (or not) 43
  • 82. Option Details: sealed sealed abstract class Option[+T] {…} 44
  • 83. Option Details: sealed sealed abstract class Option[+T] {…} All children must be defined in the same file 44
  • 84. Case Classes case class Some[+T](value: T) 45
  • 85. Case Classes case class Some[+T](value: T) ●Provides factory method, pattern matching, equals, toString, etc. ●Makes “value” a field without val keyword. 45
  • 86. Object case object None extends Option[Nothing] {…} 46
  • 87. Object case object None extends Option[Nothing] {…} A “singleton”. Only one instance will exist. 46
  • 88. Nothing case object None extends Option[Nothing] {…} 47
  • 89. Nothing case object None extends Option[Nothing] {…} Special child type of all other types. Used for this special case where no actual instances required. 47
  • 91. Succinct Code A few things we’ve seen so far. 48
  • 92. Infix Operator Notation "hello" + "world" 49
  • 93. Infix Operator Notation "hello" + "world" same as "hello".+("world") 49
  • 94. Type Inference // Java HashMap<String,Person> persons = new HashMap<String,Person>(); 50
  • 95. Type Inference // Java HashMap<String,Person> persons = new HashMap<String,Person>(); vs. // Scala val persons = new HashMap[String,Person] 50
  • 96. Type Inference // Java HashMap<String,Person> persons = new HashMap<String,Person>(); vs. // Scala val persons = new HashMap[String,Person] 51
  • 97. Type Inference // Java HashMap<String,Person> persons = new HashMap<String,Person>(); vs. // Scala val persons = new HashMap[String,Person] 51
  • 98. // Scala val persons = new HashMap[String,Person] 52
  • 99. // Scala val persons = new HashMap[String,Person] no () needed. Semicolons inferred. 52
  • 100. User-defined Factory Methods val words = List("Scala", "is", "fun!") 53
  • 101. User-defined Factory Methods val words = List("Scala", "is", "fun!") no new needed. Can return a subtype! 53
  • 102. class Person { private String firstName; private String lastName; private int age; public Person(String firstName, String lastName, int age){ this.firstName = firstName; this.lastName = lastName; this.age = age; } public void String getFirstName() {return this.firstName;} public void setFirstName(String firstName) { this.firstName = firstName; } public void String getLastName() {return this.lastName;} public void setLastName(String lastName) { this.lastName = lastName; } public void int getAge() {return this.age;} public void setAge(int age) { this.age = age; } } 54
  • 103. class Person { private String firstName; private String lastName; private int age; public Person(String firstName, String lastName, int age){ this.firstName = firstName; this.lastName = lastName; this.age = age; } public void String getFirstName() {return this.firstName;} public void setFirstName(String firstName) { this.firstName = firstName; } public void String getLastName() {return this.lastName;} public void setLastName(String lastName) { this.lastName = lastName; } public void int getAge() {return this.age;} public void setAge(int age) { this.age = age; } Typical Java } 54
  • 104. class Person( var firstName: String, var lastName: String, var age: Int) 55
  • 105. class Person( var firstName: String, var lastName: String, var age: Int) Typical Scala! 55
  • 106. class Person( var firstName: String, var lastName: String, var age: Int) 56
  • 107. Class body is the “primary” constructor Parameter list for c’tor class Person( var firstName: String, var lastName: String, var age: Int) No class body {…}. Makes the arg a field nothing else needed! with accessors 56
  • 108. Even Better... case class Person( firstName: String, lastName: String, age: Int) 57
  • 109. Even Better... case class Person( firstName: String, lastName: String, age: Int) Constructor args are automatically vals, plus other goodies. 57
  • 111. Scala’s Object Model: Traits Composable Units of Behavior 58
  • 112. We would like to compose objects from mixins. 59
  • 113. Java: What to Do? class Server extends Logger { … } 60
  • 114. Java: What to Do? class Server extends Logger { … } “Server is a Logger”? 60
  • 115. Java: What to Do? class Server extends Logger { … } “Server is a Logger”? class Server implements Logger { … } Logger isn’t an interface! 60
  • 117. Java’s object model • Good • Promotes abstractions. • Bad • No composition through reusable mixins. 61
  • 118. Traits Like interfaces with implementations, 62
  • 119. Traits … or like abstract classes + multiple inheritance (if you prefer). 63
  • 120. Logger as a Mixin: trait Logger { val level: Level // abstract def log(message: String) = { Log4J.log(level, message) } } 64
  • 121. Logger as a Mixin: trait Logger { val level: Level // abstract def log(message: String) = { Log4J.log(level, message) } } Traits don’t have constructors, but you can still define fields. 64
  • 122. Logger as a Mixin: trait Logger { val level: Level // abstract … } 65
  • 123. Logger as a Mixin: trait Logger { val level: Level // abstract … } val server = new Server(…) with Logger { val level = ERROR } server.log("Internet down!!") 65
  • 124. Logger as a Mixin: trait Logger { val level: Level // abstract … } mixed in Logging val server = new Server(…) with Logger { val level = ERROR } server.log("Internet down!!") 65
  • 125. Logger as a Mixin: trait Logger { val level: Level // abstract … } mixed in Logging val server = new Server(…) with Logger { val level = ERROR abstract } member defined server.log("Internet down!!") 65
  • 127. When you share mutable state... 67
  • 128. When you share mutable state... Hic sunt dracones (Here be dragons) 67
  • 129. Actor Model • Message passing between autonomous actors. • No shared (mutable) state. 68
  • 130. Actor Model • First developed in the 70’s by Hewitt, Agha, Hoare, etc. • Made “famous” by Erlang. • Scala’s Actors patterned after Erlang’s. 69
  • 131. 2 Actors: “self” Display draw draw ??? error! “exit” exit 70
  • 132. package shapes case class Point( x: Double, y: Double) abstract class Shape { def draw() } Hierarchy of geometric shapes 71
  • 133. package shapes case class Point( x: Double, y: Double) abstract class Shape { def draw() abstract “draw” method } Hierarchy of geometric shapes 71
  • 134. case class Circle( center:Point, radius:Double) extends Shape { def draw() = … } case class Rectangle( ll:Point, h:Double, w:Double) extends Shape { def draw() = … } 72
  • 135. case class Circle( center:Point, radius:Double) extends Shape { def draw() = … concrete “draw” } methods case class Rectangle( ll:Point, h:Double, w:Double) extends Shape { def draw() = … } 72
  • 136. package shapes import akka.actor._ class ShapeDrawingActor extends Actor { def receive = { … } } Actor for drawing shapes 73
  • 137. Use the “Akka” package shapes Actor library import akka.actor._ class ShapeDrawingActor extends Actor { def receive = { … } } Actor for drawing shapes 73
  • 138. Use the “Akka” package shapes Actor library import akka.actor._ class ShapeDrawingActor Actor extends Actor { def receive = { receive and handle … each message } } Actor for drawing shapes 73
  • 139. Receive receive = { method case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) } Actor for drawing shapes 74
  • 140. receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) } Actor for drawing shapes 75
  • 141. receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") pattern case "exit" => matching println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) } Actor for drawing shapes 75
  • 142. receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") pattern case "exit" => matching println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) } Actor for drawing shapes 75
  • 143. receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") pattern case "exit" => matching println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) } Actor for drawing shapes 75
  • 144. receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) } 76
  • 145. receive = { draw shape case s:Shape => & send reply print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) } 76
  • 146. receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") done self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) } 76
  • 147. receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) } unrecognized message 76
  • 148. receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) } 76
  • 149. package shapes import akka.actor._ class ShapeDrawingActor extends Actor { receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) } } 77
  • 150. package shapes import akka.actor._ class ShapeDrawingActor extends Actor { receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) } } Altogether 77
  • 151. import shapes._ import akka.actor._ import akka.actor.Actor object Driver { def main(args:Array[String])={ val driver = actorOf[Driver] driver.start driver ! "go!" } } class Driver … 78
  • 152. import shapes._ import akka.actor._ import akka.actor.Actor a “singleton” type to hold main object Driver { def main(args:Array[String])={ val driver = actorOf[Driver] driver.start driver ! "go!" } } class Driver … driver to try it out 78
  • 153. import shapes._ import akka.actor._ import akka.actor.Actor a “singleton” type to hold main object Driver { def main(args:Array[String])={ val driver = actorOf[Driver] driver.start driver ! "go!" } } class Driver … driver to try it out 78
  • 154. import shapes._ import akka.actor._ import akka.actor.Actor a “singleton” type to hold main object Driver { def main(args:Array[String])={ val driver = actorOf[Driver] driver.start driver ! "go!" ! is the message } send “operator” } class Driver … driver to try it out 78
  • 155. … class Driver extends Actor { val drawer = actorOf[ShapeDrawingActor] drawer.start def receive = { … } } driver to try it out 79
  • 156. Its “companion” object Driver … was on the previous slide. class Driver extends Actor { val drawer = actorOf[ShapeDrawingActor] drawer.start def receive = { … } } driver to try it out 79
  • 157. def receive = { case "go!" => drawer ! Circle(Point(…),…) drawer ! Rectangle(…) drawer ! 3.14159 drawer ! "exit" case "good bye!" => println("<- cleaning up…") drawer.stop; self.stop case other => println("<- " + other) } driver to try it out 80
  • 158. def receive = { case "go!" => sent by main drawer ! Circle(Point(…),…) drawer ! Rectangle(…) drawer ! 3.14159 drawer ! "exit" case "good bye!" => println("<- cleaning up…") drawer.stop; self.stop case other => println("<- " + other) } driver to try it out 80
  • 159. def receive = { case "go!" => sent by main drawer ! Circle(Point(…),…) drawer ! Rectangle(…) drawer ! 3.14159 drawer ! "exit" sent by case "good bye!" => drawer println("<- cleaning up…") drawer.stop; self.stop case other => println("<- " + other) } driver to try it out 80
  • 160. case "go!" => drawer ! Circle(Point(…),…) drawer ! Rectangle(…) drawer ! 3.14159 drawer ! "exit" // run Driver.main (see github README.md) -> drawing: Circle(Point(0.0,0.0),1.0) -> drawing: Rectangle(Point(0.0,0.0), 2.0,5.0) -> Error: 3.14159 -> exiting... “<-” and “->” messages <- Shape drawn. may be interleaved!! <- Shape drawn. <- Unknown: 3.14159 <- cleaning up... 81
  • 161. … // ShapeDrawingActor receive = { case s:Shape => s.draw() self.reply("…") case … case … } 82
  • 162. … // ShapeDrawingActor Functional-style receive = { pattern matching case s:Shape => s.draw() self.reply("…") case … case … } 82
  • 163. … // ShapeDrawingActor Functional-style receive = { pattern matching case s:Shape => s.draw() Object- self.reply("…") oriented-style polymorphism case … case … } “Switch” statements are not evil! 82
  • 165. Scala is... 84
  • 166. 85
  • 167. a better Java and C#, 85
  • 168. 86
  • 169. object-oriented and functional, 86
  • 170. 87
  • 171. succinct, elegant, and powerful. 87
  • 172. Thanks! dean@deanwampler.com @deanwampler polyglotprogramming.com/talks programmingscala.com thinkbiganalytics.com 88
  • 175. Example trait Queue[T] { def get(): T def put(t: T) } 91
  • 176. Example trait Queue[T] { def get(): T def put(t: T) } A pure abstraction (in this case...) 91
  • 177. Log put trait QueueLogging[T] extends Queue[T] { abstract override def put( t: T) = { println("put("+t+")") super.put(t) } } 92
  • 178. Log put trait QueueLogging[T] extends Queue[T] { abstract override def put( t: T) = { println("put("+t+")") super.put(t) } } 93
  • 179. Log put trait QueueLogging[T] extends Queue[T] { abstract override def put( t: T) = { println("put("+t+")") super.put(t) } } What is “super” bound to?? 93
  • 180. class StandardQueue[T] extends Queue[T] { import ...ArrayBuffer private val ab = new ArrayBuffer[T] def put(t: T) = ab += t def get() = ab.remove(0) … } 94
  • 181. class StandardQueue[T] extends Queue[T] { import ...ArrayBuffer private val ab = new ArrayBuffer[T] def put(t: T) = ab += t def get() = ab.remove(0) … } Concrete (boring) implementation 94
  • 182. val sq = new StandardQueue[Int] with QueueLogging[Int] sq.put(10) // #1 println(sq.get()) // #2 // => put(10) (on #1) // => 10 (on #2) 95
  • 183. val sq = new StandardQueue[Int] with QueueLogging[Int] sq.put(10) // #1 println(sq.get()) // #2 // => put(10) (on #1) // => 10 (on #2) Example use 95
  • 184. val sq = new StandardQueue[Int] with QueueLogging[Int] sq.put(10) // #1 println(sq.get()) // #2 // => put(10) (on #1) // => 10 (on #2) 96
  • 185. Mixin composition; no class required val sq = new StandardQueue[Int] with QueueLogging[Int] sq.put(10) // #1 println(sq.get()) // #2 // => put(10) (on #1) // => 10 (on #2) Example use 96
  • 186. Like Aspect-Oriented Programming? Traits give us advice, but not a join point “query” language. 97
  • 187. Traits are a powerful composition mechanism! 98
  • 189. What is Functional Programming? 100
  • 190. What is Functional Programming? Don’t we already write “functions”? 100
  • 191. y = sin(x) 101
  • 192. y = sin(x) Based on Mathematics 101
  • 193. y = sin(x) 102
  • 194. y = sin(x) Setting x fixes y ∴ variables are immutable 102
  • 195. 20 += 1 ?? 103
  • 196. 20 += 1 ?? We never modify the 20 “object” 103
  • 197. Concurrency 104
  • 198. Concurrency No mutable state ∴ nothing to synchronize 104
  • 199. When you share mutable state... 105
  • 200. When you share mutable state... Hic sunt dracones (Here be dragons) 105
  • 201. y = sin(x) 106
  • 202. y = sin(x) Functions don’t change state ∴ side-effect free 106
  • 203. Side-effect free functions • Easy to reason about behavior. • Easy to invoke concurrently. • Easy to invoke anywhere. • Encourage immutable objects. 107
  • 205. tan(Θ) = sin(Θ)/cos(Θ) Compose functions of other functions ∴ first-class citizens 108
  • 207. For “Comprehensions” val l = List( Some("a"), None, Some("b"), None, Some("c")) for (Some(s) <- l) yield s // List(a, b, c) 110
  • 208. For “Comprehensions” val l = List( Some("a"), None, Some("b"), None, Some("c")) for (Some(s) <- l) yield s // List(a, b, c) Pattern match; only take elements of “l” No “if ” statement that are Somes. 110

Notas del editor

  1. Available now from oreilly.com, Amazon, etc.
  2. I picked Scala to learn in 2007 because I wanted to learn a functional language. Scala appealed because it runs on the JVM and interoperates with Java. In the end, I was seduced by its power and flexibility.
  3. First reason, we need the benefits of FP.
  4. Java&amp;#x2019;s object model (and to a lesser extent, C#&amp;#x2018;s) has significant limitations.
  5. We think of objects as mutable and methods as state-modifying, while FP emphasizes immutability, which reduces bugs and often simplifies code. Objects don&amp;#x2019;t have to be mutable!
  6. We rarely have the luxury of starting from scratch...
  7. Odersky is the creator of Scala. He&amp;#x2019;s a prof. at EPFL in Switzerland. Many others have contributed to it, mostly his grad. students. GJ had generics, but they were disabled in javac until v1.5.
  8. Not all objects are functions, but they can be...
  9. A simple wrapper around your favorite logging library (e.g., Log4J).
  10. Note how variables are declared, &amp;#x201C;name: Type&amp;#x201D;.
  11. Note how variables are declared, &amp;#x201C;name: Type&amp;#x201D;.
  12. Note how variables are declared, &amp;#x201C;name: Type&amp;#x201D;.
  13. Note how variables are declared, &amp;#x201C;name: Type&amp;#x201D;.
  14. Note how variables are declared, &amp;#x201C;name: Type&amp;#x201D;.
  15. Note how variables are declared, &amp;#x201C;name: Type&amp;#x201D;.
  16. After creating an instance of Logger, in this case for Error logging, we can &amp;#x201C;pretend&amp;#x201D; the object is a function!
  17. After creating an instance of Logger, in this case for Error logging, we can &amp;#x201C;pretend&amp;#x201D; the object is a function!
  18. Adding a parameterized arg. list after an object causes the compiler to invoke the object&amp;#x2019;s &amp;#x201C;apply&amp;#x201D; method.
  19. Adding a parameterized arg. list after an object causes the compiler to invoke the object&amp;#x2019;s &amp;#x201C;apply&amp;#x201D; method.
  20. Adding a parameterized arg. list after an object causes the compiler to invoke the object&amp;#x2019;s &amp;#x201C;apply&amp;#x201D; method.
  21. This is how any object can be a function, if it has an apply method. Note that the signature of the argument list must match the arguments specified. Remember, this is a statically-typed language!
  22. While an object can be a function, every &amp;#x201C;bare&amp;#x201D; function is actually an object, both because this is part of the &amp;#x201C;theme&amp;#x201D; of scala&amp;#x2019;s unification of OOP and FP, but practically, because the JVM requires everything to be an object!
  23. There isn&amp;#x2019;t an object-primitive divide, at the source level, in Scala, but it optimizes to primitives to avoid boxing, where it can.
  24. We build up a literal list with the &amp;#x201C;::&amp;#x201D; cons operator to prepend elements, starting with an empty list, the Nil &amp;#x201C;object&amp;#x201D;. &amp;#x201C;::&amp;#x201D; binds to the right, so the second form shown is equivalent to the first. Note the &amp;#x201C;infix operator notation&amp;#x201D;; x.m(y) ==&gt; x m y
  25. We build up a literal list with the &amp;#x201C;::&amp;#x201D; cons operator to prepend elements, starting with an empty list, the Nil &amp;#x201C;object&amp;#x201D;. &amp;#x201C;::&amp;#x201D; binds to the right, so the second form shown is equivalent to the first. Note the &amp;#x201C;infix operator notation&amp;#x201D;; x.m(y) ==&gt; x m y
  26. We build up a literal list with the &amp;#x201C;::&amp;#x201D; cons operator to prepend elements, starting with an empty list, the Nil &amp;#x201C;object&amp;#x201D;. &amp;#x201C;::&amp;#x201D; binds to the right, so the second form shown is equivalent to the first. Note the &amp;#x201C;infix operator notation&amp;#x201D;; x.m(y) ==&gt; x m y
  27. We build up a literal list with the &amp;#x201C;::&amp;#x201D; cons operator to prepend elements, starting with an empty list, the Nil &amp;#x201C;object&amp;#x201D;. &amp;#x201C;::&amp;#x201D; binds to the right, so the second form shown is equivalent to the first. Note the &amp;#x201C;infix operator notation&amp;#x201D;; x.m(y) ==&gt; x m y
  28. We build up a literal list with the &amp;#x201C;::&amp;#x201D; cons operator to prepend elements, starting with an empty list, the Nil &amp;#x201C;object&amp;#x201D;. &amp;#x201C;::&amp;#x201D; binds to the right, so the second form shown is equivalent to the first. Note the &amp;#x201C;infix operator notation&amp;#x201D;; x.m(y) ==&gt; x m y
  29. We build up a literal list with the &amp;#x201C;::&amp;#x201D; cons operator to prepend elements, starting with an empty list, the Nil &amp;#x201C;object&amp;#x201D;. &amp;#x201C;::&amp;#x201D; binds to the right, so the second form shown is equivalent to the first. Note the &amp;#x201C;infix operator notation&amp;#x201D;; x.m(y) ==&gt; x m y
  30. We build up a literal list with the &amp;#x201C;::&amp;#x201D; cons operator to prepend elements, starting with an empty list, the Nil &amp;#x201C;object&amp;#x201D;. &amp;#x201C;::&amp;#x201D; binds to the right, so the second form shown is equivalent to the first. Note the &amp;#x201C;infix operator notation&amp;#x201D;; x.m(y) ==&gt; x m y
  31. Note the &amp;#x201C;infix operator notation&amp;#x201D;; x.m(y) ==&gt; x m y. It&amp;#x2019;s not just a special case backed into the language grammar (like Java&amp;#x2019;s special case for string addition). Rather, it&amp;#x2019;s a general feature of the language you can use for your classes.
  32. Note the &amp;#x201C;infix operator notation&amp;#x201D;; x.m(y) ==&gt; x m y. It&amp;#x2019;s not just a special case backed into the language grammar (like Java&amp;#x2019;s special case for string addition). Rather, it&amp;#x2019;s a general feature of the language you can use for your classes.
  33. Maps also have a literal syntax, which should look familiar to you Ruby programmers ;) Is this a special case in the language grammar?
  34. Scala provides mechanisms to define convenient &amp;#x201C;operators&amp;#x201D; as methods, without special exceptions baked into the grammer (e.g., strings and &amp;#x201C;+&amp;#x201D; in Java).
  35. Scala provides mechanisms to define convenient &amp;#x201C;operators&amp;#x201D; as methods, without special exceptions baked into the grammer (e.g., strings and &amp;#x201C;+&amp;#x201D; in Java).
  36. Scala provides mechanisms to define convenient &amp;#x201C;operators&amp;#x201D; as methods, without special exceptions baked into the grammer (e.g., strings and &amp;#x201C;+&amp;#x201D; in Java).
  37. Scala provides mechanisms to define convenient &amp;#x201C;operators&amp;#x201D; as methods, without special exceptions baked into the grammer (e.g., strings and &amp;#x201C;+&amp;#x201D; in Java).
  38. We won&amp;#x2019;t discuss implicit conversions here, due to time....
  39. Collections like List and Map have a set of common operations that can be used on them.
  40. Let&amp;#x2019;s map a list of strings with lower-case letters to a corresponding list of uppercase strings.
  41. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  42. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  43. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  44. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  45. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  46. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  47. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  48. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  49. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  50. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  51. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  52. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  53. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  54. Note that the function literal is just the &amp;#x201C;s =&gt; s.toUpperCase&amp;#x201D;. The {&amp;#x2026;} are used like parentheses around the argument to map, so we get a block-like syntax.
  55. We&amp;#x2019;ve used type inference, but here&amp;#x2019;s how we could be more explicit about the argument list to the function literal.
  56. We&amp;#x2019;ve used type inference, but here&amp;#x2019;s how we could be more explicit about the argument list to the function literal.
  57. We&amp;#x2019;ve used type inference, but here&amp;#x2019;s how we could be more explicit about the argument list to the function literal.
  58. Here&amp;#x2019;s the declaration of List&amp;#x2019;s map method (lots of details omitted&amp;#x2026;). Scala uses [...] for parameterized types, so you can use &amp;#x201C;&lt;&amp;#x201C; and &amp;#x201C;&gt;&amp;#x201D; for method names!
  59. Here&amp;#x2019;s the declaration of List&amp;#x2019;s map method (lots of details omitted&amp;#x2026;). Scala uses [...] for parameterized types, so you can use &amp;#x201C;&lt;&amp;#x201C; and &amp;#x201C;&gt;&amp;#x201D; for method names!
  60. Here&amp;#x2019;s the declaration of List&amp;#x2019;s map method (lots of details omitted&amp;#x2026;). Scala uses [...] for parameterized types, so you can use &amp;#x201C;&lt;&amp;#x201C; and &amp;#x201C;&gt;&amp;#x201D; for method names!
  61. Here&amp;#x2019;s the declaration of List&amp;#x2019;s map method (lots of details omitted&amp;#x2026;). Scala uses [...] for parameterized types, so you can use &amp;#x201C;&lt;&amp;#x201C; and &amp;#x201C;&gt;&amp;#x201D; for method names!
  62. Here&amp;#x2019;s the declaration of List&amp;#x2019;s map method (lots of details omitted&amp;#x2026;). Scala uses [...] for parameterized types, so you can use &amp;#x201C;&lt;&amp;#x201C; and &amp;#x201C;&gt;&amp;#x201D; for method names!
  63. We look at the actual implementation of Function1 (or any FunctionN). Note that the scaladocs have links to the actual source listings. (We&amp;#x2019;re omitting some details&amp;#x2026;) The trait declares an abstract method &amp;#x201C;apply&amp;#x201D; (i.e., it doesn&amp;#x2019;t also define the method.) Traits are a special kind of abstract class/interface definition, that promote &amp;#x201C;mixin composition&amp;#x201D;. (We won&amp;#x2019;t have time to discuss&amp;#x2026;)
  64. We look at the actual implementation of Function1 (or any FunctionN). Note that the scaladocs have links to the actual source listings. (We&amp;#x2019;re omitting some details&amp;#x2026;) The trait declares an abstract method &amp;#x201C;apply&amp;#x201D; (i.e., it doesn&amp;#x2019;t also define the method.) Traits are a special kind of abstract class/interface definition, that promote &amp;#x201C;mixin composition&amp;#x201D;. (We won&amp;#x2019;t have time to discuss&amp;#x2026;)
  65. We look at the actual implementation of Function1 (or any FunctionN). Note that the scaladocs have links to the actual source listings. (We&amp;#x2019;re omitting some details&amp;#x2026;) The trait declares an abstract method &amp;#x201C;apply&amp;#x201D; (i.e., it doesn&amp;#x2019;t also define the method.) Traits are a special kind of abstract class/interface definition, that promote &amp;#x201C;mixin composition&amp;#x201D;. (We won&amp;#x2019;t have time to discuss&amp;#x2026;)
  66. You use the function literal syntax and the compiler instantiates an anonymous class using the corresponding FunctionN trait, with a concrete definition of apply provided by your function literal.
  67. You use the function literal syntax and the compiler instantiates an anonymous class using the corresponding FunctionN trait, with a concrete definition of apply provided by your function literal.
  68. You use the function literal syntax and the compiler instantiates an anonymous class using the corresponding FunctionN trait, with a concrete definition of apply provided by your function literal.
  69. You use the function literal syntax and the compiler instantiates an anonymous class using the corresponding FunctionN trait, with a concrete definition of apply provided by your function literal.
  70. You use the function literal syntax and the compiler instantiates an anonymous class using the corresponding FunctionN trait, with a concrete definition of apply provided by your function literal.
  71. Back to where we started. Note again that we can use &amp;#x201C;{&amp;#x2026;}&amp;#x201D; instead of &amp;#x201C;(&amp;#x2026;)&amp;#x201D; for the argument list (i.e., the single function) to map. Why, to get a nice block-like syntax.
  72. Back to where we started. Note again that we can use &amp;#x201C;{&amp;#x2026;}&amp;#x201D; instead of &amp;#x201C;(&amp;#x2026;)&amp;#x201D; for the argument list (i.e., the single function) to map. Why, to get a nice block-like syntax.
  73. Back to where we started. Note again that we can use &amp;#x201C;{&amp;#x2026;}&amp;#x201D; instead of &amp;#x201C;(&amp;#x2026;)&amp;#x201D; for the argument list (i.e., the single function) to map. Why, to get a nice block-like syntax.
  74. Our functions can have state! Not the usual thing for FP-style functions, where functions are usually side-effect free, but you have this option. Note that this is like a normal closure in FP.
  75. Our functions can have state! Not the usual thing for FP-style functions, where functions are usually side-effect free, but you have this option. Note that this is like a normal closure in FP.
  76. We&amp;#x2019;ve seen a lot of syntax. Let&amp;#x2019;s recap a few of the ways Scala keeps your code succinct.
  77. Syntactic sugar: obj.operation(arg) == obj operation arg
  78. Syntactic sugar: obj.operation(arg) == obj operation arg
  79. Java (and to a lesser extent C#) require explicit type &amp;#x201C;annotations&amp;#x201D; on all references, method arguments, etc., leading to redundancy and noise. Note that Scala use [] rather than &lt;&gt;, so you can use &amp;#x201C;&lt;&amp;#x201C; and &amp;#x201C;&gt;&amp;#x201D; as method names!
  80. Java (and to a lesser extent C#) require explicit type &amp;#x201C;annotations&amp;#x201D; on all references, method arguments, etc., leading to redundancy and noise. Note that Scala use [] rather than &lt;&gt;, so you can use &amp;#x201C;&lt;&amp;#x201C; and &amp;#x201C;&gt;&amp;#x201D; as method names!
  81. Java (and to a lesser extent C#) require explicit type &amp;#x201C;annotations&amp;#x201D; on all references, method arguments, etc., leading to redundancy and noise. Note that Scala use [] rather than &lt;&gt;, so you can use &amp;#x201C;&lt;&amp;#x201C; and &amp;#x201C;&gt;&amp;#x201D; as method names!
  82. Java (and to a lesser extent C#) require explicit type &amp;#x201C;annotations&amp;#x201D; on all references, method arguments, etc., leading to redundancy and noise. Note that Scala use [] rather than &lt;&gt;, so you can use &amp;#x201C;&lt;&amp;#x201C; and &amp;#x201C;&gt;&amp;#x201D; as method names!
  83. Java (and to a lesser extent C#) require explicit type &amp;#x201C;annotations&amp;#x201D; on all references, method arguments, etc., leading to redundancy and noise. Note that Scala use [] rather than &lt;&gt;, so you can use &amp;#x201C;&lt;&amp;#x201C; and &amp;#x201C;&gt;&amp;#x201D; as method names!
  84. Other things aren&amp;#x2019;t needed...
  85. Other things aren&amp;#x2019;t needed...
  86. Factory methods on the cheap...
  87. Factory methods on the cheap...
  88. Typical Java boilerplate for a simple &amp;#x201C;struct-like&amp;#x201D; class. Deliberately too small to read...
  89. Scala is much more succinct. It eliminates a lot of boilerplate.
  90. Scala is much more succinct. It eliminates a lot of boilerplate.
  91. Scala is much more succinct. It eliminates a lot of boilerplate.
  92. Scala is much more succinct. It eliminates a lot of boilerplate.
  93. Scala is much more succinct. It eliminates a lot of boilerplate.
  94. Scala is much more succinct. It eliminates a lot of boilerplate.
  95. Scala is much more succinct. It eliminates a lot of boilerplate.
  96. Scala is much more succinct. It eliminates a lot of boilerplate.
  97. Scala is much more succinct. It eliminates a lot of boilerplate.
  98. Note that Scala does not define an argument list for &amp;#x201C;firstName&amp;#x201D;, so you can call this method as if it were a bare field access. The client doesn&amp;#x2019;t need to know the difference!
  99. Note that Scala does not define an argument list for &amp;#x201C;firstName&amp;#x201D;, so you can call this method as if it were a bare field access. The client doesn&amp;#x2019;t need to know the difference!
  100. Case classes also get equals, hashCode, toString, and the &amp;#x201C;factory&amp;#x201D; method we&amp;#x2019;ve mentioned (e.g., for List and Map) that, by default, creates an instance of the type without the &amp;#x201C;new&amp;#x201D;. We&amp;#x2019;ll see more about case classes later.
  101. Fixes limitations of Java&amp;#x2019;s object model.
  102. Made-up example Java type.
  103. Made-up example Java type.
  104. Made-up example Java type.
  105. Chances are, the &amp;#x201C;logging&amp;#x201D; and &amp;#x201C;filtering&amp;#x201D; behaviors are reusable, yet Java provides no built-in way to &amp;#x201C;mix-in&amp;#x201D; reusable implementations. Ad hoc mechanisms must be used.
  106. Chances are, the &amp;#x201C;logging&amp;#x201D; and &amp;#x201C;filtering&amp;#x201D; behaviors are reusable, yet Java provides no built-in way to &amp;#x201C;mix-in&amp;#x201D; reusable implementations. Ad hoc mechanisms must be used.
  107. One way to compare traits to what you know...
  108. &amp;#x2026; and another way.
  109. I changed some details compared to our original Logger example, e.g., no &amp;#x201C;level&amp;#x201D; field. Mix in Logger.
  110. I changed some details compared to our original Logger example, e.g., no &amp;#x201C;level&amp;#x201D; field. Mix in Logger.
  111. I changed some details compared to our original Logger example, e.g., no &amp;#x201C;level&amp;#x201D; field. Mix in Logger.
  112. FP is going mainstream because it is the best way to write robust concurrent software. Here&amp;#x2019;s an example...
  113. It&amp;#x2019;s very hard to do multithreaded programming robustly. We need higher levels of abstraction, like Actors.
  114. It&amp;#x2019;s very hard to do multithreaded programming robustly. We need higher levels of abstraction, like Actors.
  115. The actor model is not new!!
  116. Our example. An actor for drawing geometric shapes and another actor that drives it.
  117. &amp;#x201C;Case&amp;#x201D; classes for 2-dim. points and a hierarchy of shapes. Note the abstract draw method in Shape. The &amp;#x201C;case&amp;#x201D; keyword makes the arguments &amp;#x201C;vals&amp;#x201D; by default, adds factory, equals, etc. methods. Great for &amp;#x201C;structural&amp;#x201D; objects. (Case classes automatically get generated equals, hashCode, toString, so-called &amp;#x201C;apply&amp;#x201D; factory methods - so you don&amp;#x2019;t need &amp;#x201C;new&amp;#x201D; - and so-called &amp;#x201C;unapply&amp;#x201D; methods used for pattern matching.)
  118. &amp;#x201C;Case&amp;#x201D; classes for 2-dim. points and a hierarchy of shapes. Note the abstract draw method in Shape. The &amp;#x201C;case&amp;#x201D; keyword makes the arguments &amp;#x201C;vals&amp;#x201D; by default, adds factory, equals, etc. methods. Great for &amp;#x201C;structural&amp;#x201D; objects. (Case classes automatically get generated equals, hashCode, toString, so-called &amp;#x201C;apply&amp;#x201D; factory methods - so you don&amp;#x2019;t need &amp;#x201C;new&amp;#x201D; - and so-called &amp;#x201C;unapply&amp;#x201D; methods used for pattern matching.)
  119. Case classes for 2-dim. points and a hierarchy of shapes. Note the abstract draw method in Shape. For our example, the draw methods will just do &amp;#x201C;println(this.toString)&amp;#x201D;.
  120. Case classes for 2-dim. points and a hierarchy of shapes. Note the abstract draw method in Shape. For our example, the draw methods will just do &amp;#x201C;println(this.toString)&amp;#x201D;.
  121. Case classes for 2-dim. points and a hierarchy of shapes. Note the abstract draw method in Shape. For our example, the draw methods will just do &amp;#x201C;println(this.toString)&amp;#x201D;.
  122. An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received... Note: This example uses Scala&amp;#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
  123. An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received... Note: This example uses Scala&amp;#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
  124. An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received... Note: This example uses Scala&amp;#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
  125. An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received... Note: This example uses Scala&amp;#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
  126. An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received... Note: This example uses Scala&amp;#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
  127. An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received... Note: This example uses Scala&amp;#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
  128. An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received... Note: This example uses Scala&amp;#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
  129. An actor that waits for messages containing shapes to draw. Imagine this is the window manager on your computer. It loops indefinitely, blocking until a new message is received... Note: This example uses Scala&amp;#x2019;s built in Actor library, but there are others have some advantages. See for example, akkasource.org.
  130. &amp;#x201C;Receive&amp;#x201D; blocks until a message is received. Then it does a pattern match on the message. In this case, looking for a Shape object, the &amp;#x201C;exit&amp;#x201D; message, or an unexpected object, handled with the last case, the default.
  131. Each pattern is tested and the first match &amp;#x201C;wins&amp;#x201D;. The messages we expect are a Shape object, the &amp;#x201C;exit&amp;#x201D; string or anything else. Hence, the last &amp;#x201C;case&amp;#x201D; is a &amp;#x201C;default&amp;#x201D; that catches anything, we we treat as an unexpected error.
  132. Each pattern is tested and the first match &amp;#x201C;wins&amp;#x201D;. The messages we expect are a Shape object, the &amp;#x201C;exit&amp;#x201D; string or anything else. Hence, the last &amp;#x201C;case&amp;#x201D; is a &amp;#x201C;default&amp;#x201D; that catches anything, we we treat as an unexpected error.
  133. Each pattern is tested and the first match &amp;#x201C;wins&amp;#x201D;. The messages we expect are a Shape object, the &amp;#x201C;exit&amp;#x201D; string or anything else. Hence, the last &amp;#x201C;case&amp;#x201D; is a &amp;#x201C;default&amp;#x201D; that catches anything, we we treat as an unexpected error.
  134. Each pattern is tested and the first match &amp;#x201C;wins&amp;#x201D;. The messages we expect are a Shape object, the &amp;#x201C;exit&amp;#x201D; string or anything else. Hence, the last &amp;#x201C;case&amp;#x201D; is a &amp;#x201C;default&amp;#x201D; that catches anything, we we treat as an unexpected error.
  135. Each pattern is tested and the first match &amp;#x201C;wins&amp;#x201D;. The messages we expect are a Shape object, the &amp;#x201C;exit&amp;#x201D; string or anything else. Hence, the last &amp;#x201C;case&amp;#x201D; is a &amp;#x201C;default&amp;#x201D; that catches anything, we we treat as an unexpected error.
  136. Each pattern is tested and the first match &amp;#x201C;wins&amp;#x201D;. The messages we expect are a Shape object, the &amp;#x201C;exit&amp;#x201D; string or anything else. Hence, the last &amp;#x201C;case&amp;#x201D; is a &amp;#x201C;default&amp;#x201D; that catches anything, we we treat as an unexpected error.
  137. Each pattern is tested and the first match &amp;#x201C;wins&amp;#x201D;. The messages we expect are a Shape object, the &amp;#x201C;exit&amp;#x201D; string or anything else. Hence, the last &amp;#x201C;case&amp;#x201D; is a &amp;#x201C;default&amp;#x201D; that catches anything, we we treat as an unexpected error.
  138. After handling each message, a response is sent to the sender, which we get by calling the &amp;#x201C;sender&amp;#x201D; method. The &amp;#x201C;!&amp;#x201D; is the message send method (from Erlang).
  139. After handling each message, a response is sent to the sender, which we get by calling the &amp;#x201C;sender&amp;#x201D; method. The &amp;#x201C;!&amp;#x201D; is the message send method (from Erlang).
  140. After handling each message, a response is sent to the sender, which we get by calling the &amp;#x201C;sender&amp;#x201D; method. The &amp;#x201C;!&amp;#x201D; is the message send method (from Erlang).
  141. After handling each message, a response is sent to the sender, which we get by calling the &amp;#x201C;sender&amp;#x201D; method. The &amp;#x201C;!&amp;#x201D; is the message send method (from Erlang).
  142. After handling each message, a response is sent to the sender, which we get by calling the &amp;#x201C;sender&amp;#x201D; method. The &amp;#x201C;!&amp;#x201D; is the message send method (from Erlang).
  143. After handling each message, a response is sent to the sender, which we get by calling the &amp;#x201C;sender&amp;#x201D; method. The &amp;#x201C;!&amp;#x201D; is the message send method (from Erlang).
  144. After handling each message, a response is sent to the sender, which we get by calling the &amp;#x201C;sender&amp;#x201D; method. The &amp;#x201C;!&amp;#x201D; is the message send method (from Erlang).
  145. The whole thing, with &amp;#x201C;elided&amp;#x201D; imports and other edits, so it would fit. It looks busy on a presentation slide, but isn&amp;#x2019;t a lot of code in an editor!
  146. Here&amp;#x2019;s the driver actor, a scala script (precompilation not required) to drive the drawing actor. Normally, you would not do such synchronous call and response coding, if avoidable, as it defeats the purpose of using actors for concurrency.
  147. The &amp;#x201C;!&amp;#x201D; method sends a message. Then we wait for a reply. In our receive method, we match on any &amp;#x201C;reply&amp;#x201D; and just print it. This script uses the method &amp;#x201C;self&amp;#x201D; to get the actor corresponding to &amp;#x201C;me&amp;#x201D;.
  148. The &amp;#x201C;!&amp;#x201D; method sends a message. Then we wait for a reply. In our receive method, we match on any &amp;#x201C;reply&amp;#x201D; and just print it. This script uses the method &amp;#x201C;self&amp;#x201D; to get the actor corresponding to &amp;#x201C;me&amp;#x201D;.
  149. The &amp;#x201C;!&amp;#x201D; method sends a message. Then we wait for a reply. In our receive method, we match on any &amp;#x201C;reply&amp;#x201D; and just print it. This script uses the method &amp;#x201C;self&amp;#x201D; to get the actor corresponding to &amp;#x201C;me&amp;#x201D;.
  150. The &amp;#x201C;!&amp;#x201D; method sends a message. Then we wait for a reply. In our receive method, we match on any &amp;#x201C;reply&amp;#x201D; and just print it. This script uses the method &amp;#x201C;self&amp;#x201D; to get the actor corresponding to &amp;#x201C;me&amp;#x201D;.
  151. The &amp;#x201C;!&amp;#x201D; method sends a message. Then we wait for a reply. In our receive method, we match on any &amp;#x201C;reply&amp;#x201D; and just print it. This script uses the method &amp;#x201C;self&amp;#x201D; to get the actor corresponding to &amp;#x201C;me&amp;#x201D;.
  152. Start the drawing actor, then send it four messages. The blue shows what gets printed (after the &amp;#x201C;// =&gt; &amp;#x201C;).
  153. 1st message and response.
  154. 2nd message and response.
  155. 3rd message and response.
  156. 4th message and response.
  157. The power of combining the best features of FP (pattern matching and &amp;#x201C;destructuring&amp;#x201D;) and OOP (polymorphic behavior).
  158. The power of combining the best features of FP (pattern matching and &amp;#x201C;destructuring&amp;#x201D;) and OOP (polymorphic behavior).
  159. The power of combining the best features of FP (pattern matching and &amp;#x201C;destructuring&amp;#x201D;) and OOP (polymorphic behavior).
  160. The power of combining the best features of FP (pattern matching and &amp;#x201C;destructuring&amp;#x201D;) and OOP (polymorphic behavior).
  161. A very simple abstraction for a Queue.
  162. (We&amp;#x2019;re ignoring &amp;#x201C;get&amp;#x201D;&amp;#x2026;) &amp;#x201C;Super&amp;#x201D; is not yet bound, because the &amp;#x201C;super.put(t)&amp;#x201D; so far could only call the abstract method in Logging, which is not allowed. Therefore, &amp;#x201C;super&amp;#x201D; will be bound &amp;#x201C;later&amp;#x201D;, as we&amp;#x2019;ll so. So, this method is STILL abstract and it&amp;#x2019;s going to override a concrete &amp;#x201C;put&amp;#x201D; &amp;#x201C;real soon now&amp;#x201D;.
  163. (We&amp;#x2019;re ignoring &amp;#x201C;get&amp;#x201D;&amp;#x2026;) &amp;#x201C;Super&amp;#x201D; is not yet bound, because the &amp;#x201C;super.put(t)&amp;#x201D; so far could only call the abstract method in Logging, which is not allowed. Therefore, &amp;#x201C;super&amp;#x201D; will be bound &amp;#x201C;later&amp;#x201D;, as we&amp;#x2019;ll so. So, this method is STILL abstract and it&amp;#x2019;s going to override a concrete &amp;#x201C;put&amp;#x201D; &amp;#x201C;real soon now&amp;#x201D;.
  164. (We&amp;#x2019;re ignoring &amp;#x201C;get&amp;#x201D;&amp;#x2026;) &amp;#x201C;Super&amp;#x201D; is not yet bound, because the &amp;#x201C;super.put(t)&amp;#x201D; so far could only call the abstract method in Logging, which is not allowed. Therefore, &amp;#x201C;super&amp;#x201D; will be bound &amp;#x201C;later&amp;#x201D;, as we&amp;#x2019;ll so. So, this method is STILL abstract and it&amp;#x2019;s going to override a concrete &amp;#x201C;put&amp;#x201D; &amp;#x201C;real soon now&amp;#x201D;.
  165. (We&amp;#x2019;re ignoring &amp;#x201C;get&amp;#x201D;&amp;#x2026;) &amp;#x201C;Super&amp;#x201D; is not yet bound, because the &amp;#x201C;super.put(t)&amp;#x201D; so far could only call the abstract method in Logging, which is not allowed. Therefore, &amp;#x201C;super&amp;#x201D; will be bound &amp;#x201C;later&amp;#x201D;, as we&amp;#x2019;ll so. So, this method is STILL abstract and it&amp;#x2019;s going to override a concrete &amp;#x201C;put&amp;#x201D; &amp;#x201C;real soon now&amp;#x201D;.
  166. (We&amp;#x2019;re ignoring &amp;#x201C;get&amp;#x201D;&amp;#x2026;) &amp;#x201C;Super&amp;#x201D; is not yet bound, because the &amp;#x201C;super.put(t)&amp;#x201D; so far could only call the abstract method in Logging, which is not allowed. Therefore, &amp;#x201C;super&amp;#x201D; will be bound &amp;#x201C;later&amp;#x201D;, as we&amp;#x2019;ll so. So, this method is STILL abstract and it&amp;#x2019;s going to override a concrete &amp;#x201C;put&amp;#x201D; &amp;#x201C;real soon now&amp;#x201D;.
  167. Our concrete class. We import scala.collection.mutable.ArrayBuffer wherever we want, in this case, right were it&amp;#x2019;s used. This is boring; it&amp;#x2019;s just a vehicle for the cool traits stuff...
  168. We instantiate StandardQueue AND mixin the trait. We could also declare a class that mixes in the trait. The &amp;#x201C;put(10)&amp;#x201D; output comes from QueueLogging.put. So &amp;#x201C;super&amp;#x201D; is StandardQueue.
  169. We instantiate StandardQueue AND mixin the trait. We could also declare a class that mixes in the trait. The &amp;#x201C;put(10)&amp;#x201D; output comes from QueueLogging.put. So &amp;#x201C;super&amp;#x201D; is StandardQueue.
  170. We instantiate StandardQueue AND mixin the trait. We could also declare a class that mixes in the trait. The &amp;#x201C;put(10)&amp;#x201D; output comes from QueueLogging.put. So &amp;#x201C;super&amp;#x201D; is StandardQueue.
  171. We instantiate StandardQueue AND mixin the trait. We could also declare a class that mixes in the trait. The &amp;#x201C;put(10)&amp;#x201D; output comes from QueueLogging.put. So &amp;#x201C;super&amp;#x201D; is StandardQueue.
  172. We instantiate StandardQueue AND mixin the trait. We could also declare a class that mixes in the trait. The &amp;#x201C;put(10)&amp;#x201D; output comes from QueueLogging.put. So &amp;#x201C;super&amp;#x201D; is StandardQueue.
  173. We instantiate StandardQueue AND mixin the trait. We could also declare a class that mixes in the trait. The &amp;#x201C;put(10)&amp;#x201D; output comes from QueueLogging.put. So &amp;#x201C;super&amp;#x201D; is StandardQueue.
  174. If you know AspectJ or Spring AOP, traits make it easy to implement &amp;#x201C;advice&amp;#x201D;, but there is no join point language for querying over the set of all possible join points, like a real AOP framework provides.
  175. Not shown, nesting of traits...
  176. Syntactic sugar: obj.operation(arg) == obj operation arg
  177. Syntactic sugar: obj.operation(arg) == obj operation arg
  178. Syntactic sugar: obj.operation(arg) == obj operation arg
  179. If I put the &amp;#x201C;(n, line) =&gt;&amp;#x201D; on the same line as the &amp;#x201C;{&amp;#x201C;, it would look like a Ruby block.
  180. Here&amp;#x2019;s the code that implements loop...
  181. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  182. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  183. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  184. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  185. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  186. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  187. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  188. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  189. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  190. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  191. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  192. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  193. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  194. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  195. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  196. Singleton &amp;#x201C;objects&amp;#x201D; replace Java statics (or Ruby class methods and attributes). As written, &amp;#x201C;loop&amp;#x201D; takes two parameters, the file to &amp;#x201C;numberate&amp;#x201D; and a the function that takes the line number and the corresponding line, does something, and returns Unit. User&amp;#x2019;s specify what to do through &amp;#x201C;f&amp;#x201D;.
  197. The oval highlights the comma separating the two parameters in the list. Watch what we do on the next slide...
  198. We convert the single, two parameter list to two, single parameter lists, which is valid syntax.
  199. Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}. Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
  200. Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}. Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
  201. Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}. Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
  202. Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}. Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
  203. Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}. Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
  204. Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}. Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
  205. Having two, single-item parameter lists, rather than one, two-item list, is necessary to allow the syntax shown here. The first parameter list is (file), while the second is {function literal}. Note that we have to import the loop method (like a static import in Java). Otherwise, we could write Loop.loop.
  206. Finishing the implementation, loop creates a buffered reader, then calls a recursive, nested method &quot;doLoop&quot;.
  207. Finishing the implementation, loop creates a buffered reader, then calls a recursive, nested method &quot;doLoop&quot;.
  208. Finishing the implementation, loop creates a buffered reader, then calls a recursive, nested method &quot;doLoop&quot;.
  209. Here is the nested method, doLoop.
  210. Here is the nested method, doLoop.
  211. Here is the nested method, doLoop.
  212. Here is the nested method, doLoop.
  213. A tail recursion - the recursive call is the last thing done in the function (or branch).
  214. &amp;#x201C;Functional Programming&amp;#x201D; is based on the behavior of mathematical functions and variables.
  215. &amp;#x201C;Functional Programming&amp;#x201D; is based on the behavior of mathematical functions. &amp;#x201C;Variables&amp;#x201D; are actually immutable values.
  216. &amp;#x201C;Functional Programming&amp;#x201D; is based on the behavior of mathematical functions. &amp;#x201C;Variables&amp;#x201D; are actually immutable values.
  217. FP is breaking out of the academic world, because it offers a better way to approach concurrency, which is becoming ubiquitous.
  218. FP is breaking out of the academic world, because it offers a better way to approach concurrency, which is becoming ubiquitous.
  219. A math function doesn&amp;#x2019;t change any &amp;#x201C;object&amp;#x201D; or global state. All the work it does is returned by the function. This property is called &amp;#x201C;referential transparency&amp;#x201D;.
  220. A math function doesn&amp;#x2019;t change any &amp;#x201C;object&amp;#x201D; or global state. All the work it does is returned by the function. This property is called &amp;#x201C;referential transparency&amp;#x201D;.
  221. side-effect free functions are far less likely to introduce subtle integration bugs, especially in concurrent systems. By encouraging immutable objects (e.g., when methods return new objects, rather than modify existing ones), that improves concurrency robustness.
  222. Function are &amp;#x201C;first-class citizens&amp;#x201D;; you can assign them to variables and pass them to other (higher-order) functions, giving you composable behavior.
  223. Function are &amp;#x201C;first-class citizens&amp;#x201D;; you can assign them to variables and pass them to other (higher-order) functions, giving you composable behavior.
  224. FP is going mainstream because it is the best way to write robust concurrent software. Here&amp;#x2019;s an example...
  225. I am omitting MANY details. You can&amp;#x2019;t instantiate Option, which is an abstraction for a container/collection with 0 or 1 item. If you have one, it is in a Some, which must be a class, since it has an instance field, the item. However, None, used when there are 0 items, can be a singleton object, because it has no state! Note that type parameter for the parent Option. In the type system, Nothing is a subclass of all other types, so it substitutes for instances of all other types. This combined with a proper called covariant subtyping means that you could write &amp;#x201C;val x: Option[String = None&amp;#x201D; it would type correctly, as None (and Option[Nothing]) is a subtype of Option[String].
  226. I am omitting MANY details. You can&amp;#x2019;t instantiate Option, which is an abstraction for a container/collection with 0 or 1 item. If you have one, it is in a Some, which must be a class, since it has an instance field, the item. However, None, used when there are 0 items, can be a singleton object, because it has no state! Note that type parameter for the parent Option. In the type system, Nothing is a subclass of all other types, so it substitutes for instances of all other types. This combined with a proper called covariant subtyping means that you could write &amp;#x201C;val x: Option[String = None&amp;#x201D; it would type correctly, as None (and Option[Nothing]) is a subtype of Option[String].
  227. Returning Option tells the user that &amp;#x201C;there may not be a value&amp;#x201D; and forces proper handling, thereby drastically reducing sloppy code leading to NullPointerExceptions.
  228. Returning Option tells the user that &amp;#x201C;there may not be a value&amp;#x201D; and forces proper handling, thereby drastically reducing sloppy code leading to NullPointerExceptions.
  229. Returning Option tells the user that &amp;#x201C;there may not be a value&amp;#x201D; and forces proper handling, thereby drastically reducing sloppy code leading to NullPointerExceptions.
  230. We&amp;#x2019;re using the type system and pattern matching built into case classes to discriminate elements in the list. No conditional statements required. This is just the tip of the iceberg of what &amp;#x201C;for comprehensions&amp;#x201D; can do and not only with Options, but other containers, too.
  231. We&amp;#x2019;re using the type system and pattern matching built into case classes to discriminate elements in the list. No conditional statements required. This is just the tip of the iceberg of what &amp;#x201C;for comprehensions&amp;#x201D; can do and not only with Options, but other containers, too.
  232. We&amp;#x2019;re using the type system and pattern matching built into case classes to discriminate elements in the list. No conditional statements required. This is just the tip of the iceberg of what &amp;#x201C;for comprehensions&amp;#x201D; can do and not only with Options, but other containers, too.