Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Introduction to Scala

Introduction to Scala

Milano Scala Group - Group Kickoff

Gabriele Petronella

February 18, 2015
Tweet

More Decks by Gabriele Petronella

Other Decks in Programming

Transcript

  1. 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...
  2. 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
  3. RANDOM WORDS (FROM WIKIPEDIA) METHODS, MESSAGE PASSING, INFORMATION HIDING, DATA

    ABSTRACTION, ENCAPSULATION, POLYMORPHISM, INHERITANCE
  4. The large scale one was to find a better module

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

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

    programming” today is simply old style programming with fancier constructs.
  7. 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; } }
  8. 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 + ")"; } }
  9. JAVA Collections.sort(users, new Comparator<User>() { public int compare(User a, User

    b) { return a.getLastName().compare(b.getLastName()); } });
  10. DYNAMIC TYPING function subtract(x, y) { return x - y;

    } subtract(42, 2) // 40, that was easy!
  11. DYNAMIC TYPING if (new Date().getDay() === 2) { var foo

    = subtract('foo', 'fo'); return foo.concat('!'); }
  12. STATIC TYPING def subtract(x: Int, y: Int): Int = x

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

    Date().getDay() == 2) { val foo = subtract("foo", "fo"); return foo.concat("!"); }
  14. TRAITS trait Polite { def salutation: String def greet =

    println(salutation) } class User(name: String) extends Polite { def salutation = s"Hello, my name is $name" }
  15. 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
  16. IMPLICIT PARAMETERS DB.withConnection { connection => Query("SELECT * FROM USERS").execute(connection)

    } DB.withConnection { implicit connection => Query("SELECT * FROM USERS").execute }
  17. TYPE CLASSES class Semigroup a where append :: a ->

    a -> a instance Semigroup Integer where append a b = a + b Prelude> append 42 7 49
  18. 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
  19. 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
  20. 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 // :-(
  21. 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
  22. 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)
  23. TRAILING PARAMETERS def sum(x: Int)(y: Int) = x + y

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

    + 2) // 68 foo { val y = 4 * 8 y + 2 } // 68
  25. 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) }
  26. 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) )