Slide 1

Slide 1 text

SCALA Java2Days 2013 Manuel Bernhardt Dienstag, 03. Dezember 13

Slide 2

Slide 2 text

@elmanu AGENDA • History • Why Scala? • Scala in the wild • The Code / Scala in practice • Tools & more Dienstag, 03. Dezember 13

Slide 3

Slide 3 text

@elmanu YOUR SPEAKER • Independent software consultant based in Vienna • Web, web, web • Scala & Java & Javascript • Open-Source Dienstag, 03. Dezember 13

Slide 4

Slide 4 text

@elmanu AGENDA • History • Why Scala? • Scala in the wild • The Code / Scala in practice • Tools & more Dienstag, 03. Dezember 13

Slide 5

Slide 5 text

@elmanu HISTORY • Martin Odersky, EPFL • Espresso, Pizza, GJ, javac • Funnel, Scala • First Scala release in 2003 Dienstag, 03. Dezember 13

Slide 6

Slide 6 text

@elmanu AGENDA • History • Why Scala? • Scala in the wild • The Code / Scala in practice Dienstag, 03. Dezember 13

Slide 7

Slide 7 text

@elmanu SCALA DESIGN GOALS Dienstag, 03. Dezember 13

Slide 8

Slide 8 text

@elmanu SCALA DESIGN GOALS • Full interoperability with Java Dienstag, 03. Dezember 13

Slide 9

Slide 9 text

@elmanu SCALA DESIGN GOALS • Full interoperability with Java • Cut down boilerplate Dienstag, 03. Dezember 13

Slide 10

Slide 10 text

@elmanu SCALA DESIGN GOALS • Full interoperability with Java • Cut down boilerplate • Pure object orientation & functional programming Dienstag, 03. Dezember 13

Slide 11

Slide 11 text

@elmanu SCALA DESIGN GOALS • Full interoperability with Java • Cut down boilerplate • Pure object orientation & functional programming • Move away from null Dienstag, 03. Dezember 13

Slide 12

Slide 12 text

@elmanu SCALA DESIGN GOALS • Full interoperability with Java • Cut down boilerplate • Pure object orientation & functional programming • Move away from null • Multi-core programming Dienstag, 03. Dezember 13

Slide 13

Slide 13 text

@elmanu AGENDA • History • Why Scala? • Scala in the wild • The Code / Scala in practice • Tools & more Dienstag, 03. Dezember 13

Slide 14

Slide 14 text

@elmanu WHAT PEOPLE SAY If I were to pick a language today other than Java, it would be Scala. James Gosling Father of Java Dienstag, 03. Dezember 13

Slide 15

Slide 15 text

@elmanu WHAT PEOPLE SAY I can honestly say if someone had shown me the Programming Scala book by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I’d probably have never created Groovy. James Strachan Creator of Groovy http://macstrac.blogspot.co.at/2009/04/scala-as-long-term-replacement-for.html Dienstag, 03. Dezember 13

Slide 16

Slide 16 text

@elmanu ThoughtWorks TechRadar May 2013 http://www.thoughtworks.com/radar Dienstag, 03. Dezember 13

Slide 17

Slide 17 text

@elmanu ThoughtWorks TechRadar May 2013 http://www.thoughtworks.com/radar Dienstag, 03. Dezember 13

Slide 18

Slide 18 text

@elmanu SCALA IN THE WILD etc. Dienstag, 03. Dezember 13

Slide 19

Slide 19 text

@elmanu SCALA IN THE WILD Dienstag, 03. Dezember 13

Slide 20

Slide 20 text

@elmanu SCALA IN THE WORLD http://www.scala-tribes.org/ Dienstag, 03. Dezember 13

Slide 21

Slide 21 text

@elmanu SCALA IN VIENNA • Scala Vienna User Group • 1 year old, 124+ members • http://scala-vienna.org/ Dienstag, 03. Dezember 13

Slide 22

Slide 22 text

@elmanu AGENDA • History • Why Scala? • Scala in the wild • The Code / Scala in practice • Tools & more Dienstag, 03. Dezember 13

Slide 23

Slide 23 text

@elmanu AVOIDING THE BILLION- DOLLAR MISTAKE But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement Tony Hoare Creator of ALGOL Dienstag, 03. Dezember 13

