getting functional with scala
TRANSCRIPT
Getting Functional with Scala An Introduction to Functional Programming and the Scala Programming Language
September, 2016
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
7
Core Ideas• Data is immutable
• PURE function are our basic building block • Use expressions over instructions • First class functions • Type-strictness
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" }) }
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