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

Introduction to Scala

Introduction to Scala

Milano Scala Group - Group Kickoff

C2bb0454c4af1a61e7f173d54ce17b0b?s=128

Gabriele Petronella

February 18, 2015
Tweet

More Decks by Gabriele Petronella

Other Decks in Programming

Transcript

  1. JUST, WHAT IS Scala?

  2. AS A START, IT'S NOT...

  3. None
  4. NOT that OBVIOUS, TRUST ME

  5. HISTORY (ALMOST) 2003 - A drunken Martin Odersky sees a

    Reese's Peanut Butter Cup ad featuring somebody's peanut butter getting on somebody else's chocolate and has an idea...
  6. None
  7. HISTORY (ALMOST) He creates Scala, a language that unifies constructs

    from both object oriented and functional languages. This pisses off both groups and each promptly declares jihad. — James Iry
  8. JOKES ASIDE...

  9. OBJECT-ORIENTED PROGRAMMING ENCAPSULATE FUNCTIONALITIES INTO OBJECTS

  10. RANDOM WORDS (FROM WIKIPEDIA) METHODS, MESSAGE PASSING, INFORMATION HIDING, DATA

    ABSTRACTION, ENCAPSULATION, POLYMORPHISM, INHERITANCE
  11. FUNCTIONAL PROGRAMMING ACTUAL MATHEMATICAL FUNCTIONS NO SIDE EFFECTS

  12. RANDOM WORDS (FROM WIKIPEDIA) LAMBDA CALCULUS, COMPOSITIONALITY, RECURSION, REFERENTIAL TRANSPARENCY,

    NO SIDE EFFECTS
  13. Though OOP came from many motivations, two were central

  14. The large scale one was to find a better module

    scheme for complex systems involving hiding of details
  15. ...and the small scale one was to find a more

    flexible version of assignment, and then to try to eliminate it altogether.
  16. It is unfortunate that much of what is called “object-oriented

    programming” today is simply old style programming with fancier constructs.
  17. THE EARLY HISTORY OF SMALLTALK ALAN KAY, 1993

  18. CAN WE HAVE OUR CAKE AND EAT IT TOO?

  19. FUNCTIONAL + OO PROGRAMMING ???

  20. MEET Scala

  21. MODULAR PROGRAMMING OO FOR MODULARITY FP FOR DATA MANIPULATION

  22. A PRACTICAL LANGUAGE

  23. JAVA INTEROPERABILITY SCALA -> JAVA JAVA -> SCALA

  24. EASY TO DEPLOY RUNS ON A JVM* *RAM NOT INCLUDED

  25. FAST YEP

  26. EXTENSIBLE BY DESIGN (MORE ON THIS LATER)

  27. THEY TOLD ME SCALA IS COMPLICATED

  28. None
  29. WELL OK, MAYBE SOMETIMES...

  30. LET'S BUILD A USER CLASS PRETTY BASIC RIGHT?

  31. public class Person implements Serializable { private final String firstName;

    private final String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
  32. public class Person implements Serializable { private final String firstName;

    private final String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Person person = (Person) o; if (firstName != null ? !firstName.equals(person.firstName) : person.firstName != null) { return false; } if (lastName != null ? !lastName.equals(person.lastName) : person.lastName != null) { return false; } return true; } public int hashCode() { int result = firstName != null ? firstName.hashCode() : 0; result = 31 * result + (lastName != null ? lastName.hashCode() : 0); return result; } public String toString() { return "Person(" + firstName + "," + lastName + ")"; } }
  33. None
  34. case class User(firstName: String, lastName: String)

  35. None
  36. LET'S SORT OUR USERS

  37. JAVA Collections.sort(users, new Comparator<User>() { public int compare(User a, User

    b) { return a.getLastName().compare(b.getLastName()); } });
  38. SCALA users.sortBy(x => x.firstName) RUBY users.sort_by {|x| x.firstName}

  39. SCALA users.sortBy(_.firstName) RUBY users.sort_by(&:firstName)

  40. SCALABLE DESIGN FEW, BUT POWERFUL CONCEPTS

  41. TYPES

  42. DYNAMIC TYPING function subtract(x, y) { return x - y;

    } subtract(42, 2) // 40, that was easy!
  43. None
  44. OR NOT...

  45. None
  46. DYNAMIC TYPING if (new Date().getDay() === 2) { var foo

    = subtract('foo', 'fo'); return foo.concat('!'); }
  47. QUESTION 1 IS THIS BROKEN?

  48. BOY, IF IT IS!

  49. QUESTION 2 WHEN WILL IT BREAK?

  50. NEXT TUESDAY (AND THE ONE AFTER THAT, AND THE ONE

    AFTER...)
  51. QUESTION 3 WHERE WILL IT BREAK?

  52. ONLY X KNOWS WHERE X IS YOUR FAVORITE GOD

  53. None
  54. LET'S TRY AGAIN

  55. STATIC TYPING (FTW!)

  56. None
  57. STATIC TYPING def subtract(x: Int, y: Int): Int = x

    - y subtract(42, 2) // 40, that was easy
  58. STATIC TYPING import java.util.Date // because fuck you if (new

    Date().getDay() == 2) { val foo = subtract("foo", "fo"); return foo.concat("!"); }
  59. QUESTION 1 IS THIS BROKEN?

  60. YOU BETCHA!

  61. QUESTION 2 WHEN WILL IT BREAK?

  62. RIGHT NOW ACTUALLY, AFTER IT COMPILES, SO IT MIGHT WELL

    BE NEXT TUESDAY
  63. QUESTION 3 WHERE WILL IT BREAK?

  64. RIGHT HERE NO CELESTIAL ENTITIES INVOLVED

  65. None
  66. TRAITS

  67. TRAITS trait Polite { def salutation: String def greet =

    println(salutation) }
  68. TRAITS trait Polite { def salutation: String def greet =

    println(salutation) } class User(name: String) extends Polite { def salutation = s"Hello, my name is $name" }
  69. TRAITS trait Polite { def salutation: String def greet =

    println(salutation) } class User(name: String) extends Polite { def salutation = s"Hello, my name is $name" } new User("Gabriele").greet // Hello, my name is Gabriele
  70. IMPLICIT PARAMETERS

  71. IMPLICIT PARAMETERS val hi = "Hi there!" def greet(s: String)

    = println(s) greet(hi) // Hi there!
  72. IMPLICIT PARAMETERS implicit val hi = "Hi there!" def greet(implicit

    s: String) = println(s) greet // Hi there!
  73. IMPLICIT PARAMETERS DB.withConnection { connection => Query("SELECT * FROM USERS").execute(connection)

    } DB.withConnection { implicit connection => Query("SELECT * FROM USERS").execute }
  74. TRAITS + IMPLICITS = TYPECLASSES

  75. TYPE CLASSES class Semigroup a where append :: a ->

    a -> a instance Semigroup Integer where append a b = a + b Prelude> append 42 7 49
  76. TYPE CLASSES trait Semigroup[A] { def append(a1: A, a2: A):

    A } implicit val SemigroupInt = new Semigroup[Int] { def append(x: Int, y: Int) = x + y } def append[A](x: A, y: A)(implicit s: Semigroup[A]) = s.append(x, y) scala> append(42, 7) res0: Int = 49
  77. IMPLICIT CONVERSIONS

  78. IMPLICIT CONVERSIONS In ruby: 2.even? // true 2.odd? // false

  79. IMPLICIT CONVERSIONS In scala: 2.isEven // error: value isEven is

    not a member of Int
  80. None
  81. IMPLICIT CONVERSIONS def isEven(n: Int) = n % 2 ==

    0 def isOdd(n: Int) = !isEven(n) isEven(2) // true isEven(3) // false isOdd(3) // true isOdd(2) // false
  82. IMPLICIT CONVERSIONS class PimpedInt(n: Int) { def isEven = n

    % 2 == 0 def isOdd = !isEven } new PimpedInt(2).isEven // true new PimpedInt(2).isOdd // false new PimpedInt(2) + 3 // :-(
  83. IMPLICIT CONVERSIONS implicit def toPimpedInt(n: Int) = new PimpedInt(n) 2.isEven

    // true 3.isEven // false 3.isOdd // true 2.isOdd // false like ruby, plus, it won't break next tuesday
  84. None
  85. SYNTAX INFIX METHODS

  86. INFIX METHODS 1 + 2 // 3 1.+(2) // 3

    List(1, 2, 3).map(x => x + 1) // List(2, 3, 4) List(1, 2, 3) map (x => x + 1) // List(2, 3, 4)
  87. SYNTAX TRAILING PARAMETERS

  88. TRAILING PARAMETERS def sum(x: Int)(y: Int) = x + y

    sum(42)(2) // 44 sum(42) { 2 } // 44
  89. TRAILING PARAMETERS def foo(f: Int) = f * 2 foo(32

    + 2) // 68 foo { val y = 4 * 8 y + 2 } // 68
  90. IMPLICITS + SYNTAX = DSL

  91. DSL lastSender ! "finished" forAll { (x: Int, y: Int)

    => (x > 0) ==> (y > 0) }
  92. DSL (EXPLICIT VERSION) lastSender.!("finished") forAll((x: Int, y: Int) => (x

    > 0).==>(y > 0))
  93. DSL "A Stack" should "pop values in LIFO order" in

    { val stack = new Stack[Int] stack.push(1) stack.push(2) stack.pop() should be (2) stack.pop() should be (1) }
  94. DSL (EXPLICIT VERSION) toShouldable("A Stack").should("pop values in LIFO order").in(x =>

    val stack = new Stack[Int] stack.push(1) stack.push(2) stack.pop().should().be(2) stack.pop().should().be(1) )
  95. SCALA RECAP

  96. MODULAR FP + OO

  97. PRACTICAL JAVA INTEROP, JVM, FAST

  98. EXTENSIBLE SIMPLE BUILDING BLOCKS

  99. THANK YOU