SlideShare une entreprise Scribd logo
1  sur  77
Practically Functional
Daniel Spiewak
whoami
 Author of Scala for Java Refugees
  and other articles on Scala and FP
 Former editor Javalobby / EclipseZone
 Engaged in academic research
  involving Scala DSLs and text parsing
  (ScalaBison, GLL
  Combinators, ScalaQL)
Agenda
 Define “functional programming” (sort
  of)
 See some common elements of FP
 Motivate why this stuff is useful in the
  real world (hopefully)
 Show practical functional techniques
  and design patterns
 Explain monads!
 Hopefully pique your interest in
  learning and applying more of this
Definitions
   Q: What is “functional programming”?
Definitions
   Q: What is “functional programming”?
    ◦ A: Nobody knows!
Definitions
   Q: What is “purely-functional”?
Definitions
   Q: What is “purely-functional”?
    ◦ Everything is immutable (no variables)
Definitions
   Q: What is “purely-functional”?
    ◦ Everything is immutable (no variables)
    ◦ Absolutely no side-effects

     println(quot;Hello, World!quot;)
Definitions
   Q: What is “purely-functional”?
    ◦ Everything is immutable (no variables)
    ◦ Absolutely no side-effects
    ◦ Referential transparency
Definitions
   Q: What is “purely-functional”?
    ◦   Everything is immutable (no variables)
    ◦   Absolutely no side-effects
    ◦   Referential transparency
    ◦   Bondage discipline?
Definitions
   Scala is not purely-functional
    ◦ vars
    ◦ Mutable collections
    ◦ Uncontrolled side-effects (println)
Definitions
   Scala is not purely-functional
    ◦ vars
    ◦ Mutable collections
    ◦ Uncontrolled side-effects (println)
   Is Scala a “functional language”?
Functional Trademarks
   Higher-order functions

    def foreach(f: String=>Unit) {
      f(quot;Whatquot;)
      f(quot;isquot;)
      f(quot;goingquot;)
      f(quot;on?quot;)
    }
Functional Trademarks
   Higher-order functions

    foreach { s => println(s) }
Functional Trademarks
 Higher-order functions
 Closures are anonymous functions
    ◦ Ruby, Groovy, Python; none of these
      count!

    foreach(println)
Functional Trademarks
 Higher-order functions
 Closures are anonymous functions
    ◦ Ruby, Groovy, Python; none of these
      count!
   Singly-linked immutable lists (cons
    cells)

    val names = quot;Chrisquot; :: quot;Joequot; :: Nil
    val names2 = quot;Danielquot; :: names
Functional Trademarks
 Higher-order functions
 Closures are anonymous functions
    ◦ Ruby, Groovy, Python; none of these
      count!
 Singly-linked immutable lists (cons
  cells)
 Usually some form of type-inference

    val me = quot;Danielquot;
    // equivalent to...
    val me: String = quot;Danielquot;
Functional Trademarks
 Higher-order functions
 Closures are anonymous functions
    ◦ Ruby, Groovy, Python; none of these
      count!
 Singly-linked immutable lists (cons
  cells)
 Usually some form of type-inference

    foreach { s => println(s) }
Functional Trademarks
 Higher-order functions
 Closures are anonymous functions
    ◦ Ruby, Groovy, Python; none of these
      count!
 Singly-linked immutable lists (cons
  cells)
 Usually some form of type-inference
 Immutable by default (or encouraged)

    val me = quot;Danielquot;
    var me = quot;Danielquot;
What does this buy you?
 Modularity (separation of concerns)
 Understandability
 No more “spooky action at a distance”
…
What does this buy you?
public class Company {
    private List<Person> employees;

    public List<Person> getEmployees() {
        return employees;
    }

    public void addEmployee(Person p) {
        if (p.isAlive()) {
            employees.add(p);
        }
    }
}
What does this buy you?
 Modularity (separation of concerns)
 Understandability
 No more “spooky action at a distance”
 Flexible libraries (more on this later)
 Syntactic power (internal DSLs)
What does this buy you?
quot;vectorquot; should {
    quot;store a single elementquot; in {
        val prop = forAll { (i: Int, e: Int) =>
            i >= 0 ==> { (vector(0) = e)(0) mustEqual e }
        }


        prop must pass
    }


    quot;implement lengthquot; in {
        val prop = forAll { list: List[Int] =>
            val vec = Vector(list:_*)
            vec.length mustEqual list.length
        }


        prop must pass
    }
}
Functional Idioms
   Recursion instead of loops
    ◦ Scala helps with this by allowing methods
      within methods
Functional Idioms
   Recursion instead of loops
    ◦ Scala helps with this by allowing methods
      within methods
    def factorial(n: Int) = {
      var back = 1
      for (i <- 1 to n) {
        back *= i
      }
      back
    }
Functional Idioms
   Recursion instead of loops
    ◦ Scala helps with this by allowing methods
      within methods
    def factorial(n: Int): Int = {
      if (n == 1)
        1
      else
        n * factorial(n - 1)
    }
