160

Introduction to Scala

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

October 07, 2016

Transcript

6. 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

9. This is Scala abstract class Fruit { def isSeasonal(): Boolean

} class Mango extends Fruit { def isSeasonal() = { return true } }
10. 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) }

15. 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 !
16. Why both OOP: information hiding, modularity FP: composability OOP +

FP = modular programming

19. 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 !
20. Functions Note: » functions are pure (some would argue: functions

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

They are ﬁrst-order citizens in the language. val double = (x: Int) => x * 2 List(1, 2, 3).map(double) // List(2, 4, 6)
22. 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

26. Why immutability matters var foo = 42 hey(foo) ho(foo) letsgo(foo)

println(foo) // ???

println(foo)
28. Why immutability matters val foo = 42 hey(foo) ho(foo) letsgo(foo)

println(foo) // 42!

33. 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...
34. 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!
35. 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

only one

42. 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
43. Scala as a growable language » highly-composable » very simple

(but powerful) constructs » ﬂexible syntax

46. 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?" }
47. 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 }
48. 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"
49. syntax Shocking truth: this is a general rule. 1.+(2) ==

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

A runInTransaction(options)(txn => doStuff(txn)) runInTransaction(options) { txn => doStuff() }
51. 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!
52. implicits “Implicits are the source of everything that is good

and bad in Scala” -- myself, right now
53. 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)
54. 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
55. 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 } }

61. Resources » Functional Programming Principles in Scala (coursera) » Programming

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