getting functional with scala

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

Upload: jorge-paez

Post on 16-Feb-2017

56 views

Category:

Software


0 download

TRANSCRIPT

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