Functional Idioms
   Recursion instead of loops
    ◦ Scala helps with this by allowing methods
      within methods
    def factorial(n: Int) = {
      def loop(n: Int, acc: Int): Int = {
        if (n == 1)
          acc
        else
          loop(n - 1, acc * n)
      }

        loop(n, 1)
    }
Functional Idioms
   Recursion instead of loops
    ◦ Scala helps with this by allowing methods
      within methods
   Higher-order functions instead of
    recursion
Functional Idioms
   Recursion instead of loops
    ◦ Scala helps with this by allowing methods
      within methods
 Higher-order functions instead of
  recursion
 Combinators instead of higher-order
  functions
Functional Idioms
   Recursion instead of loops
    ◦ Scala helps with this by allowing methods
      within methods
 Higher-order functions instead of
  recursion
 Combinators instead of higher-order
  functions
 Monads!
Example #1
Retrieve structured, formatted data from
 across multiple .properties files
 and multiple keys within those files.

# daniel.properties   # tim.properties

name.first = Daniel   name.first = Timothy
name.last = Spiewak   name.last = Olmsted
age = 21              age = 22
Example #1
   Using loops
def toInt(s: String) = try {
  s.toInt
} catch {
  case _ => null
}

// uninteresting and ugly
def readFile(file: String): Map[String, String] = {
  import collection.jcl.Hashtable

    try {
      val is = new BufferedInputStream(new FileInputStream(file))

     val p = new Properties
     p.load(is)

     is.close()

      new Hashtable(p).asInstanceOf[Hashtable[String, String]]
    } catch {
      case _ => null
    }
}
import collection.mutable.ListBuffer

def readPeople(files: List[String]): List[Person] = {
  val back = new ListBuffer[Person]

    for (file <- files) {
      val props = readFile(file)

        if (props != null) {
          if (props.contains(quot;name.firstquot;) &&
              props.contains(quot;name.lastquot;) &&
              props.contains(quot;agequot;)) {
            val age = toInt(props(quot;agequot;))

                if (age != null)
                  back += new Person(props(quot;name.firstquot;),
                                     props(quot;name.lastquot;), age)
            }
        }
    }

    back.toList
}
Example #1
 Using loops
 Recursive
def readPeople(files: List[String]): List[Person] = files match {
  case file :: tail => {
    val props = readFile(file)

        val back = if (props != null) {
          if (props.contains(quot;name.firstquot;) &&
              props.contains(quot;name.lastquot;) &&
              props.contains(quot;agequot;)) {
            val age = toInt(props(quot;agequot;))

            if (age != null)
              new Person(props(quot;name.firstquot;), props(quot;name.lastquot;), age)
            else
              null
          } else null
        } else null

        if (back != null)
          back :: readPeople(tail)
        else
          readPeople(tail)
    }

    case Nil => Nil
}
Example #1
 Loops
 Recursion
 Higher-order functions
def readPeople(files: List[String]): List[Person] = {
  files.foldRight(List[String]()) { (file, people) =>
    val props = readFile(file)

        val back = if (props != null) {
          if (props.contains(quot;name.firstquot;) &&
              props.contains(quot;name.lastquot;) &&
              props.contains(quot;agequot;)) {
            val age = toInt(props(quot;agequot;))

            if (age != null)
              new Person(props(quot;name.firstquot;), props(quot;name.lastquot;), age)
            else
              null
          } else null
        } else null

        if (back != null)
          back :: people
        else
          people
    }
}
Example #1
 Loops
 Recursion
 Higher-order functions
…
 Monads!
def toInt(s: String) = try {
  Some(s.toInt)
} catch {
  case _ => None
}

// uninteresting and ugly
def readFile(file: String): Option[Map[String, String]] = {
  import collection.jcl.Hashtable

    try {
      val is = new BufferedInputStream(new FileInputStream(file))

     val p = new Properties
     p.load(is)

     is.close()

      Some(new Hashtable(p).asInstanceOf[Hashtable[String, String]])
    } catch {
      case _ => None
    }
}
def readPeople(files: List[String]): List[Person] = {
    for {
     file <- files
     props <- readFile(file)


     firstName <- props get quot;name.firstquot;
     lastName <- props get quot;name.lastquot;


     ageString <- props get quot;agequot;
     age <- toInt(ageString)
    } yield new Person(firstName, lastName, age)
}
Example #1
 Loops
 Recursion
 Higher-order functions
 Combinators
 Monads!
def readPeople(files: List[String]) = {
    import Function._


    files flatMap readFile flatMap { props =>
        val fNames = props get quot;name.firstquot;
        val names = fNames flatMap {
            (_, props get quot;name.lastquot;)
        }


        val data = names flatMap {
            case (fn, ln) =>
             (fn, ln, props get quot;agequot; map toInt)
        }


        data map tupled(new Person _)
    }
}
What did we just see?
   foldLeft / foldRight
    ◦ Catamorphisms
    ◦ Use when you want to reduce all of the
      elements of a collection into a single
      result
    ◦ Capable of almost anything!
What did we just see?
   foldLeft / foldRight

    def sum(nums: List[Int]) = {
      nums.foldLeft(0) { (x, y) =>
        x + y
      }
    }
