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

Introduction to Scala

Introduction to Scala

An updated version of my Introduction to Scala, presented for the first time at Community Days 2016 in Milan.

Gabriele Petronella

October 07, 2016
Tweet

More Decks by Gabriele Petronella

Other Decks in Programming

Transcript

  1. Why Scala? 1.Curiosity 2.A growing trend in industry (are you

    into data science?) 3.Approachable introduction to FP 4.Great learning experience that you can apply elsewhere
  2. This is Scala abstract class Fruit { def isSeasonal(): Boolean

    } class Mango extends Fruit { def isSeasonal() = { return true } }
  3. This is also Scala def ApplicativeCompose[M[_], N[_]] (implicit ma: Applicative[M],

    na: Applicative[N]): Applicative[({type λ[α]=M[N[α]]})#λ] = new Applicative[({type λ[α]=M[N[α]]})#λ] { def ap[A, B](f: M[N[A => B]], a: M[N[A]]) = { def liftA2[X, Y, Z](f: X => Y => Z, a: M[X], b: M[Y]): M[Z] = ma.ap(ma.fmap(f, a), b) liftA2((ff: N[A => B]) => (aa: N[A]) => na.ap(ff, aa), f, a) } def point[A](a: A) = ma point (na point a) }
  4. YES! That's kind of the gist of it. Scala sits

    in between FP and OOP. And yes, both FP and OOP eventually end up declaring war to it !
  5. Functions a function f: A -> B is a subset

    f of A x B such that for all a ∈ A exists exactly one b ∈ B such that (a, b) ∈ f If A are Integers and B are Strings: f(42) -> "puppy" ✅ f(43) -> "kitten" ✅ f(42) -> "shark" ⛔ ! 42 is mapped to two values !
  6. Functions Note: » functions are pure (some would argue: functions

    are FUNCTIONS) » functions are total (they always have a return value)
  7. Functions In FP functions can be passed around as values.

    They are first-order citizens in the language. val double = (x: Int) => x * 2 List(1, 2, 3).map(double) // List(2, 4, 6)
  8. Immutability and functions val inc = (x: Int) => x

    + 1 val x = inc(42) An expression is REFERENTIALLY TRANSPARENT if this ALWAYS holds true: inc(42) == 43 So: val x = 43 // 43 or inc(42) doesn't make a difference
  9. Scala and FP Scala embraces FP as a default... //

    functions as values val inc = (x: Int) => x + 1 // immutable collections List(1, 2, 3).append(4) // ⛔ ERROR! // immmutable classes case class User(name: String, age: Int) val gab = User("Gabriele", 27) gab.age = 20 // ⛔ ERROR! nice try...
  10. Scala and FP ...but doesn't force you to it //

    mutable collections import scala.collection.mutable.ListBuffer val list = ListBuffer(1, 2, 3) list.append(4) println(list) // ListBuffer(1, 2, 3, 4) // mutable values case class User(name: String, var age: Int) val gab = User("Gabriele", 27) gab.age = 10 // I'm a kid again!
  11. Quite nice ✌ Want to write Java-like Scala? With minimal

    effort you can! Want to go full-force FP? No problem!* Want to sneak in some FP here and there? We got you covered! *terms and conditions may apply
  12. What does it mean? “I need to design a language

    that can grow. I need to plan ways in which it might grow. But I need, too, to leave some choices so that other persons can make those choices at a later time” Growing a Language, by Guy Steele
  13. Scala as a growable language » highly-composable » very simple

    (but powerful) constructs » flexible syntax
  14. Expressions Everything is an expression. And expressions compose! val animal

    = if (legs == 8) "spider" else "other" val result = try { computeQuestion(42) } catch { case e: Throwable => "How many roads must a man walk down?" }
  15. Destructuring trait Animal case class Dog(owner: Option[Person]) extends Animal case

    class Reindeer(bells: Int) extends Animal animal match { case Dog(Some(owner)) => // handle dogs with owners case Dog(None) => // handle stray dogs case Reindeer(bells) if bells > 4 => // handle reindeers with more than 4 bells }
  16. syntax Custom "operators" case class Person(name: String) { def ->>(p:

    Person) = s"$name points at ${p.name}" } val me = new Person("me") val you = new Person("you") println(me ->> you) // "me points at you"
  17. syntax Shocking truth: this is a general rule. 1.+(2) ==

    1 + 2 Every method with one argument can be used in infix form
  18. syntax Trailing arguments def runInTransaction[A](o: O)(f: (txn: Txn) => A):

    A runInTransaction(options)(txn => doStuff(txn)) runInTransaction(options) { txn => doStuff() }
  19. implicits val context = // some context doSomething(a, b, context)

    doSomethingElse(x, y, context) can we avoid passing context around? implicit val context = // some context def doSomething(a: Int, b: Int)(implicit context: Context) doSomething(a, b) // Black magic!
  20. implicits “Implicits are the source of everything that is good

    and bad in Scala” -- myself, right now
  21. implicits Remember? Simple != easy trait Eq[A] { def eq(x:

    A, y: A): Boolean } implicit object StringEq extends Eq[String] { def eq(x: String, y: String) = x == y } def isEqual[A](x: A, y: A)(implicit e: Eq[A]) = e.eq(x, y)
  22. implicits Based on a simple concept (passing an implicit value

    around) we now have libraries like: » scalaz/cats: category theory applied to Scala » shapeless: generic programming in Scala Those are CRAZY projects, that no-one could envision when designing the language
  23. Did I mention it can go crazy? object SquareRoot extends

    Baysick { def main(args:Array[String]) = { 10 PRINT "Enter a number" 20 INPUT 'n 30 PRINT "Square root of " % "'n is " % SQRT('n) 40 END RUN } }
  24. Resources » Functional Programming Principles in Scala (coursera) » Programming

    in Scala (M.Odersky et al.) » Functional Programming in Scala (P. Chiusano, R. Bjarnason)