Slide 24

Slide 24 text

@elmanu AVOIDING THE BILLION- DOLLAR MISTAKE val maybeUser: Option[User] = User.findOneByName("bob") // returns Some[User] maybeUser == None // false maybeUser.foreach { user => println(user.fullName) // prints "Bob Marley" if there is a user! } val name = maybeUser.map(_.name).getOrElse("Unknown user") Dienstag, 03. Dezember 13

Slide 25

Slide 25 text

@elmanu CONCISENESS public class User { ! private String name; ! private String surname; ! private String email; ! public User(String name, String surname, String email) { ! ! this.name = name; ! ! this.surname = surname; ! ! this.email = email; ! } ! public void setName(String name) { ! ! this.name = name; ! } ! public void setSurname(String surname) { ! ! this.surname = surname; ! } ! public void setEmail(String email) { ! ! this.email = email ! } ! public String getName() { ! ! return this.name; ! } ! public String getSurname() { ! ! return this.surname; ! } ! public String getEmail() { ! ! return this.surname; ! } } Dienstag, 03. Dezember 13

Slide 26

Slide 26 text

@elmanu CONCISENESS class User( var name: String, var surname: String, var email: String) val bob = new User("Bob", "Marley", "[email protected]") // bob: User = User@5c3f1224 bob.name // res0: String = Bob bob.name = "Bobby" // bob.name: String = Bobby Dienstag, 03. Dezember 13

Slide 27

Slide 27 text