What did we just see?
   foldLeft / foldRight

    def sum(nums: List[Int]) = {
      nums.foldLeft(0) { _ + _ }
    }
What did we just see?
   foldLeft / foldRight

    def sum(nums: List[Int]) = {
      (0 /: nums) { _ + _ }
    }
What did we just see?
 foldLeft / foldRight
 map
    ◦ Use when you want to transform every
      element of a collection, leaving the results
      in the corresponding location within a new
      collection
What did we just see?
 foldLeft / foldRight
 map

    val nums = List(quot;1quot;, quot;2quot;, quot;3quot;, quot;4quot;, quot;5quot;)
    nums map { str => str.toInt }
What did we just see?
 foldLeft / foldRight
 map

    val nums = List(quot;1quot;, quot;2quot;, quot;3quot;, quot;4quot;, quot;5quot;)
    nums map { _.toInt }
What did we just see?
 foldLeft / foldRight
 map
 flatMap (has two meanings)
    ◦ Collections: Use when you want to
      transform every element optionally
    ◦ Monads: Should have really been called
      “bind” (or >>=). More later…
What did we just see?
 foldLeft / foldRight
 map
 flatMap (has two meanings)

    def toCharArray(arr: Array[String]) = {
      arr flatMap { _.toCharArray }
    }

    toCharArray(Array(quot;Danielquot;, quot;Spiewakquot;))
    // =>
    Array('D', 'a', 'n', 'i', 'e', 'l',
          'S', 'p', 'i', 'e', 'w', 'a', 'k')
Other Common Util Methods
   filter (used in for-comprehensions)

    val nums = List(1, 2, 3, 4, 5)
    nums filter { _ % 2 == 0 }
Other Common Util Methods
   filter (used in for-comprehensions)

    val nums = List(1, 2, 3, 4, 5)
    nums filter (0 == 2 %)
Other Common Util Methods
 filter (used in for-comprehensions)
 zip / zipWithIndex
    ◦ zipWith (not available pre-2.8.0)

    val evens = List(2, 4, 6)
    val odds = List(1, 3, 5)

    evens zip odds
    // =>
    List((1, 2), (3, 4), (5, 6))
Other Common Util Methods
 filter (used in for-comprehensions)
 zip / zipWithIndex
    ◦ zipWith (not available pre-2.8.0)
   forall and exists

    val nums = List(1, 2, 3, 4, 5)
    nums forall { _ % 2 == 0 }       // => false
Other Common Util Methods
 filter (used in for-comprehensions)
 zip / zipWithIndex
    ◦ zipWith (not available pre-2.8.0)
   forall and exists

    val nums = List(1, 2, 3, 4, 5)
    nums exists { _ % 2 == 0 }       // => true
Other Common Util Methods
 filter (used in for-comprehensions)
 zip / zipWithIndex
    ◦ zipWith (not available pre-2.8.0)
 forall and exists
 take and drop

    val nums = List(5, 4, 3, 2, 1)
    nums take 2
    // =>
    List(5, 4)
Other Common Util Methods
 filter (used in for-comprehensions)
 zip / zipWithIndex
    ◦ zipWith (not available pre-2.8.0)
 forall and exists
 take and drop

    val nums = List(5, 4, 3, 2, 1)
    nums drop 2
    // =>
    List(3, 2, 1)
Other Common Util Methods
 filter (used in for-comprehensions)
 zip / zipWithIndex
    ◦ zipWith (not available pre-2.8.0)
 forall and exists
 take and drop
 foreach

    val names = List(quot;Danielquot;, quot;Chrisquot;)
    names foreach println
Example #2
Comparing the prefix of a List[Char]
 to a given string.

List[Char]                           String      Result
List('d', 'a', 'n', 'i', 'e', 'l')   quot;danquot;       true
List('d', 'a', 'n', 'i', 'e', 'l')   quot;ielquot;       false
List('t', 'e', 's', 't')             quot;testingquot;   false
List('t', 'e', 's', 't')             quot;testquot;      true
def isPrefix(chars: List[Char], str: String) = {
  if (chars.lengthCompare(str.length) < 0) {
    false
  } else {
    val trunc = chars take str.length

        trunc.zipWithIndex forall {
          case (c, i) => c == str(i)
        }
    }
}
More About Combinators
 The “Essence of Functional
  Programming”
 Combine simple things to solve
  complex problems
 Very high level
 Think about Lego™ bricks
More About Combinators
   The best example: Parser
    Combinators
    def expr: Parser[Int] = (
         num ~ quot;+quot; ~ expr    ^^ { case (x, _, y) => x + y }
        | num ~ quot;-quot; ~ expr   ^^ { case (x, _, y) => x - y }
        | num
    )


    def num = quot;quot;quot;d+quot;quot;quot;.r ^^ { _.toInt }
More About Combinators
   The best example: Parser
    Combinators
    def expr: Parser[Int] = (
         num ~ quot;+quot; ~ expr    ^^ { case (x, _, y) => x + y }
        | num ~ quot;-quot; ~ expr   ^^ { case (x, _, y) => x - y }
        | num
    )


    def num = quot;quot;quot;d+quot;quot;quot;.r ^^ { _.toInt }


    expr(quot;12 + 7 - 4quot;)         // => Success(15)
    expr(quot;42quot;)                 // => Success(42)
