SlideShare a Scribd company logo
LEARNING
 FUNCTIONAL
PROGRAMMING
   WITHOUT
 GROWING A
  NECKBEARD
   by Kelsey Innis / @kelseyinnis
HI!
                    I'm Kelsey.
I work at StackMob writing code that lets our users
 create & manage their applications, APIs, and data
  through the browser. I use Scala and the Lift web
               framework to do that.
WHY ARE YOU HERE?
http://www.youtube.com/embed/Lb8BCl6NKn0
To learn to write code with drive that don't take no
                        jive.
THE PAM GRIER CRITERIA FOR
     CODE BADASSERY
   Code, like Pam Grier, should be:
          Powerful,
          Beautiful, and
          Tough to mess with.
POWERFUL
Do big things
Do them easily
Do them quickly
TOUGH TO MESS WITH
Secure from outside manipulation
Hard to unintentionally make mistakes
Easy to maintain
BEAUTIFUL
Elegant, concise, and--yes--readable
Able to be easily reused
Fun to write
SCALA!
don't need parentheses for method calls
semicolons are optional
return value is the last line of the method
static typing with type inference
BUT WHAT DOES IT LOOK LIKE?
val   x: String = "a"
val   y = 2
val   z = 15.3
val   myThing = new Thing
val   theList = List("this", "sure", "is", "a", "list")
val   whatIsIt = theList(4)
BUT WHAT DOES IT LOOK LIKE?
def haggle(theirPrice: Int, myOffer: Int): String = {
        val theResponse: String =
                if (theirPrice <= myOffer + 5) {
                         "You've got a deal!"
                } else {
                         "I definitely wouldn't pay more than " +
                         (myOffer + (theirPrice - myOffer)/2) +
                         " for it."
                }
        theResponse
}

val askingPrice = 100
val iWantToPay = 50
val letsMakeADeal = haggle(askingPrice, iWantToPay)
FUNCTIONAL
PROGRAMMING
WHAT IS FUNCTIONAL
  PROGRAMMING?
  Well, what is a program?
ASK A KID
 (OR SIMPLE ENGLISH WIKIPEDIA)




                 A computer
               program is a list




WRONG
                of instructions
                   that tell a
              computer what to
                      do.
Imperative programming:
a sequence of commands that the computer carries
                 out in sequence

          Object-oriented programming:
these instructions, and the data they manipulate, are
                organized into objects
If a program's not a series of commands, then
                  what is it?
Learning Functional Programming Without Growing a Neckbeard
“Functional programming is a style of
 programming that emphasizes the
evaluation of expressions rather than
    the execution of commands.”
   —comp.lang.functional FAQ
WHAT THINGS ARE
val theQueen = "Elizabeth II"



                          but also...
def theGovernor(state: State) = {
        val candidates = state.getCandidates
        candidates(getTopVoteGetter)
}
WHAT IS A FUNCTION?



          A function is a relation
          between values where
          each of its input values
          gives back exactly one
           output value, playa.
SOME FUNCTIONS
Math.sqrt(x)
Collections.max(list)
Arrays.copyOf(original, newLength)
String.valueOf(anInt)
A function is pure if “the impact of a function on the
rest of the program [can] be described only in terms of
   its return type, and...the impact of the rest of the
program on the function be described only in terms of
            its arguments”. (Victor Nicollet)
This is our building block.




          Sooooo....
FUNCTIONS ARE DETERMINISTIC.
You will always get the same result if you run them
                with the same data.
             correctness is more clear
             unit tests are a breeze
             debugging is more directed

                    tough to mess with
FUNCTIONS ARE ENCAPSULATED.
“With a referentially transparent function, the interface-
     level activity is all one needs to know about its
            behavior.”. (Michael O. Church)
                        readability
                        reuse
                        maintainability

                           beautiful


                       tough to mess with
FUNCTIONS ARE COMMUTATIVE.
val firstThing = doOneThing()
val secondThing = doAnotherThing()

val thirdThing = doTheLastThing(firstThing, secondThing)



                        parallelization
                        concurrency
                        lazy evaluation

                                powerful
DATA IS IMMUTABLE.
Once an object is created, it cannot be changed.
If you need to change an object, make your own
                     copy.
                    a quick detour back to Java...

String s1 = "san dimas high school football rules"
String s2 = s1.toUpperCase

println("string 1: " + s1);
println("string 2: " + s2);



                       concurrency
                       rollback of data
                       simplicity

          powerful                               tough to mess with
Functions are deterministic
Functions are encapsulated
Functions are commutative
Data is immutable
                              Let's build.
...how?
FUNCTIONS AS FIRST CLASS CITIZENS
FIRST CLASS CITIZENS
val longSkinnyThing: String = "this is a string"
val listOfThem: List[String] = List("yarn","twine","thread")
val freshNewLongSkinnyThing: String = spinFromFiber("wool")
tieInAKnot(longSkinnyThing)




 class Rope(type:String) {
    override def toString(): String = "You've put me on a diet!";
}

val longSkinnyThing: Rope = new Rope("nautical")
val listOfThem: List[String] =
    List(longSkinnyThing, new Rope("climbing"),
    new Rope("clothesline"), new Rope("jump"))
val freshNewLongSkinnyThing: Rope = spinFromFiber("hemp")
tieInAKnot(longSkinnyThing)
val addSpam: (String) => String =
        { (x:String) => x + " and Spam" }