@elmanu CONCISENESS public class ImmutableUser { ! private final String name; ! private final String surname; ! private final String email; ! public ImmutableUser(String name, String surname, String email) { ! ! this.name = name; ! ! this.surname = surname; ! ! this.email = email; ! } ! public String getName() { ! ! return this.name; ! } ! public String getSurname() { ! ! return this.surname; ! } ! public String getEmail() { ! ! return this.surname; ! } ! @Override public int hashCode() { ! ! // yada yada yada ! } ! @Override public boolean equals(Object that) { ! ! // yada yada yada ! } } Dienstag, 03. Dezember 13

Slide 28

Slide 28 text

@elmanu CONCISENESS case class ImmutableUser( name: String, surname: String, email: String) val bob = ImmutableUser("Bob", "Marley", "[email protected]") // hashcode and equals for free! val namedBob = ImmutableUser(name = "Bob", surname = "Marley", email = "email") val bobby = bob.copy(name = "Bobby") // returns a User with name Bobby bob.toString // res0: String = ImmutableUser(Bob,Marley,email) Dienstag, 03. Dezember 13

Slide 29

Slide 29 text

@elmanu USEFUL TYPE INFERENCE Dienstag, 03. Dezember 13

Slide 30

Slide 30 text

@elmanu USEFUL TYPE INFERENCE val foo = "Bar" // foo: String = Bar val answer = 42 // answer: Int = 42 val price = 9.99 // price: Double = 9.99 val nums = List(1, 2, 3) // nums: List[Int] = List(1, 2, 3) val map = Map("abc" -> List(1, 2, 3)) // map: scala.collection.immutable.Map[String,List[Int]] = Map(abc -> List(1, 2, 3)) Dienstag, 03. Dezember 13

Slide 31

Slide 31 text

@elmanu EXPLICIT TYPING val foo: String = "Bar" // foo: String = Bar val answer: Int = 42 // answer: Int = 42 val price: Double = 9.99 // price: Double = 9.99 val nums: List[Int] = List(1, 2, 3) // nums: List[Int] = List(1, 2, 3) val map: Map[String, List[Int]] = Map("abc" -> List(1, 2, 3)) // map: scala.collection.immutable.Map[String,List[Int]] = Map(abc -> List(1, 2, 3)) Dienstag, 03. Dezember 13

Slide 32

Slide 32 text

@elmanu COLLECTION LIBRARY & FUNCTIONAL STYLE users.sort(new Comparator { public int compare(Object user1, Object user2) { ! int userAge1 = ((User) user1).getAge(); ! int userAge2 = ((User) user2).getAge(); ! if (userAge1 > userAge2) { ! ! return 1; ! } else if userAge1 < userAge2) { ! ! ! return -1; ! ! } else { ! ! ! return 0; ! ! } ! } }); Dienstag, 03. Dezember 13

Slide 33

Slide 33 text

@elmanu COLLECTION LIBRARY & FUNCTIONAL STYLE def sortByAge(user1: User, user2: User) = user1.age > user2.age users.sortWith(sortByAge) Dienstag, 03. Dezember 13

Slide 34

Slide 34 text

@elmanu COLLECTION LIBRARY & FUNCTIONAL STYLE users.sortWith((user1, user2) => user1.age > user2.age) Dienstag, 03. Dezember 13

Slide 35

Slide 35 text

@elmanu COLLECTION LIBRARY & FUNCTIONAL STYLE users.sortWith(_.age > _.age) Dienstag, 03. Dezember 13

Slide 36

Slide 36 text

@elmanu COLLECTION LIBRARY & FUNCTIONAL STYLE List minors = new ArrayList(); List majors = new ArrayList(); for (User u : users) { ! if (u.getAge() < 18) { ! ! minors.add(u); ! } else { ! ! majors.add(u); ! } } Dienstag, 03. Dezember 13

Slide 37

Slide 37 text

@elmanu COLLECTION LIBRARY & FUNCTIONAL STYLE val (minors, majors) = users.partition(_.age < 18) Dienstag, 03. Dezember 13

Slide 38

Slide 38 text

@elmanu COLLECTION LIBRARY & FUNCTIONAL STYLE val minors = users.filter(_.age < 18) Dienstag, 03. Dezember 13

Slide 39

Slide 39 text

@elmanu • Minimal language, powerful library • Language features for extensibility EXTENSIBLE LANGUAGE Dienstag, 03. Dezember 13

Slide 40

Slide 40 text

@elmanu DOMAIN SPECIFIC LANGUAGES import collection.mutable.Stack import org.scalatest._ class ExampleSpec extends FlatSpec with Matchers { "A Stack" should "pop values in last-in-first-out order" in { val stack = new Stack[Int] stack.push(1) stack.push(2) stack.pop() should be (2) stack.pop() should be (1) } it should "throw NoSuchElementException if an empty stack is popped" in { val emptyStack = new Stack[Int] a [NoSuchElementException] should be thrownBy { emptyStack.pop() } } } Dienstag, 03. Dezember 13

Slide 41

Slide 41 text

@elmanu DOMAIN SPECIFIC LANGUAGES import collection.mutable.Stack import org.scalatest._ class ExampleSpec extends FlatSpec with Matchers { "A Stack" should "pop values in last-in-first-out order" in { val stack = new Stack[Int] stack.push(1) stack.push(2) stack.pop() should be (2) stack.pop() should be (1) } it should "throw NoSuchElementException if an empty stack is popped" in { val emptyStack = new Stack[Int] a [NoSuchElementException] should be thrownBy { emptyStack.pop() } } } Dienstag, 03. Dezember 13

Slide 42

Slide 42 text

@elmanu MACROS • Compile-time, during type checking • Expanding the AST • Experimental since Scala 2.10 http://scalamacros.org Dienstag, 03. Dezember 13

Slide 43

Slide 43 text

@elmanu MACROS PLAY JSON DE/SERIALIZATION Dienstag, 03. Dezember 13

Slide 44

Slide 44 text

@elmanu MACROS PLAY JSON DE/SERIALIZATION case class Creature(name: String, isDead: Boolean, weight: Float) implicit val creatureReads: Reads[Creature] = ( (__ \ "name").read[String] and (__ \ "isDead").read[Boolean] and (__ \ "weight").read[Float] )(Creature) implicit val creatureWrites: Writes[Creature] = ( (__ \ "name").write[String] and (__ \ "isDead").write[Boolean] and (__ \ "weight").write[Float] )(unlift(Creature.unapply)) Dienstag, 03. Dezember 13

Slide 45

Slide 45 text

@elmanu MACROS PLAY JSON DE/SERIALIZATION import play.api.json._ implicit val creatureFormat = Json.format[Creature] // format is a macro Dienstag, 03. Dezember 13

Slide 46

Slide 46 text

@elmanu AGENDA • History • Why Scala? • Scala in the wild • The Code / Scala in practice • Tools & more Dienstag, 03. Dezember 13

Slide 47

Slide 47 text

@elmanu IDE • IntelliJ IDEA • Eclipse • SublimeText Dienstag, 03. Dezember 13

Slide 48

Slide 48 text

@elmanu SIMPLE BUILD TOOL name := "My Project" version := "1.0" organization := "org.myproject" libraryDependencies += "org.scala-tools.testing" %% "scalacheck" % "1.8" % "test" libraryDependencies ++= Seq( "net.databinder" %% "dispatch-meetup" % "0.7.8", "net.databinder" %% "dispatch-twitter" % "0.7.8" ) javaOptions += "-Xmx256m" logLevel in compile := Level.Warn Dienstag, 03. Dezember 13

Slide 49

Slide 49 text

@elmanu PLAY! FRAMEWORK • MVC web framework, inspired by RoR and Django • Java, Scala • Everything is compiled • Predictable & scalable performance • Fun to work with! Dienstag, 03. Dezember 13

Slide 50

Slide 50 text

@elmanu PLAY! FRAMEWORK • MVC web framework, inspired by RoR and Django • Java, Scala • Everything is compiled • Predictable & scalable performance • Fun to work with! Dienstag, 03. Dezember 13

Slide 51

Slide 51 text

@elmanu AKKA • Toolkit for building concurrent & distributed applications more easily • Actors as concurrency model, simpler to reason with than threads • Remoting and clustering support Dienstag, 03. Dezember 13

Slide 52

Slide 52 text

REACTIVE http://www.reactivemanifesto.org Dienstag, 03. Dezember 13

Slide 53

Slide 53 text

@elmanu THANK YOU! Questions, comments ? http://manuel.bernhardt.io [email protected] @elmanu Dienstag, 03. Dezember 13

Slide 54

Slide 54 text

@elmanu FRAMEWORKS: AKKA • Actor concurrency model based on Erlang • “Human” design: actors talk to eachother and form hierarchies • Much, much, much simpler to work and reason with than threads Dienstag, 03. Dezember 13

Slide 55

Slide 55 text

@elmanu FRAMEWORKS: AKKA Source: http://prabhubuzz.wordpress.com/2012/09/28/akka-really-mountains-of-concurrency/ Dienstag, 03. Dezember 13

Slide 56

Slide 56 text

@elmanu FRAMEWORKS: AKKA class Master extends Actor { ! val workers = context.actorOf(Props[Worker].withRouter( ! RoundRobinRouter(nrOfInstances = 5)) ! ) ! def receive = { ! ! case Start => ! ! ! getDocumentsFromDb.foreach { document => ! ! ! ! workers ! Process(document) ! ! ! } ! ! case Result(processed) => ! ! ! writeResult(processed) ! ! case Stop => ! ! ! children.foreach(stop) ! } } Dienstag, 03. Dezember 13

Slide 57

Slide 57 text

@elmanu FRAMEWORKS: AKKA class Worker extends Actor { ! def receive = { ! ! case Process(doc: Document) => ! ! ! val processed = doSomeHardWork(doc) ! ! ! sender ! Result(processed) ! } } Dienstag, 03. Dezember 13

Slide 58

Slide 58 text

@elmanu FRAMEWORKS: PLAY • MVC framework à la Rails • Everything is compiled • I mean everything: CSS, JavaScripts, Templates, URLs, JSON, ... Dienstag, 03. Dezember 13

Slide 59

Slide 59 text

@elmanu FRAMEWORKS: PLAY GET /users controllers.Users.list POST /users controllers.Users.create PUT /users/:id/update controllers.Users.update(id: Long) DELETE /users/:id controllers.Users.delete(id: Long) Dienstag, 03. Dezember 13

Slide 60

Slide 60 text

@elmanu FRAMEWORKS: PLAY class Users extends Controller { def list = Action { request => val users = User.findAll Ok(Json.toJson(users)) } } Dienstag, 03. Dezember 13

Slide 61

Slide 61 text

@elmanu FRAMEWORKS: PLAY class Users extends Controller { def list = Action { request => val users = User.findAll Ok(Json.toJson(users)) } } 200 OK Content-Type: application/json Dienstag, 03. Dezember 13