More About Combinators
   Three Types of Combinators
    ◦ Sequential (first a, then b)

     a ~ b
More About Combinators
   Three Types of Combinators
    ◦ Sequential (first a, then b)
    ◦ Disjunctive (either a, or b)

     a | b
More About Combinators
   Three Types of Combinators
    ◦ Sequential (first a, then b)
    ◦ Disjunctive (either a, or b)
    ◦ Literal (exactly foo)

     quot;fooquot;
More About Combinators
   Three Types of Combinators
    ◦ Sequential (first a, then b)
    ◦ Disjunctive (either a, or b)
    ◦ Literal (exactly foo)
   Note: Our example uses a regular
    expression parser, but that is only a
    generalization of the literal parser
More About Combinators
 Seldom created, often used
 Good for problems which split into
  smaller sub-problems
March of the Monads
   Monads are not scary
March of the Monads
 Monads are not scary
 Monad explanations are scary
March of the Monads
   Monads are little containers for
    encapsulating something
    ◦ What the “something” is depends on the
      monad
 An instance of a monad can be
  “bound” together with another instance
  of that monad
 Most combinators are monads
March of the Monads
   All monads have
    ◦ A type constructor
       class Option[A] { … }

    ◦ A single-argument constructor
       new Some(quot;one to watch over mequot;)

    ◦ A flatMap method which behaves
      properly
       a flatMap { v => v.next }
March of the Monads
March of the Monads
   Option
    ◦ This is what the Groovy folks really wanted
      when they designed the “Elvis Operator”
   Parser
    ◦ Sequential parser is really two bound
      parsers
    ◦ Disjunctive parser uses an optional
      monadic function: orElse
    ◦ Literal parser is the one-argument
      constructor
   Function1 (sort of)
    ◦ We could say that function composition is
Learn More
   Read my blog! :-)
    ◦ http://www.codecommit.com/blog
   Some better sources…
    ◦   http://apocalisp.wordpress.com/
    ◦   http://michid.wordpress.com/
    ◦   http://joelneely.wordpress.com/
    ◦   http://scala-blogs.org
   A really good paper…
    ◦ Monadic Parser Combinators
      (1996; Hutton, Meijer)

Contenu connexe

Tendances

A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOJorge Vásquez
 
A Tour Of Scala
A Tour Of ScalaA Tour Of Scala
A Tour Of Scalafanf42
 
Introduction to Scala for Java Developers
Introduction to Scala for Java DevelopersIntroduction to Scala for Java Developers
Introduction to Scala for Java DevelopersMichael Galpin
 
Few simple-type-tricks in scala
Few simple-type-tricks in scalaFew simple-type-tricks in scala
Few simple-type-tricks in scalaRuslan Shevchenko
 
Demystifying Shapeless
Demystifying Shapeless Demystifying Shapeless
Demystifying Shapeless Jared Roesch
 
A Brief Intro to Scala
A Brief Intro to ScalaA Brief Intro to Scala
A Brief Intro to ScalaTim Underwood
 
Scala : language of the future
Scala : language of the futureScala : language of the future
Scala : language of the futureAnsviaLab
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scalapramode_ce
 
Brief tour of psp-std
Brief tour of psp-stdBrief tour of psp-std
Brief tour of psp-stdPaul Phillips
 
SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.Ruslan Shevchenko
 
Ponies and Unicorns With Scala
Ponies and Unicorns With ScalaPonies and Unicorns With Scala
Ponies and Unicorns With ScalaTomer Gabel
 
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
JDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation streamJDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation stream
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation streamRuslan Shevchenko
 
Introduction To Scala
Introduction To ScalaIntroduction To Scala
Introduction To ScalaPeter Maas
 
Scala Refactoring for Fun and Profit
Scala Refactoring for Fun and ProfitScala Refactoring for Fun and Profit
Scala Refactoring for Fun and ProfitTomer Gabel
 

Tendances (20)

A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIO
 
A Tour Of Scala
A Tour Of ScalaA Tour Of Scala
A Tour Of Scala
 
Scala cheatsheet
Scala cheatsheetScala cheatsheet
Scala cheatsheet
 
Introduction to Scala for Java Developers
Introduction to Scala for Java DevelopersIntroduction to Scala for Java Developers
Introduction to Scala for Java Developers
 
Scala Intro
Scala IntroScala Intro
Scala Intro
 
Few simple-type-tricks in scala
Few simple-type-tricks in scalaFew simple-type-tricks in scala
Few simple-type-tricks in scala
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Demystifying Shapeless
Demystifying Shapeless Demystifying Shapeless
Demystifying Shapeless
 
Scala fundamentals
Scala fundamentalsScala fundamentals
Scala fundamentals
 
A Brief Intro to Scala
A Brief Intro to ScalaA Brief Intro to Scala
A Brief Intro to Scala
 
Scala : language of the future
Scala : language of the futureScala : language of the future
Scala : language of the future
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
 
Brief tour of psp-std
Brief tour of psp-stdBrief tour of psp-std
Brief tour of psp-std
 
