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

Scala - Java2Days Sofia

Scala - Java2Days Sofia

This is a short introduction to the Scala programming language and its ecosystem, giving some background about how the language came to be and a quick taste of what it looks like. It also shortly introduces a few tools and technologies related to it

Manuel Bernhardt

April 27, 2022
Tweet

More Decks by Manuel Bernhardt

Other Decks in Programming

Transcript

  1. @elmanu AGENDA • History • Why Scala? • Scala in

    the wild • The Code / Scala in practice • Tools & more Dienstag, 03. Dezember 13
  2. @elmanu YOUR SPEAKER • Independent software consultant based in Vienna

    • Web, web, web • Scala & Java & Javascript • Open-Source Dienstag, 03. Dezember 13
  3. @elmanu AGENDA • History • Why Scala? • Scala in

    the wild • The Code / Scala in practice • Tools & more Dienstag, 03. Dezember 13
  4. @elmanu HISTORY • Martin Odersky, EPFL • Espresso, Pizza, GJ,

    javac • Funnel, Scala • First Scala release in 2003 Dienstag, 03. Dezember 13
  5. @elmanu AGENDA • History • Why Scala? • Scala in

    the wild • The Code / Scala in practice Dienstag, 03. Dezember 13
  6. @elmanu SCALA DESIGN GOALS • Full interoperability with Java •

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

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

    Cut down boilerplate • Pure object orientation & functional programming • Move away from null Dienstag, 03. Dezember 13
  9. @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
  10. @elmanu AGENDA • History • Why Scala? • Scala in

    the wild • The Code / Scala in practice • Tools & more Dienstag, 03. Dezember 13
  11. @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
  12. @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
  13. @elmanu SCALA IN VIENNA • Scala Vienna User Group •

    1 year old, 124+ members • http://scala-vienna.org/ Dienstag, 03. Dezember 13
  14. @elmanu AGENDA • History • Why Scala? • Scala in

    the wild • The Code / Scala in practice • Tools & more Dienstag, 03. Dezember 13
  15. @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
  16. @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
  17. @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
  18. @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
  19. @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
  20. @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
  21. @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
  22. @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
  23. @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
  24. @elmanu COLLECTION LIBRARY & FUNCTIONAL STYLE def sortByAge(user1: User, user2:

    User) = user1.age > user2.age users.sortWith(sortByAge) Dienstag, 03. Dezember 13
  25. @elmanu COLLECTION LIBRARY & FUNCTIONAL STYLE List<User> minors = new

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

    users.partition(_.age < 18) Dienstag, 03. Dezember 13
  27. @elmanu • Minimal language, powerful library • Language features for

    extensibility EXTENSIBLE LANGUAGE Dienstag, 03. Dezember 13
  28. @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
  29. @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
  30. @elmanu MACROS • Compile-time, during type checking • Expanding the

    AST • Experimental since Scala 2.10 http://scalamacros.org Dienstag, 03. Dezember 13
  31. @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
  32. @elmanu MACROS PLAY JSON DE/SERIALIZATION import play.api.json._ implicit val creatureFormat

    = Json.format[Creature] // format is a macro Dienstag, 03. Dezember 13
  33. @elmanu AGENDA • History • Why Scala? • Scala in

    the wild • The Code / Scala in practice • Tools & more Dienstag, 03. Dezember 13
  34. @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
  35. @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
  36. @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
  37. @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
  38. @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
  39. @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
  40. @elmanu FRAMEWORKS: AKKA class Worker extends Actor { ! def

    receive = { ! ! case Process(doc: Document) => ! ! ! val processed = doSomeHardWork(doc) ! ! ! sender ! Result(processed) ! } } Dienstag, 03. Dezember 13
  41. @elmanu FRAMEWORKS: PLAY • MVC framework à la Rails •

    Everything is compiled • I mean everything: CSS, JavaScripts, Templates, URLs, JSON, ... Dienstag, 03. Dezember 13
  42. @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
  43. @elmanu FRAMEWORKS: PLAY class Users extends Controller { def list

    = Action { request => val users = User.findAll Ok(Json.toJson(users)) } } Dienstag, 03. Dezember 13
  44. @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