addSpam("Egg and Bacon")
        //result: "Egg and Bacon and Spam"
val menuOptions = List(addSpam, withoutSpam)
menuOptions(1)("Egg and Bacon and Spam")
        //result: "You can't have that"




   addSpam's type is (String) => String
(list of parameters' types) => return
                 type
RETURNING FUNCTIONS FROM
             FUNCTIONS
def tagText(tag: String, text: String) = "<" + tag +">" + text +
""
val noReally = tagText("em", "pay attention!!!!")
        //result: <em>pay attention!!!!</em>

def tagText2(tag: String) = { (text:String) =>"<" + tag +">" + te
xt + "" }
val tagWithAndSpam = tagText2("andSpam")
val breakfast = tagWithAndSpam("Spam Bacon and Sausage")
        //result: <andSpam>Spam Bacon and Sausage</andSpam>




                               beautiful


                                powerful
CURRYING




  YUM!
HIGHER-ORDER FUNCTIONS
FOR LOOP
                               Java

public void talkAboutFruit {
         Fruit[] fruits = {
                 new Fruit("apple"),
                 new Fruit("cherry"),
                 new Fruit("strawberry")
         };
         for (int i = 0; i < fruits.length; i++) {
                 System.out.println("Hey the other day I ate a " +
  fruits[i];
         }
}

                               Scala

 def talkAboutFruit = {
        val fruits = List(new Fruit("apple"),
                          new Fruit("cherry"),
                          new Fruit("strawberry"))
        for (i <- 0 until fruits.length) {
                System.out.println("Hey the other day I ate a " +
 fruits(i);
        }
}
LET'S GET ABSTRACT
    a function that takes a list and a function
          (list of parameters' types) => return type

  foreach(fruitList:List(fruits),
theFunction: (Fruit) => Unit): Unit
  def foreach(fruitList:List(fruits), theFunction: (Fruit) => Unit
) = {
         for (i <- 0 until fruitList.length) {
                 theFunction(fruits(i))
         }
}

 def talkAboutFruit = {
        val fruits = List(new Fruit("apple"),
                          new Fruit("cherry"),
                          new Fruit("strawberry"))
        val tellEm =
                { (f:Fruit) => System.out.println(
                        "Hey the other day I ate a " + f) }
        foreach(fruits, tellEm)
        }
}
MORE ABSTRACTERER!
foreach(theList:List(A), theFunction:
         (A) => Unit): Unit
abstract class Collection[A] {
        ...
        def foreach(theFunction: (A) => Unit): Unit
        ...
}

 def talkAboutFruit = {
        val fruits = List(new Fruit("apple"),
                          new Fruit("cherry"),
                          new Fruit("strawberry"))
        val tellEm =
                { (f:Fruit) => System.out.println(
                        "Hey the other day I ate a " + f) }
        fruits.foreach(tellEm)
        }
}
THIS:
abstract class Collection[A] {
        ...
        def foreach(theFunction: (A) => Unit): Unit = {
                for (i <- 0 until this.length) {
                        theFunction(this(i))
                }
        }
        ...
}


        IS NOT HOW SCALA
      IMPLEMENTED FOREACH
                          tough to mess with


                                powerful
SOMETHING A LITTLE JUICIER
def makePies: List[Pie] = {
        val fruits = List(new Fruit("apple"),
                          new Fruit("cherry"),
                          new Fruit("strawberry"))
        var pies = List()
        for (i <- 0 until fruits.length) {
                new Pie(fruits(i)) :: pies
        }
        pies
}


           on a collection of A, you can
        map(theFunction: (A) => B):
                 Collection[B]
def makePies: List[Pie] = {
        val fruits = List(new Fruit("apple"),
                          new Fruit("cherry"),
                          new Fruit("strawberry"))
        val makePie = { (f: Fruit) => new Pie(f) }
        fruits.map(makePie)
}
ANONYMOUS FUNCTIONS
val kindOfFruit: String = "blueberry"
val blueberryFruit = new Fruit(kindOfFruit)
val alsoBlueberry = new Fruit("blueberry")

val makePie = { (f: Fruit) => new Pie(f) }
fruits.map(makePie)
//equivalent to
fruits.map( { (f: Fruit) => new Pie(f) } )

def makePies: List[Pie] = {
        val fruits = List(new Fruit("apple"),
                          new Fruit("cherry"),
                          new Fruit("strawberry"))
        fruits.map( { (f: Fruit) => new Pie(f) } )
}

def makePies(fruits: List[Fruit]) : List[Pie]
         = fruits.map( { (f: Fruit) => new Pie(f) } )




                               beautiful
COLLECTION HANDLING
                            FILTER
val theList = List(new Fruit("apple"), new Fruit("pear"), new Fru
it("cherry"), new Fruit("strawberry"), new Fruit("honeydew"))

scala> theList.filter( { (f: Fruit) => f.isDelicious } )
res0: List[Fruit] = List(apple, cherry, strawberry)

                             FOLD
scala> theList.fold("The fruits on this list are: ")( { (stringSo
Far: String, f: Fruit) => stringSoFar + " " + f.name } )
res1: String = "The fruits on this list are: apple pear cherry st
rawberry honeydew"

                           REDUCE
scala> theList.fold(0)( { (count: Int, f: Fruit) => count + " " +
 f.totalPieces } )
res2: Int = 42300

theList.reduce( { (f: Fruit) => f.totalPieces } )
res3: Int = 42300
NESTED FOR-LOOPS
  def tryAllPairings(pies: List[Pie], iceCreams: List[IceCream]):
List(Serving[Pie, IceCream]) {
         val servings = List[Serving[Pie,IceCream]]()
         for (p <- 0 until pies.length) {
                  for (i <- 0 until iceCreams.length) {
                          val serving = new Serving(p, i)
                          serving :: servings
                  }
         }
         servings
}

  def tryAllPairings(pies: List[Pie], iceCreams: List[IceCream]):
List(Serving[Pie, IceCream]) {
         pies.map( { (p: Pie) =>
                 iceCreams.map( { (i: IceCream) =>
                         new Serving(p, i)
                 } )
         } )
}
IS THIS AN IMPROVEMENT?
def tryAllPairings(pies: List[Pie], iceCreams: List[IceCream]): L
ist(Serving[Pie, IceCream]) {
        val servingsLists =
                pies.map( { (p: Pie) =>
                        iceCreams.map( { (i: IceCream) =>
                                new Serving(p, i)
                        } )
                } )
        servingsLists.flatten
}
FUNCTION COMPOSITION




  def bakeAPie(f: Fruit, c: Crust): Pie
  def eatAPie(p: Pie): HappyKelsey

  def bakeAndEatAPie(f: Fruit, c: Crust): HappyKelsey = eatAPie com
  pose bakeAPie
          //could also be written bakeAPie andThen eatAPie


flatten compose map is flatMap, and it's MAGIC
FOR-YIELD
  def tryAllPairings(pies: List[Pie], iceCreams: List[IceCream]):
List(Serving[Pie, IceCream]) {
         for {
                 p <- pies
                 i <- iceCreams
         } yield {
                 new Serving(p,i)
         }
}




                               beautiful!
FUN WITH FOR-YIELD
  def goodPairings(pies: List[Pie], iceCreams: List[IceCream]): Li
st(Serving[Pie, IceCream]) {
         for {
                 p <- pies
                 i <- iceCreams
                 val serving = new Serving(p,i)
                 if (serving.isGood)
         } yield {
                 serving
         }
}

  def pleaseEverybody(audience: List[Person], pies: List[Pie], ice
Creams: List[IceCream]): List(ThankYou) {
         for {
                 person <- audience
                 p <- pies
                 i <- iceCreams
                 val serving = new Serving(p,i)
                 if (serving.isGood)
         } yield {
                 person.feed(serving)
         }
}
partial application
higher order functions
function composition
for-yield
AND NOW FOR SOMETHING
(NOT REALLY) COMPLETELY DIFFERENT
NULL.
YUCK
 public Serving<Pie, IceCream> serveBestALaMode(Pie key, Map<Pie,
 IceCream> pairings) {
     if(pairings != null) {
         IceCream iceCream = pairings.get(key);
         if(iceCream != null) {
             return new Serving(key, iceCream)
         } else {
                  return null;
         }
     }
 }


SCALA PROGRAMMING DOESN'T USE NULL.
              YIPPEE!
OPTION
Option[T] is either a Some with a value of type T
     inside, or None representing nothing.
 val someOption: Option[String] = Some("this is a value")
 val noneOption: Option[String] = None

 val theSomeValue = someOption.get //returns "this is a value"
 val someIsDefined = someOption.isDefined //returns true

 val theNoneValue = noneOption.get //throws NoSuchElementException
 val someIsDefined = someOption.isDefined //returns false
def serveBestALaMode(key: Pie, pairings: Map[Pie, IceCream]): Op
tion[Serving[Pie,IceCream]] = {
         iceCream: Option[IceCream] = pairings.get(key);
         if (iceCream.isDefined) {
                  Some(new Serving(key, iceCream.get))
         } else {
                  None
         }
}
OPTION IS KIND OF LIKE A
          COLLECTION
                             .MAP
someOption.map( {(str:String) => str + " SAN DIMAS HIGH SCHOOL FO
OTBALL RULES"} )
        //returns Some("this is a value SAN DIMAS HIGH SCHOOL FOO
TBALL RULES")
noneOption.map( {(str:String) => str + " SAN DIMAS HIGH SCHOOL FO
OTBALL RULES"} )
        //returns None

                          .FLATMAP
val favoritePie: Option[Pie] = Some(rhubarb)
favoritePie.map({ (pie: Pie) => pairings.get(pie) })
        //returns Some(Some(butterPecan))--whoops!
favoritePie.flatMap( { (pie: Pie) => pairings.get(pie) } )
        //returns Some(butterPecan)

                            .FILTER
val todaysSpecial: Option[Pie]
val myOrder = todaysSpecial.filter( { (pie: Pie) => (pie != butte
rPecan) }
FOR-YIELD OVER OPTION
 for {
         pie <- todaysSpecial
         bestIceCream <- pairings.get(pie)
         iceCream <- availableFlavors.get(bestIceCream) } yield {
         myDessert
}




                                beautiful


                                 powerful


                           tough to mess with
OPTION IS A MONAD
   WHAT IS A MONAD?
"Let’s look at what it is that makes Thing a monad.
The first thing is that I can wrap up a value inside of a
new Thing...We have a function of type A => Thing; a
  function which takes some value and wraps it up
                    inside a new Thing.
  We also have this fancy bind function, which digs
   inside our Thing and allows a function which we
supply to use that value to create a new Thing. Scala
             calls this function “flatMap“....
 What’s interesting here is the fact that bind is how
 you combine two things together in sequence. We
 start with one thing and use its value to compute a
                        new thing."
                    —Daniel Spiewak
FLATMAP IS MAGIC
 flatMap hides our boilerplate. For Lists, it abstracts
away a for-loop, letting us create a new List from an
   existing list. For Options, it abstracts away a null
check, letting us create a new nullable value from an
                       existing one.


                      tough to mess with
OTHER MONADS
accumulating errors
a cursor position in a database or file
states in a state machine
an environment that changes

                 powerful
EXTRA CREDIT WHOA




A SEMICOLON IS A MONAD
partial application
higher order functions
function composition
for-yield
monads
THE PSYCHOLOGY OF
FUNCTIONAL PROGRAMMING
READABILITY
“Is Clojure code hard to understand? Imagine if every
   time you read Java source code and encountered
   syntax elements like if statements, for loops, and
   anonymous classes, you had to pause and puzzle
  over what they mean. There are certain things that
    must be obvious to a person who wants to be a
  productive Java developer. Likewise there are parts
   of Clojure syntax that must be obvious for one to
    efficiently read and understand code. Examples
 include being comfortable with the use of let, apply,
 map, filter, reduce and anonymous functions...”—R.
                     Mark Volkmann
DSLS
class HelloWorldSpec extends Specification {

      "The 'Hello world' string" should {
        "contain 11 characters" in {
          "Hello world" must have size(11)
        }
        "start with 'Hello'" in {
          "Hello world" must startWith("Hello")
        }
        "end with 'world'" in {
          "Hello world" must endWith("world")
        }
      }
  }

                             from specs2
PURITY




“The truth is that good programmers mix the styles quite
   a bit. We program imperatively when needed, and
   functionally when possible.” - Michael O. Church
THANK YOU

More Related Content

What's hot (18)

PDF
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
John De Goes
 
PDF
Introduction to programming in scala
Amuhinda Hungai
 
PDF
Pragmatic Real-World Scala (short version)
Jonas Bonér
 
PPTX
Joy of scala
Maxim Novak
 
PDF
One Monad to Rule Them All
John De Goes
 
PPTX
Intro to Functional Programming in Scala
Shai Yallin
 
PDF
Programming in Scala: Notes
Roberto Casadei
 
PDF
Introduction to functional programming (In Arabic)
Omar Abdelhafith
 
PDF
Functional Programming Patterns for the Pragmatic Programmer
Raúl Raja Martínez
 
PDF
Introduction to functional programming using Ocaml
pramode_ce
 
PDF
A taste of Functional Programming
Jordan Open Source Association
 
PDF
Refactoring Functional Type Classes
John De Goes
 
PDF
An introduction to property based testing
Scott Wlaschin
 
PDF
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
John De Goes
 
PPT
Introduction To Functional Programming
newmedio
 
PDF
Twins: Object Oriented Programming and Functional Programming
RichardWarburton
 
PPTX
Functional Programming in Javascript - IL Tech Talks week
yoavrubin
 
PDF
FP in Java - Project Lambda and beyond
Mario Fusco
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
John De Goes
 
Introduction to programming in scala
Amuhinda Hungai
 
Pragmatic Real-World Scala (short version)
Jonas Bonér
 
Joy of scala
Maxim Novak
 
One Monad to Rule Them All
John De Goes
 
Intro to Functional Programming in Scala
Shai Yallin
 
Programming in Scala: Notes
Roberto Casadei
 
Introduction to functional programming (In Arabic)
Omar Abdelhafith
 
Functional Programming Patterns for the Pragmatic Programmer
Raúl Raja Martínez
 
Introduction to functional programming using Ocaml
pramode_ce
 
A taste of Functional Programming
Jordan Open Source Association
 
Refactoring Functional Type Classes
John De Goes
 
An introduction to property based testing
Scott Wlaschin
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
John De Goes
 
Introduction To Functional Programming
newmedio
 
Twins: Object Oriented Programming and Functional Programming
RichardWarburton
 
Functional Programming in Javascript - IL Tech Talks week
yoavrubin
 
FP in Java - Project Lambda and beyond
Mario Fusco
 

Viewers also liked (20)

PDF
Functional programming with Xtend
Sven Efftinge
 
PDF
Why Haskell
Susan Potter
 
DOCX
1 4 vamos a jugar
Araceli Sanz Muñoz
 
PDF
Kerry Karl | Debunking Myths: GLUTEN
Kerry Karl
 
PPTX
Ratpack - SpringOne2GX 2015
Daniel Woods
 
PDF
5 Reasons Why Your Headlines Are On Life Support
Wishpond
 
PDF
Auktuálne otázky zodpovednosti za porušovanie práv duševného vlastníctva online
Martin Husovec
 
PPTX
Historia insp manuel antonio leal chacon
antonio leal
 
PPTX
Nuevas tecnologías de
mariaelicena
 
PPTX
基隆交點Vol.5 - 王珈琳 - 陪伴,一段服務的時間
交點
 
PPTX
Impacto de las tics en la educaciòn
Darìo Miranda S.A
 
PDF
8th biosimilars congregation 2016
Deepak Raj (2,000+Connections)
 
PDF
Future of Grails
Daniel Woods
 
PDF
Grafico diario del dax perfomance index para el 11 02-2013
Experiencia Trading
 
PPTX
Collaboration friday
kacrey
 
PPT
부용
kindseol
 
PPTX
leonardo monsalve
antonio leal
 
PDF
Brexit Webinar Series 3
U.S. Chamber of Commerce
 
DOCX
Planificacion de eliana caballero
ElianaCaballero
 
PDF
rhythm workshop
Rhythm_Therapy
 
Functional programming with Xtend
Sven Efftinge
 
Why Haskell
Susan Potter
 
1 4 vamos a jugar
Araceli Sanz Muñoz
 
Kerry Karl | Debunking Myths: GLUTEN
Kerry Karl
 
Ratpack - SpringOne2GX 2015
Daniel Woods
 
5 Reasons Why Your Headlines Are On Life Support
Wishpond
 
Auktuálne otázky zodpovednosti za porušovanie práv duševného vlastníctva online
Martin Husovec
 
Historia insp manuel antonio leal chacon
antonio leal
 
Nuevas tecnologías de
mariaelicena
 
基隆交點Vol.5 - 王珈琳 - 陪伴,一段服務的時間
交點
 
Impacto de las tics en la educaciòn
Darìo Miranda S.A
 
8th biosimilars congregation 2016
Deepak Raj (2,000+Connections)
 
Future of Grails
Daniel Woods
 
Grafico diario del dax perfomance index para el 11 02-2013
Experiencia Trading
 
Collaboration friday
kacrey
 
부용
kindseol
 
leonardo monsalve
antonio leal
 
Brexit Webinar Series 3
U.S. Chamber of Commerce
 
Planificacion de eliana caballero
ElianaCaballero
 
rhythm workshop
Rhythm_Therapy
 
Ad

Similar to Learning Functional Programming Without Growing a Neckbeard (20)

PPTX
Scala for curious
Tim (dev-tim) Zadorozhniy
 
ODP
Functional programming with Scala
Neelkanth Sachdeva
 
KEY
Scala: functional programming for the imperative mind
Sander Mak (@Sander_Mak)
 
ODP
Scala ntnu
Alf Kristian Støyle
 
PPTX
Taxonomy of Scala
shinolajla
 
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
PPTX
Scala, Play 2.0 & Cloud Foundry
Pray Desai
 
PDF
(How) can we benefit from adopting scala?
Tomasz Wrobel
 
PDF
Introduction to Scala
Aleksandar Prokopec
 
PDF
Gentle Introduction to Scala
Fangda Wang
 
PPTX
Scala Intro
Alexey (Mr_Mig) Migutsky
 
PPT
An introduction to scala
Mohsen Zainalpour
 
PDF
Intro to functional programming - Confoo
felixtrepanier
 
PDF
From Java to Scala - advantages and possible risks
SeniorDevOnly
 
PDF
Scala - core features
Łukasz Wójcik
 
PDF
Introduction To Scala
Innar Made
 
PDF
Functional programming is the most extreme programming
samthemonad
 
Scala for curious
Tim (dev-tim) Zadorozhniy
 
Functional programming with Scala
Neelkanth Sachdeva
 
Scala: functional programming for the imperative mind
Sander Mak (@Sander_Mak)
 
Taxonomy of Scala
shinolajla
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
Scala, Play 2.0 & Cloud Foundry
Pray Desai
 
(How) can we benefit from adopting scala?
Tomasz Wrobel
 
Introduction to Scala
Aleksandar Prokopec
 
Gentle Introduction to Scala
Fangda Wang
 
An introduction to scala
Mohsen Zainalpour
 
Intro to functional programming - Confoo
felixtrepanier
 
From Java to Scala - advantages and possible risks
SeniorDevOnly
 
Scala - core features
Łukasz Wójcik
 
Introduction To Scala
Innar Made
 
Functional programming is the most extreme programming
samthemonad
 
Ad

Recently uploaded (20)

PDF
SIZING YOUR AIR CONDITIONER---A PRACTICAL GUIDE.pdf
Muhammad Rizwan Akram
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PPTX
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
PDF
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
PDF
NASA A Researcher’s Guide to International Space Station : Physical Sciences ...
Dr. PANKAJ DHUSSA
 
PPTX
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PDF
“Computer Vision at Sea: Automated Fish Tracking for Sustainable Fishing,” a ...
Edge AI and Vision Alliance
 
PDF
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
PDF
Peak of Data & AI Encore AI-Enhanced Workflows for the Real World
Safe Software
 
PPTX
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
PPTX
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
PPTX
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
“NPU IP Hardware Shaped Through Software and Use-case Analysis,” a Presentati...
Edge AI and Vision Alliance
 
PDF
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
PDF
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
PDF
How do you fast track Agentic automation use cases discovery?
DianaGray10
 
SIZING YOUR AIR CONDITIONER---A PRACTICAL GUIDE.pdf
Muhammad Rizwan Akram
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
NASA A Researcher’s Guide to International Space Station : Physical Sciences ...
Dr. PANKAJ DHUSSA
 
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
“Computer Vision at Sea: Automated Fish Tracking for Sustainable Fishing,” a ...
Edge AI and Vision Alliance
 
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
Peak of Data & AI Encore AI-Enhanced Workflows for the Real World
Safe Software
 
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
“NPU IP Hardware Shaped Through Software and Use-case Analysis,” a Presentati...
Edge AI and Vision Alliance
 
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
How do you fast track Agentic automation use cases discovery?
DianaGray10
 

Learning Functional Programming Without Growing a Neckbeard

  • 1. LEARNING FUNCTIONAL PROGRAMMING WITHOUT GROWING A NECKBEARD by Kelsey Innis / @kelseyinnis
  • 2. HI! I'm Kelsey. I work at StackMob writing code that lets our users create & manage their applications, APIs, and data through the browser. I use Scala and the Lift web framework to do that.
  • 3. WHY ARE YOU HERE? http://www.youtube.com/embed/Lb8BCl6NKn0 To learn to write code with drive that don't take no jive.
  • 4. THE PAM GRIER CRITERIA FOR CODE BADASSERY Code, like Pam Grier, should be: Powerful, Beautiful, and Tough to mess with.
  • 5. POWERFUL Do big things Do them easily Do them quickly
  • 6. TOUGH TO MESS WITH Secure from outside manipulation Hard to unintentionally make mistakes Easy to maintain
  • 7. BEAUTIFUL Elegant, concise, and--yes--readable Able to be easily reused Fun to write
  • 8. SCALA! don't need parentheses for method calls semicolons are optional return value is the last line of the method static typing with type inference
  • 9. BUT WHAT DOES IT LOOK LIKE? val x: String = "a" val y = 2 val z = 15.3 val myThing = new Thing val theList = List("this", "sure", "is", "a", "list") val whatIsIt = theList(4)
  • 10. BUT WHAT DOES IT LOOK LIKE? def haggle(theirPrice: Int, myOffer: Int): String = { val theResponse: String = if (theirPrice <= myOffer + 5) { "You've got a deal!" } else { "I definitely wouldn't pay more than " + (myOffer + (theirPrice - myOffer)/2) + " for it." } theResponse } val askingPrice = 100 val iWantToPay = 50 val letsMakeADeal = haggle(askingPrice, iWantToPay)
  • 12. WHAT IS FUNCTIONAL PROGRAMMING? Well, what is a program?
  • 13. ASK A KID (OR SIMPLE ENGLISH WIKIPEDIA) A computer program is a list WRONG of instructions that tell a computer what to do.
  • 14. Imperative programming: a sequence of commands that the computer carries out in sequence Object-oriented programming: these instructions, and the data they manipulate, are organized into objects
  • 15. If a program's not a series of commands, then what is it?
  • 17. “Functional programming is a style of programming that emphasizes the evaluation of expressions rather than the execution of commands.” —comp.lang.functional FAQ
  • 18. WHAT THINGS ARE val theQueen = "Elizabeth II" but also... def theGovernor(state: State) = { val candidates = state.getCandidates candidates(getTopVoteGetter) }
  • 19. WHAT IS A FUNCTION? A function is a relation between values where each of its input values gives back exactly one output value, playa.
  • 21. A function is pure if “the impact of a function on the rest of the program [can] be described only in terms of its return type, and...the impact of the rest of the program on the function be described only in terms of its arguments”. (Victor Nicollet)
  • 22. This is our building block. Sooooo....
  • 23. FUNCTIONS ARE DETERMINISTIC. You will always get the same result if you run them with the same data. correctness is more clear unit tests are a breeze debugging is more directed tough to mess with
  • 24. FUNCTIONS ARE ENCAPSULATED. “With a referentially transparent function, the interface- level activity is all one needs to know about its behavior.”. (Michael O. Church) readability reuse maintainability beautiful tough to mess with
  • 25. FUNCTIONS ARE COMMUTATIVE. val firstThing = doOneThing() val secondThing = doAnotherThing() val thirdThing = doTheLastThing(firstThing, secondThing) parallelization concurrency lazy evaluation powerful
  • 26. DATA IS IMMUTABLE. Once an object is created, it cannot be changed. If you need to change an object, make your own copy. a quick detour back to Java... String s1 = "san dimas high school football rules" String s2 = s1.toUpperCase println("string 1: " + s1); println("string 2: " + s2); concurrency rollback of data simplicity powerful tough to mess with
  • 27. Functions are deterministic Functions are encapsulated Functions are commutative Data is immutable Let's build.
  • 29. FUNCTIONS AS FIRST CLASS CITIZENS
  • 30. FIRST CLASS CITIZENS val longSkinnyThing: String = "this is a string" val listOfThem: List[String] = List("yarn","twine","thread") val freshNewLongSkinnyThing: String = spinFromFiber("wool") tieInAKnot(longSkinnyThing) class Rope(type:String) { override def toString(): String = "You've put me on a diet!"; } val longSkinnyThing: Rope = new Rope("nautical") val listOfThem: List[String] = List(longSkinnyThing, new Rope("climbing"), new Rope("clothesline"), new Rope("jump")) val freshNewLongSkinnyThing: Rope = spinFromFiber("hemp") tieInAKnot(longSkinnyThing)
  • 31. val addSpam: (String) => String = { (x:String) => x + " and Spam" } addSpam("Egg and Bacon") //result: "Egg and Bacon and Spam" val menuOptions = List(addSpam, withoutSpam) menuOptions(1)("Egg and Bacon and Spam") //result: "You can't have that" addSpam's type is (String) => String (list of parameters' types) => return type
  • 32. RETURNING FUNCTIONS FROM FUNCTIONS def tagText(tag: String, text: String) = "<" + tag +">" + text + "" val noReally = tagText("em", "pay attention!!!!") //result: <em>pay attention!!!!</em> def tagText2(tag: String) = { (text:String) =>"<" + tag +">" + te xt + "" } val tagWithAndSpam = tagText2("andSpam") val breakfast = tagWithAndSpam("Spam Bacon and Sausage") //result: <andSpam>Spam Bacon and Sausage</andSpam> beautiful powerful
  • 35. FOR LOOP Java public void talkAboutFruit { Fruit[] fruits = { new Fruit("apple"), new Fruit("cherry"), new Fruit("strawberry") }; for (int i = 0; i < fruits.length; i++) { System.out.println("Hey the other day I ate a " + fruits[i]; } } Scala def talkAboutFruit = { val fruits = List(new Fruit("apple"), new Fruit("cherry"), new Fruit("strawberry")) for (i <- 0 until fruits.length) { System.out.println("Hey the other day I ate a " + fruits(i); } }
  • 36. LET'S GET ABSTRACT a function that takes a list and a function (list of parameters' types) => return type foreach(fruitList:List(fruits), theFunction: (Fruit) => Unit): Unit def foreach(fruitList:List(fruits), theFunction: (Fruit) => Unit ) = { for (i <- 0 until fruitList.length) { theFunction(fruits(i)) } } def talkAboutFruit = { val fruits = List(new Fruit("apple"), new Fruit("cherry"), new Fruit("strawberry")) val tellEm = { (f:Fruit) => System.out.println( "Hey the other day I ate a " + f) } foreach(fruits, tellEm) } }
  • 37. MORE ABSTRACTERER! foreach(theList:List(A), theFunction: (A) => Unit): Unit abstract class Collection[A] { ... def foreach(theFunction: (A) => Unit): Unit ... } def talkAboutFruit = { val fruits = List(new Fruit("apple"), new Fruit("cherry"), new Fruit("strawberry")) val tellEm = { (f:Fruit) => System.out.println( "Hey the other day I ate a " + f) } fruits.foreach(tellEm) } }
  • 38. THIS: abstract class Collection[A] { ... def foreach(theFunction: (A) => Unit): Unit = { for (i <- 0 until this.length) { theFunction(this(i)) } } ... } IS NOT HOW SCALA IMPLEMENTED FOREACH tough to mess with powerful
  • 39. SOMETHING A LITTLE JUICIER def makePies: List[Pie] = { val fruits = List(new Fruit("apple"), new Fruit("cherry"), new Fruit("strawberry")) var pies = List() for (i <- 0 until fruits.length) { new Pie(fruits(i)) :: pies } pies } on a collection of A, you can map(theFunction: (A) => B): Collection[B] def makePies: List[Pie] = { val fruits = List(new Fruit("apple"), new Fruit("cherry"), new Fruit("strawberry")) val makePie = { (f: Fruit) => new Pie(f) } fruits.map(makePie) }
  • 40. ANONYMOUS FUNCTIONS val kindOfFruit: String = "blueberry" val blueberryFruit = new Fruit(kindOfFruit) val alsoBlueberry = new Fruit("blueberry") val makePie = { (f: Fruit) => new Pie(f) } fruits.map(makePie) //equivalent to fruits.map( { (f: Fruit) => new Pie(f) } ) def makePies: List[Pie] = { val fruits = List(new Fruit("apple"), new Fruit("cherry"), new Fruit("strawberry")) fruits.map( { (f: Fruit) => new Pie(f) } ) } def makePies(fruits: List[Fruit]) : List[Pie] = fruits.map( { (f: Fruit) => new Pie(f) } ) beautiful
  • 41. COLLECTION HANDLING FILTER val theList = List(new Fruit("apple"), new Fruit("pear"), new Fru it("cherry"), new Fruit("strawberry"), new Fruit("honeydew")) scala> theList.filter( { (f: Fruit) => f.isDelicious } ) res0: List[Fruit] = List(apple, cherry, strawberry) FOLD scala> theList.fold("The fruits on this list are: ")( { (stringSo Far: String, f: Fruit) => stringSoFar + " " + f.name } ) res1: String = "The fruits on this list are: apple pear cherry st rawberry honeydew" REDUCE scala> theList.fold(0)( { (count: Int, f: Fruit) => count + " " + f.totalPieces } ) res2: Int = 42300 theList.reduce( { (f: Fruit) => f.totalPieces } ) res3: Int = 42300
  • 42. NESTED FOR-LOOPS def tryAllPairings(pies: List[Pie], iceCreams: List[IceCream]): List(Serving[Pie, IceCream]) { val servings = List[Serving[Pie,IceCream]]() for (p <- 0 until pies.length) { for (i <- 0 until iceCreams.length) { val serving = new Serving(p, i) serving :: servings } } servings } def tryAllPairings(pies: List[Pie], iceCreams: List[IceCream]): List(Serving[Pie, IceCream]) { pies.map( { (p: Pie) => iceCreams.map( { (i: IceCream) => new Serving(p, i) } ) } ) }
  • 43. IS THIS AN IMPROVEMENT? def tryAllPairings(pies: List[Pie], iceCreams: List[IceCream]): L ist(Serving[Pie, IceCream]) { val servingsLists = pies.map( { (p: Pie) => iceCreams.map( { (i: IceCream) => new Serving(p, i) } ) } ) servingsLists.flatten }
  • 44. FUNCTION COMPOSITION def bakeAPie(f: Fruit, c: Crust): Pie def eatAPie(p: Pie): HappyKelsey def bakeAndEatAPie(f: Fruit, c: Crust): HappyKelsey = eatAPie com pose bakeAPie //could also be written bakeAPie andThen eatAPie flatten compose map is flatMap, and it's MAGIC
  • 45. FOR-YIELD def tryAllPairings(pies: List[Pie], iceCreams: List[IceCream]): List(Serving[Pie, IceCream]) { for { p <- pies i <- iceCreams } yield { new Serving(p,i) } } beautiful!
  • 46. FUN WITH FOR-YIELD def goodPairings(pies: List[Pie], iceCreams: List[IceCream]): Li st(Serving[Pie, IceCream]) { for { p <- pies i <- iceCreams val serving = new Serving(p,i) if (serving.isGood) } yield { serving } } def pleaseEverybody(audience: List[Person], pies: List[Pie], ice Creams: List[IceCream]): List(ThankYou) { for { person <- audience p <- pies i <- iceCreams val serving = new Serving(p,i) if (serving.isGood) } yield { person.feed(serving) } }
  • 47. partial application higher order functions function composition for-yield
  • 48. AND NOW FOR SOMETHING (NOT REALLY) COMPLETELY DIFFERENT
  • 49. NULL.
  • 50. YUCK public Serving<Pie, IceCream> serveBestALaMode(Pie key, Map<Pie, IceCream> pairings) { if(pairings != null) { IceCream iceCream = pairings.get(key); if(iceCream != null) { return new Serving(key, iceCream) } else { return null; } } } SCALA PROGRAMMING DOESN'T USE NULL. YIPPEE!
  • 51. OPTION Option[T] is either a Some with a value of type T inside, or None representing nothing. val someOption: Option[String] = Some("this is a value") val noneOption: Option[String] = None val theSomeValue = someOption.get //returns "this is a value" val someIsDefined = someOption.isDefined //returns true val theNoneValue = noneOption.get //throws NoSuchElementException val someIsDefined = someOption.isDefined //returns false
  • 52. def serveBestALaMode(key: Pie, pairings: Map[Pie, IceCream]): Op tion[Serving[Pie,IceCream]] = { iceCream: Option[IceCream] = pairings.get(key); if (iceCream.isDefined) { Some(new Serving(key, iceCream.get)) } else { None } }
  • 53. OPTION IS KIND OF LIKE A COLLECTION .MAP someOption.map( {(str:String) => str + " SAN DIMAS HIGH SCHOOL FO OTBALL RULES"} ) //returns Some("this is a value SAN DIMAS HIGH SCHOOL FOO TBALL RULES") noneOption.map( {(str:String) => str + " SAN DIMAS HIGH SCHOOL FO OTBALL RULES"} ) //returns None .FLATMAP val favoritePie: Option[Pie] = Some(rhubarb) favoritePie.map({ (pie: Pie) => pairings.get(pie) }) //returns Some(Some(butterPecan))--whoops! favoritePie.flatMap( { (pie: Pie) => pairings.get(pie) } ) //returns Some(butterPecan) .FILTER val todaysSpecial: Option[Pie] val myOrder = todaysSpecial.filter( { (pie: Pie) => (pie != butte rPecan) }
  • 54. FOR-YIELD OVER OPTION for { pie <- todaysSpecial bestIceCream <- pairings.get(pie) iceCream <- availableFlavors.get(bestIceCream) } yield { myDessert } beautiful powerful tough to mess with
  • 55. OPTION IS A MONAD WHAT IS A MONAD?
  • 56. "Let’s look at what it is that makes Thing a monad. The first thing is that I can wrap up a value inside of a new Thing...We have a function of type A => Thing; a function which takes some value and wraps it up inside a new Thing. We also have this fancy bind function, which digs inside our Thing and allows a function which we supply to use that value to create a new Thing. Scala calls this function “flatMap“.... What’s interesting here is the fact that bind is how you combine two things together in sequence. We start with one thing and use its value to compute a new thing." —Daniel Spiewak
  • 57. FLATMAP IS MAGIC flatMap hides our boilerplate. For Lists, it abstracts away a for-loop, letting us create a new List from an existing list. For Options, it abstracts away a null check, letting us create a new nullable value from an existing one. tough to mess with
  • 58. OTHER MONADS accumulating errors a cursor position in a database or file states in a state machine an environment that changes powerful
  • 59. EXTRA CREDIT WHOA A SEMICOLON IS A MONAD
  • 60. partial application higher order functions function composition for-yield monads
  • 62. READABILITY “Is Clojure code hard to understand? Imagine if every time you read Java source code and encountered syntax elements like if statements, for loops, and anonymous classes, you had to pause and puzzle over what they mean. There are certain things that must be obvious to a person who wants to be a productive Java developer. Likewise there are parts of Clojure syntax that must be obvious for one to efficiently read and understand code. Examples include being comfortable with the use of let, apply, map, filter, reduce and anonymous functions...”—R. Mark Volkmann
  • 63. DSLS class HelloWorldSpec extends Specification { "The 'Hello world' string" should { "contain 11 characters" in { "Hello world" must have size(11) } "start with 'Hello'" in { "Hello world" must startWith("Hello") } "end with 'world'" in { "Hello world" must endWith("world") } } } from specs2
  • 64. PURITY “The truth is that good programmers mix the styles quite a bit. We program imperatively when needed, and functionally when possible.” - Michael O. Church