Scala Introduction
Scala IntroductionScala Introduction
Scala Introduction
 
SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.
 
Ponies and Unicorns With Scala
Ponies and Unicorns With ScalaPonies and Unicorns With Scala
Ponies and Unicorns With Scala
 
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
JDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation streamJDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation stream
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
 
Introduction To Scala
Introduction To ScalaIntroduction To Scala
Introduction To Scala
 
Scala Refactoring for Fun and Profit
Scala Refactoring for Fun and ProfitScala Refactoring for Fun and Profit
Scala Refactoring for Fun and Profit
 

Similaire à Practically Functional

Knolx Session : Built-In Control Structures in Scala
Knolx Session : Built-In Control Structures in ScalaKnolx Session : Built-In Control Structures in Scala
Knolx Session : Built-In Control Structures in ScalaAyush Mishra
 
Scala: Devnology - Learn A Language Scala
Scala: Devnology - Learn A Language ScalaScala: Devnology - Learn A Language Scala
Scala: Devnology - Learn A Language ScalaJan Willem Tulp
 
Scala for Java Developers
Scala for Java DevelopersScala for Java Developers
Scala for Java DevelopersRamnivasLaddad
 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In ScalaSkills Matter
 
Scala - just good for Java shops?
Scala - just good for Java shops?Scala - just good for Java shops?
Scala - just good for Java shops?Sarah Mount
 
2.1 Recap From Day One
2.1 Recap From Day One2.1 Recap From Day One
2.1 Recap From Day Oneretronym
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallySean Cribbs
 
BCS SPA 2010 - An Introduction to Scala for Java Developers
BCS SPA 2010 - An Introduction to Scala for Java DevelopersBCS SPA 2010 - An Introduction to Scala for Java Developers
BCS SPA 2010 - An Introduction to Scala for Java DevelopersMiles Sabin
 
An Introduction to Scala for Java Developers
An Introduction to Scala for Java DevelopersAn Introduction to Scala for Java Developers
An Introduction to Scala for Java DevelopersMiles Sabin
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecLoïc Descotte
 
Introduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanIntroduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanJimin Hsieh
 
Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018Codemotion
 

Similaire à Practically Functional (20)

Scala introduction
Scala introductionScala introduction
Scala introduction
 
Knolx Session : Built-In Control Structures in Scala
Knolx Session : Built-In Control Structures in ScalaKnolx Session : Built-In Control Structures in Scala
Knolx Session : Built-In Control Structures in Scala
 
Scala: Devnology - Learn A Language Scala
Scala: Devnology - Learn A Language ScalaScala: Devnology - Learn A Language Scala
Scala: Devnology - Learn A Language Scala
 
Scala ntnu
Scala ntnuScala ntnu
Scala ntnu
 
Scala for Java Developers
Scala for Java DevelopersScala for Java Developers
Scala for Java Developers
 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In Scala
 
Scala - just good for Java shops?
Scala - just good for Java shops?Scala - just good for Java shops?
Scala - just good for Java shops?
 
Scala in a nutshell by venkat
Scala in a nutshell by venkatScala in a nutshell by venkat
Scala in a nutshell by venkat
 
2.1 Recap From Day One
2.1 Recap From Day One2.1 Recap From Day One
2.1 Recap From Day One
 
Scala for curious
Scala for curiousScala for curious
Scala for curious
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing Functionally
 
Scala
ScalaScala
Scala
 
BCS SPA 2010 - An Introduction to Scala for Java Developers
BCS SPA 2010 - An Introduction to Scala for Java DevelopersBCS SPA 2010 - An Introduction to Scala for Java Developers
BCS SPA 2010 - An Introduction to Scala for Java Developers
 
An Introduction to Scala for Java Developers
An Introduction to Scala for Java DevelopersAn Introduction to Scala for Java Developers
An Introduction to Scala for Java Developers
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
 
Python to scala
Python to scalaPython to scala
Python to scala
 
Introduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanIntroduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf Taiwan
 
A bit about Scala
A bit about ScalaA bit about Scala
A bit about Scala
 
Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018
 
Lazy java
Lazy javaLazy java
Lazy java
 

Dernier

Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 

Dernier (20)

Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 

