Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scala

 Scala

A feel for the Scala Programming Language

Ben Darfler

July 06, 2016
Tweet

More Decks by Ben Darfler

Other Decks in Programming

Transcript

  1. History • 2004 - v 1.0 • 2006 - v

    2.0 • 2008 - v 2.7 • 2010 - v 2.8 (Language Stabilizes) • 2011 - v 2.9 • 2013 - v 2.10 • 2014 - v 2.11 • 2016 - v 2.12 (RC1 end of July) 2.8
  2. Projects • Big Data ◦ Kafka (Distributed Log) ◦ Spark

    (Batch Processing) ◦ Flink (Stream Processing) ◦ Samza (Stream Processing) ◦ Scrunch (MapReduce Pipelines) ◦ Scalding (MapReduce Pipelines) ◦ Summingbird (Streaming MapReduce) ◦ Algebird (Aggregations for Summingbird) • Distributed Systems ◦ Finagle (RPC) ◦ Snowflake (Unique ID Generation) ◦ Gizzard (Distributed DB Framework) ◦ FlockDB (Graph Database) • Frameworks ◦ Play Framework (Web Framework) ◦ Scalatra (Web Micro-framework) ◦ Finatra (Web Micro-framework) ◦ Akka (Actor Framework)
  3. Classes class Calc { val brand: String = "HP" def

    add(m: Int, n: Int): Int = m + n }
  4. Multiple Inheritance trait Car { val brand: String } trait

    Shiny { val shineRefraction: Int } class BMW extends Car with Shiny { val brand = "BMW" val shineRefraction = 12 }
  5. First Class Functions // Anonymous Function (x: Int) => x

    + 1 // Value val addOne = (x: Int) => x + 1 // Expression 1 + 1 // Value val two = 1 + 1
  6. First Class Functions // Collection Seq( 1 ) // Function

    def addOne(x: Int) = x + 1 // Collection Seq( (x: Int) => x + 1 ) // Function def applyOne(f: Int => Int) = f(1)
  7. Immutable Data // Immutable Reference val immutable = 1 //

    Immutable Collections Seq(1, 2, 3, 4) Set(1, 2, 3, 4) Map(1 -> 2, 3 -> 4)
  8. Generics // Generic Trait trait Cache[K, V] { def get(key:

    K): V def put(key: K, value: V) def delete(key: K) } // Generic Function def id[T](x: T) = x
  9. class Covariant[+A] val cv: Covariant[Any] = new Covariant[String] Variance Meaning

    Scala notation covariant C[T’] is a subclass of C[T] [+T] contravariant C[T] is a subclass of C[T’] [-T] invariant C[T] and C[T’] are not related [T]
  10. Bounds trait Animal { def speak: String } def cacophony[T

    <: Animal](animals: Seq[T]) = animals.map { a => a.speak } Meaning Scala notation Lower Bound Type variable T refers to supertype of type A T >: A Upper Bound Type variable T refers to a subtype of type A T <: A
  11. Type Inference def id[T](x: T) = x // Seq[Int] val

    x = id(Seq(1,2,3,4)) // Int val x = id(322) // String val x = id("hey")
  12. Case Classes // Java public class Person { private final

    String firstName; private final String lastName; private final Integer zipcode; private final Integer birthYear; public Person(String firstName, String lastName, Integer zipcode, Integer birthYear) { this.firstName = firstName; this.lastName = lastName; this.zipcode = zipcode; this.birthYear = birthYear; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public Integer getZipcode() { return zipcode; } public Integer getBirthYear() { return birthYear; } // TODO: implement toString // TODO: implement equals // TODO: implement hashCode } // Scala case class Person( firstName: String, lastName: String, zipcode: Int, birthYear: Int )
  13. Pattern Matching val times = 1 times match { case

    1 => "one" case 2 => "two" case _ => "some other number" } def bigger(o: Any): Any = { o match { case i: Int if i < 0 => i - 1 case i: Int => i + 1 case d: Double if d < 0.0 => d - 0.1 case d: Double => d + 0.1 case _: Any => "bigger" } }
  14. Case Classes + Pattern Matching = def calcType(calc: Calculator) =

    calc match { case _ if calc.brand == "hp" && calc.model == "20B" => "financial" case _ if calc.brand == "hp" && calc.model == "48G" => "scientific" case _ if calc.brand == "hp" && calc.model == "30B" => "business" case _ => "unknown" } def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business" case _ => "unknown" }
  15. Option - Null Handling def speakMap(str: Option[String]) = str.foreach {

    g => println(g) } def speakMatch(str: Option[String]) = str match { case Some(g) => println(g) case None => println("crickets") } // Some("Hello!") val hello: Option[String] = Option("Hello!") // None val silent: Option[String] = Option(null)
  16. Try - Exception Handling // Success[URL] val google: Try[URL] =

    Try(new URL("http://g.co")) // Failure[MalformedURLException] val invalid: Try[URL] = Try(new URL("invalid")) def connectMap(url: Try[URL]) = url.foreach { u => println(u) } def connectMatch(url: Try[URL]) = url match { case Success(u) => println(u) case Failure(e) => println(e) }
  17. For Comprehensions val seq = Seq(1, 2, 3, 4) //

    Seq(2, 4, 6, 8) for { i <- seq } yield i * 2 // Seq(4, 8) for { i <- seq if i % 2 == 0 } yield i * 2 // Seq((2,1), (3,1), (3,2), (4,1) ... ) for { i <- seq j <- 1 until i } yield (i, j)
  18. For Comprehensions + Option = case class User( name: String,

    gender: Option[String] ) def findById(id: Int): Option[User] val gender = findById(1).flatMap{ u => u.gender.map{ g => g.toLowerCase } } val gender: Option[String] = for { user <- findById(1) gender <- user.gender } yield { gender.toLowercase }
  19. For Comprehensions + Try = val gco = "http://g.co" def

    parse(url: String): Try[URL] def connect(url: URL): Try[URLConnection] val is = parse(gco).flatMap{ u => connect(u).map{ c => c.getInputStream } } val is: Try[InputStream] = for { url <- parse(gco) conn <- connect(url) } yield { conn.getInputStream }