Your SlideShare is downloading. ×
0
def scala = oop + fpПавел Павлов
О себеЗанимаюсь системным программированием● компиляторы, среды исполнения● Excelsior JET - JVM with AOT compiler● код на ...
Язык Scala: характеристика● компилируемый● строго статически типизированный● автоматический вывод типов● OOP + FP● "лёгкий...
Язык Scala: цели● Язык общего назначения● Альтернатива/замена Java● Внедрение FP в mainstream● Преодоление "застоя" в OOPЦ...
Язык Scala: история
Язык Scala: историяMartin Odersky
Язык Scala: историяMartin Odersky Philip Wadler
Язык Scala: историяАвтор: Martin Odersky (EPFL)1995-2001 Pizza language (Odersky & Wadler)"better Java": Java + generics, ...
Язык Scala: популярность● 11 место - RedMonk Programming LanguageRankings (StackOverflow, GitHub)● 36 место - TIOBE index(...
http://www.infoq.com/research/next-jvm-language
Success story: Twitter● 2006: начало - всё на Ruby on Rails● 2007-2008: взрывной рост популярности
Success story: Twitter● 2006: начало - всё на Ruby on Rails● 2007-2008: взрывной рост популярностиРешение:+
Hello, REPL!scala> val repl = Map(R -> "Read", E -> "Eval",| P -> "Print", L -> "Loop")repl: immutable.Map[Char,String] = ...
Синтаксис: values & variablesval x: Int = 42val ys = List(1, 2, 3) // y: List[Int]var z = "hello" // z: String
Синтаксис: values & variablesval x: Int = 42val ys = List(1, 2, 3) // y: List[Int]var z = "hello" // z: Stringmake val not...
Синтаксис: functionsval x: Int = 42val ys = List(1, 2, 3) // y: List[Int]var z = "hello" // z: Stringdef max(a: Int, b: In...
Синтаксис: основыval x: Int = 42val ys = List(1, 2, 3) // y: List[Int]var z = "hello" // z: Stringdef max(a: Int, b: Int):...
abstract class Animal {def name: String}class Person(firstName: String, lastName: String)extends Animal {val name = firstN...
trait Ordered[A] {def compare(that: A): Intdef < (that: A): Boolean = (this compare that) < 0def > (that: A): Boolean = (t...
Scala = OOP + FPКак скрестить ужа с ежом?1. дешёвая китайская имитацияJava 8 lambdas2. мухи отдельно, котлеты отдельно3. к...
Синтаксический сахар● бесскобочные методы● auto-generated accessors● операторы = методы,● операторный синтаксис● apply, up...
Uniform Access PrincipleВсе услуги, предлагаемые модулем должныбыть доступны через единую нотацию,которая не раскрывает, р...
class Foo(val r1: Int) { // <- auto-generated gettervar rw1: Int // <- auto-generated getter & setterdef r2: Int = ???priv...
Methods and operatorsList(1, 2, 3).map(inc) // List(2, 3, 4)List(1, 2, 3) map inc // <- операторный синтаксисabstract clas...
val inverse = { x: Int => 1.0 / x }inverse(1) // => inverse.apply(1)val a = Array(0.33, 0.5) // => Array.apply(0.33, 0.5)a...
Функциональные типы:(A => B) // Function1[A, B]trait Function1[A, B] {def apply(x: A): B}val inc = { x: Int => x + 1 }val ...
Case classes and pattern matching● Pattern matching - обобщённый switch/case● Case classes - реализация ADTПреимущества Sc...
Case classescase class Person(name: String, age: Int)class Person(val name: String, val age: Int)extends Serializable {ove...
Case classes as ADTcase class Person(name: String, age: Int)val p = Person("John", 20)println(p) // Person(John,20)val q =...
Pattern matchingval anything: Any = ...val str = anything match {case 1 => "one"case x: Int if x > 0 => "positive integer"...
sealed class Exprcase class Var(name: String) extends Exprcase class Num(value: Int) extends Exprcase class Neg(arg: Expr)...
Extractor objectsobject PowerOfTwo {import java.lang.Long.{numberOfLeadingZeros => nlz}def apply(i: Int): Long = 1L << ide...
Pattern matching everywheredef foo(x: Int) = (x, x*x*x) // Int => (Int, Int)val xs = List(1,2,3) map foo // List((1,1),(2,...
Partial functionsclass List[T] {def collect[U](pf: PartialFunction[T,U]): List[U] = {val buf: Buffer[U] = ...for(elem <- t...
Types hierarchy
Типы● value & reference types● top & bottom types● compound types● параметризация (generics)○ variance: co- & contra-○ upp...
А также● mixin composition● implicits: extension methods, type classes● typesafe dependency injection● compound types● str...
Internal DSLs
Macrosdef assert(cond: Boolean, msg: Any) = macro Asserts.assertImplobject Asserts {def raise(msg: Any) = throw new Assert...
Scala Collections
Scala Collections: API● functional-style● collect, count, exists, filter, find, flatMap, fold, forall,foreach, groupBy, ma...
for comprehension● обобщённый цикл for○ с поддержкой фильтров и pattern matching● преобразователь потоков данных● язык зап...
for loop: basic formval files: Seq[File] = ...for (file <- files) {println(file.getName)}files foreach { file =>println(fi...
for loop: filters & nested loopsdef content(f: File): Seq[String] = ???for (file <- files) {if (!file.getName.startsWith("...
for loop: filters & nested loopsdef content(f: File): Seq[String] = ???for {file <- filesif !file.getName.startsWith(".")l...
def content(f: File): Seq[String] = ???val lines = for {file <- filesif !file.getName.startsWith(".")line <- content(file)...
for loop: pattern matchingval Email = """(w+)@([w.]+)""".rdef emails(strs: String*) =for (Email(name, domain) <- strs) yie...
Basic Haskell - Scala dictionaryHaskell Scalax :: a, T a, [a] x : A, T[A], List[A]x : xs, [1,2], [1..n] x :: xs, List(1,2)...
Parallelism & concurrencyval people: Seq[Person] = ...val (minors, adults) = people partition (_.age < 18)
Parallelism & concurrencyval people: Seq[Person] = ...val (minors, adults) = people.par partition (_.age < 18)
Parallelism & concurrencyval people: Seq[Person] = ...val (minors, adults) = people.par partition (_.age < 18)actor {recei...
Futures & promisesFuture● Хранилище для значения, которое будетполучено в будущем● Получение значение может бытьвыполнено ...
Futuresval f: Future[List[String]] = future {session.getRecentPosts}f onSuccess {case posts =>for (p <- posts) println(p)}...
Combining futuresval usdQuote = future { connection.getCurrentValue(USD) }val chfQuote = future { connection.getCurrentVal...
Promisesval p = promise[T}val f = p.futureval producer = future {val r = produceSomething()p success rcontinueDoingSomethi...
Promisesdef first[T}(f: Future[T], g: Future[T]): Future[T] = {val p = promise[T]f onSuccess { case x => p.tryComplete(x) ...
Akka● Toolkit & runtime for building concurrent,distributed & fault tolerant applications● Actors● Remoting: location tran...
ToolsIDEs: IDEA, Eclipse, NetBeans+ Emacs, vim, Sublime, TextMateBuilding: SBTbut also ant, Maven, etc...Testing: ScalaTes...
Libraries & frameworksDB query & access: Slick (LINQ-like)UI: ScalaFXText processing: parser combinators (stdlib)GPGPU: Sc...
Excelsior: наш опыт● Оптимизирующий компилятор● Новое ядро, implemented from scratch● R&D "по-взрослому"
Excelsior: наш опыт● Оптимизирующий компилятор● Новое ядро, implemented from scratch● R&D "по-взрослому"● Команда: ≤5 чело...
Excelsior: наш опыт● Оптимизирующий компилятор● Новое ядро, implemented from scratch● R&D "по-взрослому"● Команда: ≤5 чело...
Excelsior: наш опыт● Оптимизирующий компилятор● Новое ядро, implemented from scratch● R&D "по-взрослому"● Команда: ≤5 чело...
Excelsior: наш опыт● Оптимизирующий компилятор● Новое ядро, implemented from scratch● R&D "по-взрослому"● Команда: ≤5 чело...
Novosibirsk Scala Enthusiasts
Q / A
Q / A
Immutable classes and objectsTODO
Partial functionstrait Function1[T, R] {def apply(x: T): R}trait PartialFunction[T, R] extends Function1[T, R] {def isDefi...
Scala CollectionsЗдесь картинка - иерархия классовTraversableOnce, Traversable, Iterable,Iterator, Seq, Set, MapSeq: Index...
Типы: иерархия- Картинка- Top & bottom types: Any, Nothing- Основные типы: primitives, Unit, tuples,functions, Option- Сос...
Type variance: определениеПусть есть Foo[T], и A <: B (A != B).Есть три возможности:1. Foo[A] <: Foo[B] - Foo ковариантен ...
Type variance: примерыtrait InChannel[+T] { def get: T }val in: InChannel[String] = ...val x = in.get // x: Stringval in2:...
Type variance: контроль типовclass Cell[+T] { // covariantdef get: T // okdef put(x: T) // compilation error}class Cell[-T...
Type variance: ещё примерыtrait Function1[-T, +R] { // contravariant argument(s)def apply(x: T): R // covariant result}cla...
Параметризация: примерabstract class List[+A] {def head: Adef tail: List[A]def isEmpty: Boolean}final case class Cons[+A](...
Upper & lower type boundsdef max[A <: Ordered[A]](xs: List[A]): A = ???val accounts: Ordered[Money] = ???max(accounts)abst...
Compound Typestrait Cloneable {def clone: Cloneable = ???}trait Resetable {def reset(): Unit}def cloneAndReset(obj: Clonea...
Structural & dynamic typesTODO
Scala
Scala
Scala
Scala
Scala
Scala
Scala
Upcoming SlideShare
Loading in...5
×

Scala

465

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
465
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Scala"

  1. 1. def scala = oop + fpПавел Павлов
  2. 2. О себеЗанимаюсь системным программированием● компиляторы, среды исполнения● Excelsior JET - JVM with AOT compiler● код на орбите (ГЛОНАСС)Преподаю● научное руководство студентами (НГУ)● подготовка юниоров в компанииУчастник Scala community● Scala core committer (stdlib, compiler)● Организовал ScalaNsk
  3. 3. Язык Scala: характеристика● компилируемый● строго статически типизированный● автоматический вывод типов● OOP + FP● "лёгкий" синтаксис● работает на платформе JVM● бесшовная интеграция с Java
  4. 4. Язык Scala: цели● Язык общего назначения● Альтернатива/замена Java● Внедрение FP в mainstream● Преодоление "застоя" в OOPЦелевая аудитория:1. Java-программисты (народные массы)Лучший язык, FP2. Ruby/Python(/JS)-программистыСтатическая типизация, производительность3. ФункциональщикиИспользование FP в mainstream
  5. 5. Язык Scala: история
  6. 6. Язык Scala: историяMartin Odersky
  7. 7. Язык Scala: историяMartin Odersky Philip Wadler
  8. 8. Язык Scala: историяАвтор: Martin Odersky (EPFL)1995-2001 Pizza language (Odersky & Wadler)"better Java": Java + generics, function types &closures, ADT & pattern matching1997-1998 Generic Javagenerics & javac compiler => Java language2001-2005 Scala 1.x"better than Java"2006- Scala 2.x2009-2010 Проникновение в индустрию
  9. 9. Язык Scala: популярность● 11 место - RedMonk Programming LanguageRankings (StackOverflow, GitHub)● 36 место - TIOBE index(поисковые запросы)
  10. 10. http://www.infoq.com/research/next-jvm-language
  11. 11. Success story: Twitter● 2006: начало - всё на Ruby on Rails● 2007-2008: взрывной рост популярности
  12. 12. Success story: Twitter● 2006: начало - всё на Ruby on Rails● 2007-2008: взрывной рост популярностиРешение:+
  13. 13. Hello, REPL!scala> val repl = Map(R -> "Read", E -> "Eval",| P -> "Print", L -> "Loop")repl: immutable.Map[Char,String] = Map(...)scala> for ((k, v) <- repl) println(s"$k is for $v")R is for ReadE is for EvalP is for PrintL is for Loop
  14. 14. Синтаксис: values & variablesval x: Int = 42val ys = List(1, 2, 3) // y: List[Int]var z = "hello" // z: String
  15. 15. Синтаксис: values & variablesval x: Int = 42val ys = List(1, 2, 3) // y: List[Int]var z = "hello" // z: Stringmake val not var
  16. 16. Синтаксис: functionsval x: Int = 42val ys = List(1, 2, 3) // y: List[Int]var z = "hello" // z: Stringdef max(a: Int, b: Int): Int = if (a > b) a else bdef inc(x: Int) = x + 1val inc = { x: Int => x + 1 } // inc: Int => Int
  17. 17. Синтаксис: основыval x: Int = 42val ys = List(1, 2, 3) // y: List[Int]var z = "hello" // z: Stringdef max(a: Int, b: Int): Int = if (a > b) a else bdef inc(x: Int) = x + 1val inc = { x: Int => x + 1 } // inc: Int => Intys map inc // List(2, 3, 4)ys map { x => x + 1 }ys map { _ + 1 }ys filter { _ % 2 != 0 } // List(1, 3)ys reduce max // max(1, max(2, 3))ys reduce { (x, y) => x + y } // 1 + 2 + 3
  18. 18. abstract class Animal {def name: String}class Person(firstName: String, lastName: String)extends Animal {val name = firstName + " " + lastName}class Employee(firstName: String, lastName: String,val age: Int, var salary: Double)extends Person(firstName, lastName)object Main extends App {val p = new Employee("John", "Doe", 20, 300.0)println(p.name + " is + p.age + " years old")}Классы и объекты
  19. 19. trait Ordered[A] {def compare(that: A): Intdef < (that: A): Boolean = (this compare that) < 0def > (that: A): Boolean = (this compare that) > 0def <= (that: A): Boolean = (this compare that) <= 0def >= (that: A): Boolean = (this compare that) >= 0}class Money extends SomeTrait with Ordered[Money] {def compare(that: Money) = ...}Traits: множественное наследованиес человеческим лицом
  20. 20. Scala = OOP + FPКак скрестить ужа с ежом?1. дешёвая китайская имитацияJava 8 lambdas2. мухи отдельно, котлеты отдельно3. кодируем объекты функциями4. кодируем функции объектами: Scala wayScala = OO kernel + syntactic sugar
  21. 21. Синтаксический сахар● бесскобочные методы● auto-generated accessors● операторы = методы,● операторный синтаксис● apply, update● for loop● case classes, unapply● implicitsДля чего? UAP, DSLs, extension methods, FP->OOP mapping, pattern matching
  22. 22. Uniform Access PrincipleВсе услуги, предлагаемые модулем должныбыть доступны через единую нотацию,которая не раскрывает, реализованы ли онипосредством хранения либо вычисления.Bertrand Meyer
  23. 23. class Foo(val r1: Int) { // <- auto-generated gettervar rw1: Int // <- auto-generated getter & setterdef r2: Int = ???private[this] var _field = 0def rw2: Int = _fielddef rw2_=(x: Int) { _field = x }}val v: Foo = ...println(v.r1 + v.r2 + v.rw1 + v.rw2)v.rw1 = 42v.rw2 = 43 // v.rw2_=(43)UAP: fields, methods and properties
  24. 24. Methods and operatorsList(1, 2, 3).map(inc) // List(2, 3, 4)List(1, 2, 3) map inc // <- операторный синтаксисabstract class Set[T] {def contains(x: T): Booleandef - (x: T): Set[T]def !@#%^&*-+ : Int // <- пожалуй, так делать нестоит}def foo(s: Set[Int]) {if (s contains 42) println(s - 42)}1 + 3*5 => 1.+(3.*(5))
  25. 25. val inverse = { x: Int => 1.0 / x }inverse(1) // => inverse.apply(1)val a = Array(0.33, 0.5) // => Array.apply(0.33, 0.5)a(1) /*0.5*/ // => a.apply(1)a(0) = 1.0 // => a.update(0, 1.0)def foo(f: Int => Double) {println(f(1)) // => println(f.apply(1))}foo(inverse) // 1.0foo(a) // 0.5Array[T] is a function (Int => T)!Вызов и индексация
  26. 26. Функциональные типы:(A => B) // Function1[A, B]trait Function1[A, B] {def apply(x: A): B}val inc = { x: Int => x + 1 }val inc = new Function1[Int, Int] {def apply(x: Int): Int = { x + 1 }}inc(4) // inc.apply(4)Функции как объекты
  27. 27. Case classes and pattern matching● Pattern matching - обобщённый switch/case● Case classes - реализация ADTПреимущества Scala:● Case class - больше чем ADT:интерфейсы, методы, данные● Pattern matching customizable by user:абстракция логики от структуры данных,DSLs
  28. 28. Case classescase class Person(name: String, age: Int)class Person(val name: String, val age: Int)extends Serializable {override def equals(other: AnyRef) = ...override def hashCode = ...override def toString = ...def copy(name: String = this.name, age: Int = this.age) = ...}object Person extends (String, Int) => Person {def apply(name: String, age: Int) = new Persondef unapply(p: Person): Option((String, Int)) =Some((p.name, p.age))}
  29. 29. Case classes as ADTcase class Person(name: String, age: Int)val p = Person("John", 20)println(p) // Person(John,20)val q = p.copy(name="Sam")q.copy(age = q.age+1) == Person("Sam", 21) // truedef foo(x: Any) = x match {case Person(name, age) => s"$name of $age years"case _ => x.toString}foo(p) // "John of 20 years"foo(123) // "123"
  30. 30. Pattern matchingval anything: Any = ...val str = anything match {case 1 => "one"case x: Int if x > 0 => "positive integer"case x: Float if x > 0 => "positive float"case _: String => "string"case _ => "unknown"}
  31. 31. sealed class Exprcase class Var(name: String) extends Exprcase class Num(value: Int) extends Exprcase class Neg(arg: Expr) extends Exprcase class Add(arg1: Expr, arg2: Expr) extends Exprdef optimize(expr: Expr): Expr = expr match {case Neg(Neg(x)) => optimize(x)case Add(x, Num(0)) => optimize(x)case Neg(Num(x)) => Num(-x)case Add(x, Neg(y)) if x == y => Num(0)case Add(Num(x), Num(y)) => Num(x + y)case Neg(x) => Neg(optimize(x))case Add(x, y) => Add(optimize(x), optimize(y))case _ => expr}ADT in action
  32. 32. Extractor objectsobject PowerOfTwo {import java.lang.Long.{numberOfLeadingZeros => nlz}def apply(i: Int): Long = 1L << idef unapply(x: Long): Option[Int] =if (((x & (x-1)) == 0) && (x > 0))Some(63 - nlz(x)) else None}def optimize(e: Expr) = e match {case Mul(x, PowerOfTwo(n)) => Shl(x, n)case Div(x, PowerOfTwo(n)) => Shr(x, n)case Rem(x, PowerOfTwo(n)) => And(x, PowerOfTwo(n) - 1)}
  33. 33. Pattern matching everywheredef foo(x: Int) = (x, x*x*x) // Int => (Int, Int)val xs = List(1,2,3) map foo // List((1,1),(2,8),(3,27))val (n, c) = xs.last // n = 3, c = 27for ((n, c) <- xs) println(c/n) // 1, 4, 9val zs = xs collect { case (x, y) if x < y => y - x }println(zs) // List(6,24)
  34. 34. Partial functionsclass List[T] {def collect[U](pf: PartialFunction[T,U]): List[U] = {val buf: Buffer[U] = ...for(elem <- this) if(pf isDefinedAt elem) buf += pf(elem)buf.toList}}val zs = xs collect { case (x, y) if x < y => y - x }println(zs) // List(6,24)
  35. 35. Types hierarchy
  36. 36. Типы● value & reference types● top & bottom types● compound types● параметризация (generics)○ variance: co- & contra-○ upper & lower bounds● higher-kinded types● abstract types● self types● dependent types● structural types (typesafe duck typing)
  37. 37. А также● mixin composition● implicits: extension methods, type classes● typesafe dependency injection● compound types● structural & dynamic types● delimited continuations● scala reflection● ...и многое другое
  38. 38. Internal DSLs
  39. 39. Macrosdef assert(cond: Boolean, msg: Any) = macro Asserts.assertImplobject Asserts {def raise(msg: Any) = throw new AssertionError(msg)def assertImpl(c: Context)(cond: c.Expr[Boolean], msg: c.Expr[Any]): c.Expr[Unit] =if (assertionsEnabled)reify { if (!cond.splice) raise(msg.splice) }elsereify { () }}assert(c, "msg") => if(!c) raise("msg")
  40. 40. Scala Collections
  41. 41. Scala Collections: API● functional-style● collect, count, exists, filter, find, flatMap, fold, forall,foreach, groupBy, map, max/min, partition, reduce,splitAt, take, to, ...● примеры:val people: Seq[Person] = ...val (minors, adults) = people partition (_.age < 18)● параллельные коллекции: .par, tuning (thread poolsetc.)
  42. 42. for comprehension● обобщённый цикл for○ с поддержкой фильтров и pattern matching● преобразователь потоков данных● язык запросов● монадический комбинатор● всего лишь синтаксический сахар
  43. 43. for loop: basic formval files: Seq[File] = ...for (file <- files) {println(file.getName)}files foreach { file =>println(file.getName)}val names = for (file <- files) yield file.getNameval names = files map { _.getName }
  44. 44. for loop: filters & nested loopsdef content(f: File): Seq[String] = ???for (file <- files) {if (!file.getName.startsWith(".")) {for (line <- content(file)) {if (line.nonEmpty) {println(file + ": " + line)}}}}
  45. 45. for loop: filters & nested loopsdef content(f: File): Seq[String] = ???for {file <- filesif !file.getName.startsWith(".")line <- content(file)if line.nonEmpty} println(file + ": " + line)files withFilter (!_.getName.startsWith(".")) foreach { file =>content(file) withFilter (_.nonEmpty) foreach { line =>println(file + ": " + line)}}
  46. 46. def content(f: File): Seq[String] = ???val lines = for {file <- filesif !file.getName.startsWith(".")line <- content(file)if line.nonEmpty} yield file + ": " + linefiles withFilter (!_.getName.startsWith(".")) flatMap { file =>content(file) withFilter (_.nonEmpty) map { line =>file + ": " + line}}for loop: filters & nested loops
  47. 47. for loop: pattern matchingval Email = """(w+)@([w.]+)""".rdef emails(strs: String*) =for (Email(name, domain) <- strs) yield (name, domain)emails("foo@bar.com", "qwerty", "q@q.ru")// Seq[(String,String)] = ArrayBuffer((foo,bar.com),(q,q.ru))
  48. 48. Basic Haskell - Scala dictionaryHaskell Scalax :: a, T a, [a] x : A, T[A], List[A]x : xs, [1,2], [1..n] x :: xs, List(1,2), 1 to ntail xs, map f xs xs.tail, xs map fa -> b -> c (A, B) => C | A => B => Cx -> x * sin x x => x * sin(x)Maybe |Just | Nothing Option | Some | Nonea >>= b, fmap, join a flatMap b, map, flattendo{ a<-x; b<-y; return c } for (a<-x; b<-y) yield c
  49. 49. Parallelism & concurrencyval people: Seq[Person] = ...val (minors, adults) = people partition (_.age < 18)
  50. 50. Parallelism & concurrencyval people: Seq[Person] = ...val (minors, adults) = people.par partition (_.age < 18)
  51. 51. Parallelism & concurrencyval people: Seq[Person] = ...val (minors, adults) = people.par partition (_.age < 18)actor {receive {case people: Seq[Person] =>val (minors, adults) = people partition (_.age < 18)School ! minorsWork ! adults}}
  52. 52. Futures & promisesFuture● Хранилище для значения, которое будетполучено в будущем● Получение значение может бытьвыполнено асинхронно и не блокироватьпрограмму● Значение может не быть получено вовсе
  53. 53. Futuresval f: Future[List[String]] = future {session.getRecentPosts}f onSuccess {case posts =>for (p <- posts) println(p)}f onFailure {case t =>println("An error has occurred: " + t.getMessage)}
  54. 54. Combining futuresval usdQuote = future { connection.getCurrentValue(USD) }val chfQuote = future { connection.getCurrentValue(CHF) }val purchase = for {usd <- usdQuotechf <- chfQuoteif isProfitable(usd, chf)} yield connection.buy(amount, chf)purchase onSuccess {case _ => println(s"Purchased $amount CHF")}
  55. 55. Promisesval p = promise[T}val f = p.futureval producer = future {val r = produceSomething()p success rcontinueDoingSomethingUnrelated()}val consumer = future {startDoingSomething()f onSuccess {case r => doSomethingWithResult(r)}}
  56. 56. Promisesdef first[T}(f: Future[T], g: Future[T]): Future[T] = {val p = promise[T]f onSuccess { case x => p.tryComplete(x) }g onSuccess { case x => p.tryComplete(x) }p.future}
  57. 57. Akka● Toolkit & runtime for building concurrent,distributed & fault tolerant applications● Actors● Remoting: location transparent● Supervision & monitoring● Software Transactional Memory● Dataflow concurrency
  58. 58. ToolsIDEs: IDEA, Eclipse, NetBeans+ Emacs, vim, Sublime, TextMateBuilding: SBTbut also ant, Maven, etc...Testing: ScalaTest, Specs, ScalaCheckbut also JUnit, EasyMock, Mockito, etc...Web frameworks: Lift, Play!but also Struts, Spring MVC, etc...+ all that Java stuff
  59. 59. Libraries & frameworksDB query & access: Slick (LINQ-like)UI: ScalaFXText processing: parser combinators (stdlib)GPGPU: ScalaCL...and many others
  60. 60. Excelsior: наш опыт● Оптимизирующий компилятор● Новое ядро, implemented from scratch● R&D "по-взрослому"
  61. 61. Excelsior: наш опыт● Оптимизирующий компилятор● Новое ядро, implemented from scratch● R&D "по-взрослому"● Команда: ≤5 человек
  62. 62. Excelsior: наш опыт● Оптимизирующий компилятор● Новое ядро, implemented from scratch● R&D "по-взрослому"● Команда: ≤5 человек○ 4 из них не знали Скалу
  63. 63. Excelsior: наш опыт● Оптимизирующий компилятор● Новое ядро, implemented from scratch● R&D "по-взрослому"● Команда: ≤5 человек○ 4 из них не знали Скалу● Время: 1.5 года * 4 человек○ всё работает, релиз был в апреле 2013
  64. 64. Excelsior: наш опыт● Оптимизирующий компилятор● Новое ядро, implemented from scratch● R&D "по-взрослому"● Команда: ≤5 человек○ 4 из них не знали Скалу● Время: 1.5 года * 4 человек○ всё работает, релиз был в апреле 2013○ это мировой рекорд
  65. 65. Novosibirsk Scala Enthusiasts
  66. 66. Q / A
  67. 67. Q / A
  68. 68. Immutable classes and objectsTODO
  69. 69. Partial functionstrait Function1[T, R] {def apply(x: T): R}trait PartialFunction[T, R] extends Function1[T, R] {def isDefinedAt(x: T): Boolean}List(1,3,5,7) collect { case n if n < 5 => n + 1 }val pf = new PartialFunction[Int, Int] {def apply(x: Int): Int = x match{ case n if n < 5 => n + 1 }def isDefinedAt(x: Int): Boolean = x match{ case n if n < 5 => true; case _ => false }}
  70. 70. Scala CollectionsЗдесь картинка - иерархия классовTraversableOnce, Traversable, Iterable,Iterator, Seq, Set, MapSeq: IndexedSeq, Buffer; List, imm.Vector,Array, ListBuffer, ArrayBuffer, ...Set: HashSet, BitSet, TreeSetMap: HashMap, TreeMap, ListMapboth mutable & immutable
  71. 71. Типы: иерархия- Картинка- Top & bottom types: Any, Nothing- Основные типы: primitives, Unit, tuples,functions, Option- Составные типы:A with B with ... { refinement }- Отношение соответствия типов <:- Тип определяет интерфейс
  72. 72. Type variance: определениеПусть есть Foo[T], и A <: B (A != B).Есть три возможности:1. Foo[A] <: Foo[B] - Foo ковариантен по T2. Foo[B] <: Foo[A] - Foo контравариантен по T3. Иначе, Foo инвариантен по TВариантность задаётся при объявлении класса:class Foo[+T] / class Foo[-T] / class Foo[T]ко- / контра- / ин-
  73. 73. Type variance: примерыtrait InChannel[+T] { def get: T }val in: InChannel[String] = ...val x = in.get // x: Stringval in2: InChannel[Any] = inval x2 = in2.get // x2: Anytrait OutChannel[-T] { def put(x: T) }val out: OutChannel[Any] = ...out.put(42)val out2: OutChannel[String] = outout2.put("hello")
  74. 74. Type variance: контроль типовclass Cell[+T] { // covariantdef get: T // okdef put(x: T) // compilation error}class Cell[-T] { // contravariantdef get: T // compilation errordef put(x: T) // ok}class Cell[T] { // invariantdef get: T // okdef put(x: T) // ok}
  75. 75. Type variance: ещё примерыtrait Function1[-T, +R] { // contravariant argument(s)def apply(x: T): R // covariant result}class List[+T] { // immutable collections are covariantdef head: Tdef tail: List[T]}class Array[T] { // mutable collections are invariantdef apply(idx: Int): Tdef update(idx: Int, x: T)}
  76. 76. Параметризация: примерabstract class List[+A] {def head: Adef tail: List[A]def isEmpty: Boolean}final case class Cons[+A](val head: A, val tail: List[A])extends List[A] {def isEmpty = false}case object Nil extends List[Nothing] {def head = throw new NoSuchElementException("Nil.head")...}
  77. 77. Upper & lower type boundsdef max[A <: Ordered[A]](xs: List[A]): A = ???val accounts: Ordered[Money] = ???max(accounts)abstract class List[+A] {def ++[B >: A](that: List[B]): List[B] = ???}val strs = List("foo", "bar")val nums = List(13, 27)val all = strs ++ nums // List[Any]
  78. 78. Compound Typestrait Cloneable {def clone: Cloneable = ???}trait Resetable {def reset(): Unit}def cloneAndReset(obj: Cloneable with Resetable): Cloneable = {val cloned = obj.cloneobj.reset()cloned}
  79. 79. Structural & dynamic typesTODO
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×