21
Getting Functional with Scala An Introduction to Functional Programming and the Scala Programming Language September, 2016

Getting Functional with Scala

Embed Size (px)

Citation preview

Getting Functional with Scala An Introduction to Functional Programming and the Scala Programming Language

September, 2016

2

Software Engineer at IBM Mobile Innovation Lab @jorgelpaez19

Jorge Paez

3

My IBM Journey… So far

www-01.ibm.com/employment/us/extremeblue https://www.ibm.com/innovation/milab/

4

Where will yours start? http://www-03.ibm.com/employment/entrylevel_campus.html

5

What is Functional Programming?

6

Function Not a Function

7

Core Ideas• Data is immutable

• PURE function are our basic building block • Use expressions over instructions • First class functions • Type-strictness

8

…but why?

9

Benefits!• Simpler concurrency/parallelism • Optimizations with caching or memoization • Easier debugging • Cleaner/less verbose code • Encourages code re-use • Promotes Test Driven Development

10

Pure vs Impure

// In Main.java

public String getFormal(String name) { name = "Mr." + name; return name;}

// In Main.scala

def getFormal(name: String) = s"Mr. $name!"

11

Expressions vs Instructions

// In Main.java

public double[] convertToMeters(double[] measurements) { double[] metricMeasurements = new double[measurements.length]; for(int i = 0; i < measurements.length; ++i) { metricMeasurements[i] = measurements[i] * CONVERSION_FACTOR; } return metricMeasurements;}

// In Main.scala

def convertToMeters(measurements: Seq[Double]) = measurements.map(n => n * CONVERSION_FACTOR)

12

First Class Functions

def main(args: Array[String]): Unit = { draw(getCurve(0, 90), 1) draw(getCurve, 2) } def getCurve: Double => Seq[(Double, Double)] = (r) => (0 to 360).map(theta => getCartesianCoordinates(r, theta))def getCurve(thetaO: Int, thetaF: Int): Double => Seq[(Double, Double)] = (r) => (thetaO to thetaF).map(theta => getCartesianCoordinates(r, theta))def getCartesianCoordinates(r: Double, theta: Double): (Double, Double) = ((r * Math.cos(theta)), (r * Math.sin(theta)))def draw(func: Double => Seq[(Double, Double)], scale: Double)

13

First Class Functions

def main(args: Array[String]): Unit = { draw(getCurve(0, 90), 1) draw(getCurve, 2) } def getCurve: Double => Seq[(Double, Double)] = (r) => (0 to 360).map(theta => getCartesianCoordinates(r, theta))def getCurve(thetaO: Int, thetaF: Int): Double => Seq[(Double, Double)] = (r) => (thetaO to thetaF).map(theta => getCartesianCoordinates(r, theta))def getCartesianCoordinates(r: Double, theta: Double): (Double, Double) = ((r * Math.cos(theta)), (r * Math.sin(theta)))def draw(func: Double => Seq[(Double, Double)], scale: Double)

def getCurve: Double => Seq[(Double, Double)] = (r) => (0 to 360).map(theta => getCartesianCoordinates(r, theta))def getCurve(thetaO: Int, thetaF: Int): Double => Seq[(Double, Double)] = (r) => (thetaO to thetaF).map(theta => getCartesianCoordinates(r, theta))

14

First Class Functions

def main(args: Array[String]): Unit = { draw(getCurve(0, 90), 1) draw(getCurve, 2) } def getCurve: Double => Seq[(Double, Double)] = (r) => (0 to 360).map(theta => getCartesianCoordinates(r, theta))def getCurve(thetaO: Int, thetaF: Int): Double => Seq[(Double, Double)] = (r) => (thetaO to thetaF).map(theta => getCartesianCoordinates(r, theta))def getCartesianCoordinates(r: Double, theta: Double): (Double, Double) = ((r * Math.cos(theta)), (r * Math.sin(theta)))def draw(func: Double => Seq[(Double, Double)], scale: Double)

def getCartesianCoordinates(r: Double, theta: Double): (Double, Double) = ((r * Math.cos(theta)), (r * Math.sin(theta)))

15

First Class Functions

def main(args: Array[String]): Unit = { draw(getCurve(0, 90), 1) draw(getCurve, 2) } def getCurve: Double => Seq[(Double, Double)] = (r) => (0 to 360).map(theta => getCartesianCoordinates(r, theta))def getCurve(thetaO: Int, thetaF: Int): Double => Seq[(Double, Double)] = (r) => (thetaO to thetaF).map(theta => getCartesianCoordinates(r, theta))def getCartesianCoordinates(r: Double, theta: Double): (Double, Double) = ((r * Math.cos(theta)), (r * Math.sin(theta)))def draw(func: Double => Seq[(Double, Double)], scale: Double)

def main(args: Array[String]): Unit = { draw(getCurve(0, 90), 1) draw(getCurve, 2) }

def draw(func: Double => Seq[(Double, Double)], scale: Double)

16

First Class Functions

def main(args: Array[String]): Unit = { draw(getCurve(0, 90), 1) draw(getCurve, 2) } def getCurve: Double => Seq[(Double, Double)] = (r) => (0 to 360).map(theta => getCartesianCoordinates(r, theta))def getCurve(thetaO: Int, thetaF: Int): Double => Seq[(Double, Double)] = (r) => (thetaO to thetaF).map(theta => getCartesianCoordinates(r, theta))def getCartesianCoordinates(r: Double, theta: Double): (Double, Double) = ((r * Math.cos(theta)), (r * Math.sin(theta)))def draw(func: Double => Seq[(Double, Double)], scale: Double)

17

Type Strictness

sealed trait Personcase class Student(name: String) extends Personcase class Alumni(name: String) extends Persondef getBusFare(person : Person): Int = { person match { case p: Student => 0 case p: Alumni => 2 } }

18

Options

// Form asking for person's gender// a) Female// b) Male// c) Don’t want to disclosedef main(args: Array[String]): Unit = { val answers = Seq(Some("Female"), Some("Male"), Some(null), None) answers.map(a => a match { case Some(gender) => if(gender == null){ "the didn't want to disclose his or her gender" } else { s"The user's gender is $gender" } case None => "the user didn't pick a value on the form" }) }

19

What’s next?

20

Keep Learning• Slides: http://www.slideshare.net/JorgePaez15/getting-functional-with-scala

• Deploying a Scala server to Bluemix: https://www.ibm.com/innovation/milab/how-to-run-a-scala-web-app-on-ibm-bluemix/

• Free class: https://www.coursera.org/learn/progfun1

Thank You@jorgelpaez19

@IBM_MIL