SlideShare a Scribd company logo
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)

More Related Content

What's hot

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
Jorge Vásquez
 
A Tour Of Scala
A Tour Of ScalaA Tour Of Scala
A Tour Of Scala
fanf42
 
Scala cheatsheet
Scala cheatsheetScala cheatsheet
Scala cheatsheet
Arduino Aficionado
 
Introduction to Scala for Java Developers
Introduction to Scala for Java DevelopersIntroduction to Scala for Java Developers
Introduction to Scala for Java Developers
Michael Galpin
 
Scala Intro
Scala IntroScala Intro
Few simple-type-tricks in scala
Few simple-type-tricks in scalaFew simple-type-tricks in scala
Few simple-type-tricks in scala
Ruslan Shevchenko
 
Scala introduction
Scala introductionScala introduction
Scala introduction
Yardena Meymann
 
Demystifying Shapeless
Demystifying Shapeless Demystifying Shapeless
Demystifying Shapeless
Jared Roesch
 
Scala fundamentals
Scala fundamentalsScala fundamentals
Scala fundamentals
Alfonso Ruzafa
 
A Brief Intro to Scala
A Brief Intro to ScalaA Brief Intro to Scala
A Brief Intro to Scala
Tim Underwood
 
Scala : language of the future
Scala : language of the futureScala : language of the future
Scala : language of the future
AnsviaLab
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
Łukasz Bałamut
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
pramode_ce
 
Brief tour of psp-std
Brief tour of psp-stdBrief tour of psp-std
Brief tour of psp-std
Paul Phillips
 
Scala Introduction
Scala IntroductionScala Introduction
Scala Introduction
Adrian Spender
 
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 Scala
Tomer 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 stream
Ruslan Shevchenko
 
Introduction To Scala
Introduction To ScalaIntroduction To Scala
Introduction To Scala
Peter Maas
 
Scala Refactoring for Fun and Profit
Scala Refactoring for Fun and ProfitScala Refactoring for Fun and Profit
Scala Refactoring for Fun and Profit
Tomer Gabel
 

What's hot (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
 

Similar to Practically Functional

Scala introduction
Scala introductionScala introduction
Scala introduction
Alf Kristian Støyle
 
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
Ayush Mishra
 
Scala: Devnology - Learn A Language Scala
Scala: Devnology - Learn A Language ScalaScala: Devnology - Learn A Language Scala
Scala: Devnology - Learn A Language Scala
Jan Willem Tulp
 
Scala ntnu
Scala ntnuScala ntnu
Scala for Java Developers
Scala for Java DevelopersScala for Java Developers
Scala for Java Developers
RamnivasLaddad
 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In Scala
Skills 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
 
Scala in a nutshell by venkat
Scala in a nutshell by venkatScala in a nutshell by venkat
Scala in a nutshell by venkat
Venkateswaran Kandasamy
 
2.1 Recap From Day One
2.1 Recap From Day One2.1 Recap From Day One
2.1 Recap From Day One
retronym
 
Scala for curious
Scala for curiousScala for curious
Scala for curious
Tim (dev-tim) Zadorozhniy
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing Functionally
Sean Cribbs
 
Scala
ScalaScala
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
Miles Sabin
 
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
Miles Sabin
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
Loïc Descotte
 
Python to scala
Python to scalaPython to scala
Python to scala
kao kuo-tung
 
Introduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanIntroduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf Taiwan
Jimin Hsieh
 
A bit about Scala
A bit about ScalaA bit about Scala
A bit about Scala
Vladimir Parfinenko
 
Lazy Java
Lazy JavaLazy Java
Lazy Java
J On The Beach
 
Lazy java
Lazy javaLazy java
Lazy java
Mario Fusco
 

Similar to 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
 
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
 
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
 
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
 
Lazy Java
Lazy JavaLazy Java
Lazy Java
 
Lazy java
Lazy javaLazy java
Lazy java
 

Recently uploaded

Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
Chart Kalyan
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Alpen-Adria-Universität
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Jeffrey Haguewood
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
kumardaparthi1024
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
MichaelKnudsen27
 
Webinar: Designing a schema for a Data Warehouse
Webinar: Designing a schema for a Data WarehouseWebinar: Designing a schema for a Data Warehouse
Webinar: Designing a schema for a Data Warehouse
Federico Razzoli
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
DanBrown980551
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
Daiki Mogmet Ito
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
Jakub Marek
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
innovationoecd
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
Zilliz
 
UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
Wouter Lemaire
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
Ivanti
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
tolgahangng
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying AheadDigital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Wask
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
Tatiana Kojar
 

Recently uploaded (20)

Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
 
Webinar: Designing a schema for a Data Warehouse
Webinar: Designing a schema for a Data WarehouseWebinar: Designing a schema for a Data Warehouse
Webinar: Designing a schema for a Data Warehouse
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
 
UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying AheadDigital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying Ahead
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
 

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)