Practically Functional

  • 2. whoami  Author of Scala for Java Refugees and other articles on Scala and FP  Former editor Javalobby / EclipseZone  Engaged in academic research involving Scala DSLs and text parsing (ScalaBison, GLL Combinators, ScalaQL)
  • 3. Agenda  Define “functional programming” (sort of)  See some common elements of FP  Motivate why this stuff is useful in the real world (hopefully)  Show practical functional techniques and design patterns  Explain monads!  Hopefully pique your interest in learning and applying more of this
  • 4. Definitions  Q: What is “functional programming”?
  • 5. Definitions  Q: What is “functional programming”? ◦ A: Nobody knows!
  • 6. Definitions  Q: What is “purely-functional”?
  • 7. Definitions  Q: What is “purely-functional”? ◦ Everything is immutable (no variables)
  • 8. Definitions  Q: What is “purely-functional”? ◦ Everything is immutable (no variables) ◦ Absolutely no side-effects println(quot;Hello, World!quot;)
  • 9. Definitions  Q: What is “purely-functional”? ◦ Everything is immutable (no variables) ◦ Absolutely no side-effects ◦ Referential transparency
  • 10. Definitions  Q: What is “purely-functional”? ◦ Everything is immutable (no variables) ◦ Absolutely no side-effects ◦ Referential transparency ◦ Bondage discipline?
  • 11. Definitions  Scala is not purely-functional ◦ vars ◦ Mutable collections ◦ Uncontrolled side-effects (println)
  • 12. Definitions  Scala is not purely-functional ◦ vars ◦ Mutable collections ◦ Uncontrolled side-effects (println)  Is Scala a “functional language”?
  • 13. Functional Trademarks  Higher-order functions def foreach(f: String=>Unit) { f(quot;Whatquot;) f(quot;isquot;) f(quot;goingquot;) f(quot;on?quot;) }
  • 14. Functional Trademarks  Higher-order functions foreach { s => println(s) }
  • 15. Functional Trademarks  Higher-order functions  Closures are anonymous functions ◦ Ruby, Groovy, Python; none of these count! foreach(println)
  • 16. Functional Trademarks  Higher-order functions  Closures are anonymous functions ◦ Ruby, Groovy, Python; none of these count!  Singly-linked immutable lists (cons cells) val names = quot;Chrisquot; :: quot;Joequot; :: Nil val names2 = quot;Danielquot; :: names
  • 17. Functional Trademarks  Higher-order functions  Closures are anonymous functions ◦ Ruby, Groovy, Python; none of these count!  Singly-linked immutable lists (cons cells)  Usually some form of type-inference val me = quot;Danielquot; // equivalent to... val me: String = quot;Danielquot;
  • 18. Functional Trademarks  Higher-order functions  Closures are anonymous functions ◦ Ruby, Groovy, Python; none of these count!  Singly-linked immutable lists (cons cells)  Usually some form of type-inference foreach { s => println(s) }
  • 19. Functional Trademarks  Higher-order functions  Closures are anonymous functions ◦ Ruby, Groovy, Python; none of these count!  Singly-linked immutable lists (cons cells)  Usually some form of type-inference  Immutable by default (or encouraged) val me = quot;Danielquot; var me = quot;Danielquot;
  • 20. What does this buy you?  Modularity (separation of concerns)  Understandability  No more “spooky action at a distance” …
  • 21. What does this buy you? public class Company { private List<Person> employees; public List<Person> getEmployees() { return employees; } public void addEmployee(Person p) { if (p.isAlive()) { employees.add(p); } } }
  • 22. What does this buy you?  Modularity (separation of concerns)  Understandability  No more “spooky action at a distance”  Flexible libraries (more on this later)  Syntactic power (internal DSLs)
  • 23. What does this buy you? quot;vectorquot; should { quot;store a single elementquot; in { val prop = forAll { (i: Int, e: Int) => i >= 0 ==> { (vector(0) = e)(0) mustEqual e } } prop must pass } quot;implement lengthquot; in { val prop = forAll { list: List[Int] => val vec = Vector(list:_*) vec.length mustEqual list.length } prop must pass } }
  • 24. Functional Idioms  Recursion instead of loops ◦ Scala helps with this by allowing methods within methods
  • 25. Functional Idioms  Recursion instead of loops ◦ Scala helps with this by allowing methods within methods def factorial(n: Int) = { var back = 1 for (i <- 1 to n) { back *= i } back }
  • 26. Functional Idioms  Recursion instead of loops ◦ Scala helps with this by allowing methods within methods def factorial(n: Int): Int = { if (n == 1) 1 else n * factorial(n - 1) }
  • 27. Functional Idioms  Recursion instead of loops ◦ Scala helps with this by allowing methods within methods def factorial(n: Int) = { def loop(n: Int, acc: Int): Int = { if (n == 1) acc else loop(n - 1, acc * n) } loop(n, 1) }
  • 28. Functional Idioms  Recursion instead of loops ◦ Scala helps with this by allowing methods within methods  Higher-order functions instead of recursion
  • 29. Functional Idioms  Recursion instead of loops ◦ Scala helps with this by allowing methods within methods  Higher-order functions instead of recursion  Combinators instead of higher-order functions
  • 30. Functional Idioms  Recursion instead of loops ◦ Scala helps with this by allowing methods within methods  Higher-order functions instead of recursion  Combinators instead of higher-order functions  Monads!
  • 31. Example #1 Retrieve structured, formatted data from across multiple .properties files and multiple keys within those files. # daniel.properties # tim.properties name.first = Daniel name.first = Timothy name.last = Spiewak name.last = Olmsted age = 21 age = 22
  • 32. Example #1  Using loops
  • 33. def toInt(s: String) = try { s.toInt } catch { case _ => null } // uninteresting and ugly def readFile(file: String): Map[String, String] = { import collection.jcl.Hashtable try { val is = new BufferedInputStream(new FileInputStream(file)) val p = new Properties p.load(is) is.close() new Hashtable(p).asInstanceOf[Hashtable[String, String]] } catch { case _ => null } }
  • 34. import collection.mutable.ListBuffer def readPeople(files: List[String]): List[Person] = { val back = new ListBuffer[Person] for (file <- files) { val props = readFile(file) if (props != null) { if (props.contains(quot;name.firstquot;) && props.contains(quot;name.lastquot;) && props.contains(quot;agequot;)) { val age = toInt(props(quot;agequot;)) if (age != null) back += new Person(props(quot;name.firstquot;), props(quot;name.lastquot;), age) } } } back.toList }
  • 35. Example #1  Using loops  Recursive
  • 36. def readPeople(files: List[String]): List[Person] = files match { case file :: tail => { val props = readFile(file) val back = if (props != null) { if (props.contains(quot;name.firstquot;) && props.contains(quot;name.lastquot;) && props.contains(quot;agequot;)) { val age = toInt(props(quot;agequot;)) if (age != null) new Person(props(quot;name.firstquot;), props(quot;name.lastquot;), age) else null } else null } else null if (back != null) back :: readPeople(tail) else readPeople(tail) } case Nil => Nil }
  • 37. Example #1  Loops  Recursion  Higher-order functions
  • 38. def readPeople(files: List[String]): List[Person] = { files.foldRight(List[String]()) { (file, people) => val props = readFile(file) val back = if (props != null) { if (props.contains(quot;name.firstquot;) && props.contains(quot;name.lastquot;) && props.contains(quot;agequot;)) { val age = toInt(props(quot;agequot;)) if (age != null) new Person(props(quot;name.firstquot;), props(quot;name.lastquot;), age) else null } else null } else null if (back != null) back :: people else people } }
  • 39. Example #1  Loops  Recursion  Higher-order functions …  Monads!
  • 40. def toInt(s: String) = try { Some(s.toInt) } catch { case _ => None } // uninteresting and ugly def readFile(file: String): Option[Map[String, String]] = { import collection.jcl.Hashtable try { val is = new BufferedInputStream(new FileInputStream(file)) val p = new Properties p.load(is) is.close() Some(new Hashtable(p).asInstanceOf[Hashtable[String, String]]) } catch { case _ => None } }
  • 41. def readPeople(files: List[String]): List[Person] = { for { file <- files props <- readFile(file) firstName <- props get quot;name.firstquot; lastName <- props get quot;name.lastquot; ageString <- props get quot;agequot; age <- toInt(ageString) } yield new Person(firstName, lastName, age) }
  • 42. Example #1  Loops  Recursion  Higher-order functions  Combinators  Monads!
  • 43. def readPeople(files: List[String]) = { import Function._ files flatMap readFile flatMap { props => val fNames = props get quot;name.firstquot; val names = fNames flatMap { (_, props get quot;name.lastquot;) } val data = names flatMap { case (fn, ln) => (fn, ln, props get quot;agequot; map toInt) } data map tupled(new Person _) } }
  • 44. What did we just see?  foldLeft / foldRight ◦ Catamorphisms ◦ Use when you want to reduce all of the elements of a collection into a single result ◦ Capable of almost anything!
  • 45. What did we just see?  foldLeft / foldRight def sum(nums: List[Int]) = { nums.foldLeft(0) { (x, y) => x + y } }
  • 46. What did we just see?  foldLeft / foldRight def sum(nums: List[Int]) = { nums.foldLeft(0) { _ + _ } }
  • 47. What did we just see?  foldLeft / foldRight def sum(nums: List[Int]) = { (0 /: nums) { _ + _ } }
  • 48. What did we just see?  foldLeft / foldRight  map ◦ Use when you want to transform every element of a collection, leaving the results in the corresponding location within a new collection
  • 49. What did we just see?  foldLeft / foldRight  map val nums = List(quot;1quot;, quot;2quot;, quot;3quot;, quot;4quot;, quot;5quot;) nums map { str => str.toInt }
  • 50. What did we just see?  foldLeft / foldRight  map val nums = List(quot;1quot;, quot;2quot;, quot;3quot;, quot;4quot;, quot;5quot;) nums map { _.toInt }
  • 51. What did we just see?  foldLeft / foldRight  map  flatMap (has two meanings) ◦ Collections: Use when you want to transform every element optionally ◦ Monads: Should have really been called “bind” (or >>=). More later…
  • 52. What did we just see?  foldLeft / foldRight  map  flatMap (has two meanings) def toCharArray(arr: Array[String]) = { arr flatMap { _.toCharArray } } toCharArray(Array(quot;Danielquot;, quot;Spiewakquot;)) // => Array('D', 'a', 'n', 'i', 'e', 'l', 'S', 'p', 'i', 'e', 'w', 'a', 'k')
  • 53. Other Common Util Methods  filter (used in for-comprehensions) val nums = List(1, 2, 3, 4, 5) nums filter { _ % 2 == 0 }
  • 54. Other Common Util Methods  filter (used in for-comprehensions) val nums = List(1, 2, 3, 4, 5) nums filter (0 == 2 %)
  • 55. Other Common Util Methods  filter (used in for-comprehensions)  zip / zipWithIndex ◦ zipWith (not available pre-2.8.0) val evens = List(2, 4, 6) val odds = List(1, 3, 5) evens zip odds // => List((1, 2), (3, 4), (5, 6))
  • 56. Other Common Util Methods  filter (used in for-comprehensions)  zip / zipWithIndex ◦ zipWith (not available pre-2.8.0)  forall and exists val nums = List(1, 2, 3, 4, 5) nums forall { _ % 2 == 0 } // => false
  • 57. Other Common Util Methods  filter (used in for-comprehensions)  zip / zipWithIndex ◦ zipWith (not available pre-2.8.0)  forall and exists val nums = List(1, 2, 3, 4, 5) nums exists { _ % 2 == 0 } // => true
  • 58. Other Common Util Methods  filter (used in for-comprehensions)  zip / zipWithIndex ◦ zipWith (not available pre-2.8.0)  forall and exists  take and drop val nums = List(5, 4, 3, 2, 1) nums take 2 // => List(5, 4)
  • 59. Other Common Util Methods  filter (used in for-comprehensions)  zip / zipWithIndex ◦ zipWith (not available pre-2.8.0)  forall and exists  take and drop val nums = List(5, 4, 3, 2, 1) nums drop 2 // => List(3, 2, 1)
  • 60. Other Common Util Methods  filter (used in for-comprehensions)  zip / zipWithIndex ◦ zipWith (not available pre-2.8.0)  forall and exists  take and drop  foreach val names = List(quot;Danielquot;, quot;Chrisquot;) names foreach println
  • 61. Example #2 Comparing the prefix of a List[Char] to a given string. List[Char] String Result List('d', 'a', 'n', 'i', 'e', 'l') quot;danquot; true List('d', 'a', 'n', 'i', 'e', 'l') quot;ielquot; false List('t', 'e', 's', 't') quot;testingquot; false List('t', 'e', 's', 't') quot;testquot; true
  • 62. def isPrefix(chars: List[Char], str: String) = { if (chars.lengthCompare(str.length) < 0) { false } else { val trunc = chars take str.length trunc.zipWithIndex forall { case (c, i) => c == str(i) } } }
  • 63. More About Combinators  The “Essence of Functional Programming”  Combine simple things to solve complex problems  Very high level  Think about Lego™ bricks
  • 64. More About Combinators  The best example: Parser Combinators def expr: Parser[Int] = ( num ~ quot;+quot; ~ expr ^^ { case (x, _, y) => x + y } | num ~ quot;-quot; ~ expr ^^ { case (x, _, y) => x - y } | num ) def num = quot;quot;quot;d+quot;quot;quot;.r ^^ { _.toInt }
  • 65. More About Combinators  The best example: Parser Combinators def expr: Parser[Int] = ( num ~ quot;+quot; ~ expr ^^ { case (x, _, y) => x + y } | num ~ quot;-quot; ~ expr ^^ { case (x, _, y) => x - y } | num ) def num = quot;quot;quot;d+quot;quot;quot;.r ^^ { _.toInt } expr(quot;12 + 7 - 4quot;) // => Success(15) expr(quot;42quot;) // => Success(42)
  • 66. More About Combinators  Three Types of Combinators ◦ Sequential (first a, then b) a ~ b
  • 67. More About Combinators  Three Types of Combinators ◦ Sequential (first a, then b) ◦ Disjunctive (either a, or b) a | b
  • 68. More About Combinators  Three Types of Combinators ◦ Sequential (first a, then b) ◦ Disjunctive (either a, or b) ◦ Literal (exactly foo) quot;fooquot;
  • 69. More About Combinators  Three Types of Combinators ◦ Sequential (first a, then b) ◦ Disjunctive (either a, or b) ◦ Literal (exactly foo)  Note: Our example uses a regular expression parser, but that is only a generalization of the literal parser
  • 70. More About Combinators  Seldom created, often used  Good for problems which split into smaller sub-problems
  • 71. March of the Monads  Monads are not scary
  • 72. March of the Monads  Monads are not scary  Monad explanations are scary
  • 73. March of the Monads  Monads are little containers for encapsulating something ◦ What the “something” is depends on the monad  An instance of a monad can be “bound” together with another instance of that monad  Most combinators are monads
  • 74. March of the Monads  All monads have ◦ A type constructor class Option[A] { … } ◦ A single-argument constructor new Some(quot;one to watch over mequot;) ◦ A flatMap method which behaves properly a flatMap { v => v.next }
  • 75. March of the Monads
  • 76. March of the Monads  Option ◦ This is what the Groovy folks really wanted when they designed the “Elvis Operator”  Parser ◦ Sequential parser is really two bound parsers ◦ Disjunctive parser uses an optional monadic function: orElse ◦ Literal parser is the one-argument constructor  Function1 (sort of) ◦ We could say that function composition is
  • 77. Learn More  Read my blog! :-) ◦ http://www.codecommit.com/blog  Some better sources… ◦ http://apocalisp.wordpress.com/ ◦ http://michid.wordpress.com/ ◦ http://joelneely.wordpress.com/ ◦ http://scala-blogs.org  A really good paper… ◦ Monadic Parser Combinators (1996; Hutton, Meijer)