Introduktion till Scala Viktor Lövgren / ! @vlovgr
Martin Odersky
• Ph.D. ETH, Zurich. • EPFL, Lausanne. • Javac / Generics. • Scala, sedan 2001.
• Organisation grundad av Martin Odersky. • Leder utvecklingen av flera öppna projekt.
• Scala, Akka, Play, Slick, SBT, Scala IDE, … • Bra resurs för material runt dessa verktyg. • Teknikval förklaras av Reactive Manifesto.
Typesafe
• Imperativ- och funktionell programmering. • Skalbart, kan växa med användarnas behov. • Byggt ovanpå Java, kompilerar till bytecode. • Kraftfullt typsystem, grymma collections. • Möjlighet till domänspecifika språk (DSLs).
Scala i korta drag
Scala — exempel för aktieköp
// use premium pricing strategy new Order to buy(100 sharesOf "IBM") maxUnitPrice 300 using premiumPricing !
// use default pricing strategy new Order to buy(200 sharesOf "GOOGLE") maxUnitPrice 300 using defaultPricing !
// use custom pricing strategy new Order to sell(200 bondsOf "Sun") maxUnitPrice 300 using { (qty, unit) => qty * unit - 500 }
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } }
Java — Hello World
object HelloWorld extends App { def main(args: Array[String]) { println("Hello, World!") } }
Scala — Hello World
“Java features not kept in Scala: public, static, void, … the first three words
every Java programmer learns.”
— Martin Odersky
• Open source byggverktyg för Scala och Java. • Kan jämföras vid Maven eller Ant för Java. • Beroenden hanteras med Apache Ivy. • Inkrementell kompilering, interaktivt skal. • Plugins för det mesta man kan tänka sig.
Scala Build Tool (SBT)
• Utvecklingsmiljö: IntelliJ, Eclipse (Scala IDE). • Installera Scala Build Tool (SBT) eller Scala. • Starta Scalas interaktiva skal (REPL).
• Read-Evaluate-Print-Loop (REPL). • Alternativt, använd Scala Worksheets.
Komma igång
brew install scala scala
Installation (Mac)
brew install sbt sbt console
Installation (Mac)
Demo: Komma igång
• Java 8 kom med mycket ny funktionalitet. • Lambda-uttryck, streams, parallella streams. • Idéerna kan ses som inspirerade av Scala. • Scala har betydligt mer än så att erbjuda. • Låt oss titta på exempel för att visa det.
Java 8 — behövs Scala?
// 61 rader kod i Java public final class Person { !
private String name; private int age; !
public Person(final String name, final int age) { ... } !
// getName, setName, getAge, setAge // apply, copy, equals, hashCode, toString }
Java — enkel modell
// 1 rad kod i Scala case class Person(name: String, age: Int)
Scala — enkel modell
lazy val x = 42
val list = List(1, 2, 3) val map = Map(1 -> 2, 2 -> 4)
val range = 1 until 10 // 1, 2, ... 9 val even = 2 to 10 by 2 // 2, 4, ... 10
val square = (x: Int) => x * x def square(x: Int) = x * x
def multiply(x: Int*) = x.fold(1)(_ * _) def square(x: Int) = multiply(x, x)
Scala — enklare funktionalitet
val success = Try(Source.fromFile("ok.txt")) val failure = Try(Source.fromFile("nope.txt"))
val successLines = success.map(_.getLines) // Success med raderna val failureLines = failure.map(_.getLines) // Failure med felet
success.foreach(line => println(line)) // Skriver ut raderna failure.foreach(println(_)) // Inget händer
Scala — try, combinators
def even(x: Int) = if(x % 2 == 0) Some(x) else None
val two = even(2) // Some(2) val three = even(3) // None
two.map(_ * 2) // Some(4) three.map(_ * 2) // None
Scala — option, combinators
val result = for { response <- request(“some/rest/api“) someField = response.toJSON.find("some.property") if someField == "someValue"} yield { // Gör något med response}
result match { case Success(result) => // Success; gör något med resultatet case Failure(x) => // Failure; x beskriver det }
Scala — sequence comprehensions, pattern matching
val x = try { ... } catch { ... } !
val y = if(...) else ... !
val z = for(...) yield { ... } !
!
val first = if(true) 3 else "ok" // Any = 3 !
val second = if(true) 3 else 5.0 // Double = 3.0
Scala — expressions
class Student(name: String) !
trait Worker { def salary = 30000 } !
trait Underpaid { def salary = 10000 } !
object Bob extends Student("Bob") with Worker with Underpaid { override def salary = super.salary }
Scala — traits
// Lägg dit en ny metod till klassen File implicit class RichFile(val file: File) extends AnyVal { def unzip(newFolder: File) = ZipUtil.unpack(file, newFolder) }
Scala — implicit classes
val pair = ("apples", 3) val (fruit, count) = pair !
println(fruit) // “apples” println(count) // 3
Scala — tuples
val cityPopulation = Map( ("US", "GA", "Rome") -> 36303, ("Italy", "Rome") -> 2753000 ) !
cityPopulation.get(("Italy", "Rome")) cityPopulation.get(("US", "GA", "Rome"))
Scala — färdiga equals, hashcode
// String interpolation val x = "variables" s"I can embed $x in code!”
// Multiline strings val s = """ put here anything you want including " or ' """
Scala — strings
// Funktion med standardvärden def concat(x: String = "", y: String = "") = x + y
// Använd standardvärdet för x concat(y = "text")
Scala — standardvärden, namngivna argument
• Flera möjliga val, t.ex. ScalaTest, ScalaCheck. • ScalaTest har färdigt stöd för bl.a. TDD/BDD. • ScalaCheck: property-based testing.
• Generera random input; kör flera gånger. • ScalaTest och ScalaCheck kan kombineras.
Testning i Scala
• Möjlighet till implicita argument. • Allting är immutable som standard. • Undvik null (använd Option istället). • Futures/promises för framtida resultat. • JavaConversions / JavaConverters.
Annat bra att veta om i Scala
• Det tar längre tid att kompilera för Scala. • Ingen binär-kompabilitet som i Java. • ... ?
Nackdelar med Scala vs. Java
“I am 100% sure you will not find a single Scala developer that will say: ‘Java 8 got
lambdas? great, goodbye Scala forever!’.”
— Eran Medan
Case: betygen.se
• Universitetets tjänst för tentamensresultat. • Kunna se statistik på tentamensresultat. • Data finns redan, men inte lättillgänglig. • Idé: hämta och lagra resultaten.
Tentamensresultat
• Generera en query mot universitetets tjänst. • Använd en parser som läser data från svaret. • Upprepa för varje sida (10 tentamen/sida). • Problem: hur får vi tag i alla resultat?
Hämta och lagra resultaten
• Problem: tjänstens paginering är långsam. • Möjligt att söka efter resultat i datumperiod. • Idé: dela upp sökning i en mängd perioder. • Behöver bara ta reda på det äldsta resultatet. • Kör flera parallella queries med Akka.
Hämta och lagra resultaten
• Verktyg för concurrency, distributed apps. • Bygger på message-passing mellan actors. • Actors ordnas i en hierarki; felhantering. • Kommunikation är location transparent. • Många ramverk bygger på Akka, t.ex. Play.
Akka
• Idé: skriv ett API för att komma åt resultat. • MongoDB redan valt med detta i åtanke. • Flera möjliga teknikval i Scala för detta.
• Exempelvis: Play framework, Spray. • Båda ramverken är byggda med Akka.
Gör resultaten mer lättillgängliga
• Refresh workflow / Type safety överallt. • Det mesta för modern webbutveckling.
• RESTful som standard, bra JSON-stöd. • Plugins för LESS/SASS, CoffeeScript, etc. • Skalbart med Akka / Java NIO (Jetty).
Play Framework
• En komplett IDE byggd som en webbapp. • Många exempelprojekt med olika tekniker. • Guider integreras smidigt i projekten. • Enkelt att komma igång och testa.
Typesafe Activator
Installation (Mac)
brew install typesafe-activator activator
• Data är nu lättillgänglig — använd den. • Lanserade betygen.se i början av augusti. • Använder Play framework i grunden. • WebJars för client-side dependencies.
Bygg en webbtjänst för statistik
• Grundläggande funktionalitet i Java, 2012. • Allt skrevs om från grunden i Scala, 2014. • 1/4 så lite kod i Scala (1100 rader vs. 4500). • Mindre dokumentation (0 rader vs. 2500). • Lättare och mer naturlig syntax i Scala.
Lösning i Scala vs. Java
Lösning i Scala vs. Java
// Java; ServiceQuery ~ 234 rader kod final ServiceQuery query = new ServiceQuery.Builder() .examinationDate(DateRange.after(Date.year(2012))) .courseName("envariabel").build(); !
// Scala; Query ~ 63 rader kod val query = Query(Course(name = "envariabel"), date = from(2012))
" github.com/betygen
• Lätt att komma igång, roligt att använda. • Funktionellt med styrkorna i Java (JVM). • Skalbarhet i grunden, väx efter behov. • Interagera med existerande Java-system. • Används av stora företag — fler följer?
Sammanfattning — varför Scala?
• Coursera (kurser av Martin Odersky): • Grundkurs: Functional programming. • Fortsättning: Reactive programming.
• Böcker, t.ex. Scala for the Impatient. • Konferenser, t.ex. Scala Days.
Lär dig mera
• Awesome Scala — lista över Scala-verktyg. • Scala Times — nyhetsbrev varje vecka. • StackOverflow Scala — bra översikt av Scala. • Scala Stockholm — meetup-grupp för Scala.
Lär dig mera
Tack för mig! Viktor Lövgren / ! @vlovgr