SlideShare uma empresa Scribd logo
1 de 55
Baixar para ler offline
Что, как и зачем?
Тимушев Роман
ОБО МНЕ
• Scala с 2011	

• Один из организаторов встреч Scala Moscow
User Group	

• Работаю в Qubell
О ВАС
• Кто из вас	

• пишет на Java?	

• слышал о Scala?	

• пишет на Scala?	

• слышал что такое монада?	

• понимает, что монада это моноид в категории эндофункторов?
ЧТО ТАКОЕ SCALA
• Язык существует с 2003г.	

• Scalable language	

• Объединяет в себе OO и ФП-концепции	

• Статически типизирован	

• Компилируется в java-байткод	

• Open source
ПЕРЕМЕННЫЕ И ЗНАЧЕНИЯ
var a: String = "foo"!
a = "bar" // разрешено!
!
val b: String = "foo"!
b = "bar" // запрещено
ФУНКЦИИ
def sum1(a: Int, b: Int): Int =!
a + b!
!
val sum2 =!
(a: Int, b: Int) => a + b!
!
val sum3: (Int, Int) => Int =!
(a, b) => a + b!
!
val sum4: (Int, Int) => Int =!
_ + _
КЛАССЫ, ОБЪЕКТЫ И
ТРЕЙТЫ
trait Dumpable {!
def dump: String!
def dump(out: PrintStream) { out.print(dump) }!
}!
!
class Foo extends Dumpable {!
override def dump = "Foo"!
}!
!
val foo = new Foo!
foo.dump(Console.out)!
!
object Bar extends Dumpable {!
override def dump = "Bar"!
}!
!
Bar.dump(Console.err)
СИСТЕМА ТИПОВ
• Всё есть объект:Any,AnyVal,AnyRef	

• Кортежи:
scala> val tuple = (1, "a", true)!
tuple: (Int, String, Boolean) = (1,a,true)!
!
scala> tuple._2!
res0: String = a!
!
scala> val (x, y, _) = tuple!
x: Int = 1!
y: String = a
КТО ИСПОЛЬЗУЕТ SCALA
ЧТО ЭТО,
МОДА?
If I were to pick a language
today other than Java, it would
be Scala.	

!
James Gosling,

father of Java
ВЫБОР ЯЗЫКА
• Совместимость	

• Производительность	

• Поддержка	

• Продуктивность
СОВМЕСТИМОСТЬ
• Работает на платформе JVM	

• Windows, Mac, Linux,Android, кофеварки	

• Отличный JIT-компилятор	

• Отличный GC	

• Прозрачно интегрируется с Java-кодом	

• Смешанная компиляция	

• Можно использовать все доступные java-библиотеки	

• Старый код можно тоже не переписывать
ПРОИЗВОДИТЕЛЬНОСТЬ
• Какой код напишете, так и будет	

• Производительность сравнима с Java	

• Обычно потребляет немного больше памяти,
чем Java
ПОДДЕРЖКА
• Коммерческая поддержка отTypesafe Inc.	

• Дружелюбное сообщество
ПРОДУКТИВНОСТЬ
Сложно вернуться на Java без боли
РАЗМЕР КОДА JAVA
public class Person {!
!
private final String name;!
private final int age;!
!
public Person(String name, int age) {!
this.name = name;!
this.age = age;!
}!
!
public String getName() {!
return name;!
}!
!
public int getAge() {!
return age;!
}!
!
@Override!
public String toString() {!
return "Person(" + name + ", " + age + ")";!
}!
!
@Override!
public boolean equals(Object o) {!
if (this == o) return true;!
if (o == null || getClass() != o.getClass()) return false;!
Person person = (Person) o;!
if (age != person.age) return false;!
if (name != null ? !name.equals(person.name) : person.name != null) return false;!
return true;!
}!
!
@Override!
public int hashCode() {!
int result = name != null ? name.hashCode() : 0;!
result = 31 * result + age;!
return result;!
}!
!
}
РАЗМЕР КОДА SCALA
+ Метод-фабрика	

+ Метод copy	

+ Деконструктор для pattern matching
case class Person(name: String, age: Int)
РАЗМЕР ИМЕЕТ ЗНАЧЕНИЕ
• Число ошибок на строку кода — константа
слабо зависящая от языка программирования	

• В поле зрения человека попадает
ограниченный объём кода	

• Человек может сфокусировать внимание на
определённом объёме информации
ВЫВОД ТИПОВ
• Scala	

! ! val list = new ListBuffer[String]()!
• Java	

! ! ArrayList<String> list = new ArrayList<>();!
• Scala	

! ! val set = new HashMap[String, Int]().keySet!
• Java	

! ! Set<String> set = new HashMap<String, String>().keySet();!
OPTION
• Опциональное значение: None или Some(value)	

• Многие операции можно делать не извлекая значение	

• Извлечь тоже можно, но в отличие от null это
делается явно	

• Все библиотеки используют этот тип	

• В Java 8 тоже есть Optional
OPTION
val capitals = Map("Russia" -> "Moscow",!
"France" -> "Paris")!
!
val a = capitals.get("Russia")!
// Some("Moscow")!
val b = capitals.get("Italy") // None!
!
a.map(_.toUpperCase) // Some("MOSCOW")!
b.map(_.toUpperCase) // None!
!
a.getOrElse("Unknown") // "Moscow"!
b.getOrElse("Unknown") // "Unknown"!
!
for (x <- a; y <- b) yield s"$x, $y" // None
PATTERN MATCHING
sealed trait Shape!
case class Circle(radius: Double) extends Shape!
case class Rectangle(width: Double,!
height: Double) extends Shape!
!
val description = shape match {!
case Rectangle(w, h) if w == h =>!
s"square, side $w"!
case Rectangle(w, h) =>!
s"rectangle, $w x $h"!
case Circle(r) =>!
s"circle, radius $r"!
}
ПРОВЕРКА ПОЛНОТЫ
sealed trait Shape!
case class Circle(radius: Double) extends Shape!
case class Rectangle(width: Double,!
height: Double) extends Shape!
!
val description = shape match {!
case Circle(r) =>!
s"circle, radius $r"!
}!
!
pm.scala:16: match may not be exhaustive.!
It would fail on the following input: Rectangle(_, _)!
val description = shape match {!
^
FOR-EXPRESSIONS	

case class City(name: String,!
streets: List[Street],!
population: Int)!
!
case class Street(name: String,!
sights: List[String])!
!
val cities: List[City]!
!
val plan = cities!
.filter(_.population > 1000)!
.flatMap(_.streets)!
.flatMap(s => s.sights.map(s -> _))
FOR-EXPRESSIONS
val plan = cities!
.filter(_.population > 1000)!
.flatMap(_.streets)!
.flatMap(s => s.sights.map(s -> _))!
!
val plan = for {!
city <- cities if city.population > 1000!
street <- city.streets!
poi <- street.sights!
} yield (street.name, poi)
НЕ ТОЛЬКО КОЛЛЕКЦИИ
def httpGet(url: String): Future[String] = ???!
!
def getPost(idx: Int): Future[String] =!
for {!
posts <- httpGet("http://localhost/posts")!
slug = posts.split("n")(idx)!
post <- httpGet(s"http://localhost/$slug")!
} yield post
AD-HOC POLYMORPHISM
trait Pretty {!
def toPrettyString: String!
}
Привет, Мартин. Ты не мог бы
отнаследовать классы стандартной
библиотеки от Pretty? Это очень
важно для нас…
AD-HOC POLYMORPHISM
implicit class StringPretty(x: String) extends Pretty {!
def toPrettyString = x!
}!
!
implicit class IntPretty(x: Int) extends Pretty {!
def toPrettyString = x.toString!
}!
!
implicit class ListPretty[T <% Pretty](x: List[T])!
extends Pretty {!
def toPrettyString =!
x.map(_.toPrettyString).mkString("[", ", ", "]")!
}
AD-HOC POLYMORPHISM
dump("Hello, Mera")!
dump(List("a", "b"))!
dump(42)!
!
// ошибка компиляции!
dump(1.0)
ДРУГИЕ ПЛЮШКИ
• Ленивые значения	

• Именованые параметры	

• Значения параметров по-
умолчанию	

• Множественное наследование	

• Структурные типы	

• Определение операторов	

• Ко- и контра-вариантность	

• Типы высших порядков	

• XML-литералы	

• Интерполяция строк	

• Макросы	

• …
СЛОЖНОСТЬ
object Sized extends LowPrioritySized {!
implicit def sizedOps[Repr, L <: Nat](s : Sized[Repr, L])!
(implicit itl: IsTraversableLike[Repr]): SizedOps[itl.A, Repr, L] =!
new SizedOps[itl.A, Repr, L](itl.conversion(s.unsized))!
!
def apply[CC[_]] = new SizedBuilder[CC]!
!
def apply[CC[_]]()!
(implicit cbf : CanBuildFrom[Nothing, Nothing, CC[Nothing]]) =!
new Sized[CC[Nothing], _0](cbf().result)!
!
def wrap[Repr, L <: Nat](r : Repr) = new Sized[Repr, L](r)!
!
def unapplySeq[Repr, L <: Nat](x : Sized[Repr, L]) = Some(x.unsized)!
}
ПРОСТОТА
def csv[N <: Nat](hdrs: Sized[Seq[String], N],!
rows: Sized[Seq[String], N]*) = ???!
!
csv(!
Sized("ID", "Name"),!
Sized("1", "Nikolay"),!
Sized("2", "Vasiliy"),!
// compile-time error!
Sized("3", "Ivan", "Ivanovich")!
)
БОРЬБА СО СЛОЖНОСТЬЮ
• Обучение → делает сложное простым	

• Административные меры → запрет писать
сложный код	

• Code review → понятен ли ваш код другим	

• Поддержка компилятора → явное подключение
некоторых языковых конструкций
ENABLING LANGUAGE
FEATURES
implicit def intToString(x: Int): String = x.toString!
!
val x: String = 1
features.scala:7: implicit conversion method
intToString should be enabled by making the implicit
value scala.language.implicitConversions visible.
import scala.language.implicitConversions
КАДРОВЫЙ ВОПРОС
• Перейти с Java на Scala для большинства не
составляет проблемы	

• Готовых Scala-разработчиков мало, но их число
растёт	

• Конкуренция на рынке вакансий ниже	

• Средний уровень Scala-разработчиков выше
КАДРОВЫЙ ВОПРОС
• Нужна небольшая талантливая команда —

Scala может оказаться предпочтительнее	

• Большая команда для несложных задач —

Java будет лучшим выбором
УГОВОРИЛ, КАК НАЧАТЬ
• Пишите на Scala так же как на Java	

• Начните с тестов	

• Поощряйте «хороший» скала-код: Option вместо null,
иммутабельность	

• Желательно наличие эксперта в команде	

• Некоторые IDE умеют конвертировать Java код в Scala
автоматически
ПРОБЛЕМЫ
• Более сложные концепции	

• Медленная компиляция	

• Бинарная совместимость	

• Недостаточная поддержка в IDE
ПОЛЕЗНЫЕ БИБЛИОТЕКИ
• Akka — многопоточные распределённые приложения	

• Slick — работа с базами данных	

• Shapeless, scalaz — выразительный и обобщённый код	

• Scalatest — удобное тестирование	

• SBT — система сборки
AKKA
• Акторы — легковесные сущности, асинхронно
обменивающиеся сообщениями	

• О потоках и синхронизации заботится Akka	

• Простой переход к распределённому
приложению	

• Устойчивость к ошибкам
ПРИМЕР AKKA
class Worker extends Actor {!
!
val db = DB.connect()!
!
override def postStop() {!
db.close()!
}!
!
def receive = {!
case Query(sql) => sender() ! db.query(sql)!
}!
!
}
СУПЕРВИЗОР
class Supervisor extends Actor {!
!
override val supervisorStrategy =!
OneForOneStrategy(maxNrOfRetries = 10,!
withinTimeRange = 1 minute) {!
case _: IOException => Restart!
case _: Exception => Escalate!
}!
!
val worker = context.actorOf(Props[Worker])!
!
def receive = {!
case q: Query => worker forward q!
}!
!
}
POOLING
akka.actor.deployment {!
/parent/workerRouter {!
router = round-robin-pool!
nr-of-instances = 5!
}!
}!
!
val workers = context.actorOf(!
FromConfig.props(Props[Worker]),!
"workerRouter"!
)
REMOTING
akka {!
actor {!
deployment {!
/parent/worker {!
remote =!
"akka.tcp://ActorSystem@127.0.0.1:2553"!
}!
}!
}!
}
SLICK
• Схема и запросы — обычный Scala-код	

• Работа с базой данных так же проста, как с
обычными коллекциями	

• Запросы типобезопасны
ПРИМЕР SLICK
// select NAME from COFFEES !
// where PRICE < 10.0!
// order by NAME!
coffees!
.filter(_.price < 10.0)!
.sortBy(_.name)!
.map(_.name)!
.list!
!
// Seq[String]("Cappuccino", "Espresso")
БИБЛИОТЕКИTYPELEVEL
• Scalaz — упрощает программирование в
функциональном стиле (монады, функторы,
линзы и другие классы типов)	

• Shapeless — ещё более строгая типизация
SCALAZ: MONOIDS
val x = Map("a" -> List(1))!
!
val y = Map("a" -> List(2),!
"b" -> List(3))!
!
// or println(x mappend y)!
println(x |+| y)!
!
"Map(a -> List(1, 2), b -> List(3))"
SHAPELESS:TYPE-SAFE CAST
// опасно!
x.asInstanceOf[Map[String, List[Int]]]!
!
// безопасно!
x.cast[Map[String, List[Int]]]
SCALATEST
class ExampleSpec extends FreeSpec 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()!
} !
}!
}
SCALATEST
$ scala -cp scalatest_2.11-2.2.0.jar org.scalatest.run ExampleSpec	
Discovery starting.	
Discovery completed in 21 milliseconds.	
Run starting. Expected test count is: 2	
ExampleSpec:	
A Stack	
- should pop values in last-in-first-out order	
- should throw NoSuchElementException if an empty stack is popped	
Run completed in 76 milliseconds.	
Total number of tests run: 2	
Suites: completed 1, aborted 0	
Tests: succeeded 2, failed 0, canceled 0, ignored 0, pending 0	
All tests passed.
ASSERTIONS
scala> assert(a == b || c >= d)
org.scalatest.exceptions.TestFailedException:
1 did not equal 2, and 3 was not greater than or equal to 4
at ...
!
scala> assert(Some(2).isEmpty)
org.scalatest.exceptions.TestFailedException:
Some(2) was not empty
at ...
DIAGRAMMED ASSERTIONS
scala> assert(a == b || c >= d)
org.scalatest.exceptions.TestFailedException:
!
assert(a == b || c >= d)
| | | | | | |
1 | 2 | 3 | 4
| | false
| false
false
!
at ...
СПАСИБО ЗА ВНИМАНИЕ	

ВОПРОСЫ?
ССЫЛКИ
• http://www.scala-lang.org/	

• http://typesafe.com/platform/	

• http://typelevel.org/	

• http://www.scalatest.org/	

• http://notes.implicit.ly/

Mais conteúdo relacionado

Mais procurados

Scala and LiftWeb presentation (Russian)
Scala and LiftWeb presentation (Russian)Scala and LiftWeb presentation (Russian)
Scala and LiftWeb presentation (Russian)Dmitry Stropalov
 
Внешние языки DSL на funcparserlib
Внешние языки DSL на funcparserlibВнешние языки DSL на funcparserlib
Внешние языки DSL на funcparserlibAndrey Vlasovskikh
 
Groovy presentation.
Groovy presentation.Groovy presentation.
Groovy presentation.Infinity
 
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)Ontico
 
Михаил Давыдов: JavaScript. Базовые знания
Михаил Давыдов: JavaScript. Базовые знанияМихаил Давыдов: JavaScript. Базовые знания
Михаил Давыдов: JavaScript. Базовые знанияYandex
 
Лекция 11. Тестирование.
Лекция 11. Тестирование.Лекция 11. Тестирование.
Лекция 11. Тестирование.Roman Brovko
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Sergey Platonov
 
Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.Roman Brovko
 
Formal verification of C code
Formal verification of C codeFormal verification of C code
Formal verification of C codeDenis Efremov
 
C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному кодуVasiliy Deynega
 
AOT для Java: Мифы и Challenges
AOT для Java: Мифы и ChallengesAOT для Java: Мифы и Challenges
AOT для Java: Мифы и ChallengesNikita Lipsky
 
модель акторов и C++ что, зачем и как ?
модель акторов и C++ что, зачем и как ?модель акторов и C++ что, зачем и как ?
модель акторов и C++ что, зачем и как ?corehard_by
 
Лекция 1. Начало.
Лекция 1. Начало.Лекция 1. Начало.
Лекция 1. Начало.Roman Brovko
 
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.Roman Brovko
 
Лекция 4. Строки, байты, файлы и ввод/вывод.
 Лекция 4. Строки, байты, файлы и ввод/вывод. Лекция 4. Строки, байты, файлы и ввод/вывод.
Лекция 4. Строки, байты, файлы и ввод/вывод.Roman Brovko
 
Making of external DSL for Django ORM - Павел Петлинский, Rambler&Co
Making of external DSL for Django ORM - Павел Петлинский, Rambler&CoMaking of external DSL for Django ORM - Павел Петлинский, Rambler&Co
Making of external DSL for Django ORM - Павел Петлинский, Rambler&Coit-people
 
Язык программирования Scala / Владимир Успенский (TCS Bank)
Язык программирования Scala / Владимир Успенский (TCS Bank)Язык программирования Scala / Владимир Успенский (TCS Bank)
Язык программирования Scala / Владимир Успенский (TCS Bank)Ontico
 
Лекция 6. Классы 1.
Лекция 6. Классы 1.Лекция 6. Классы 1.
Лекция 6. Классы 1.Roman Brovko
 

Mais procurados (18)

Scala and LiftWeb presentation (Russian)
Scala and LiftWeb presentation (Russian)Scala and LiftWeb presentation (Russian)
Scala and LiftWeb presentation (Russian)
 
Внешние языки DSL на funcparserlib
Внешние языки DSL на funcparserlibВнешние языки DSL на funcparserlib
Внешние языки DSL на funcparserlib
 
Groovy presentation.
Groovy presentation.Groovy presentation.
Groovy presentation.
 
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
 
Михаил Давыдов: JavaScript. Базовые знания
Михаил Давыдов: JavaScript. Базовые знанияМихаил Давыдов: JavaScript. Базовые знания
Михаил Давыдов: JavaScript. Базовые знания
 
Лекция 11. Тестирование.
Лекция 11. Тестирование.Лекция 11. Тестирование.
Лекция 11. Тестирование.
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.
 
Formal verification of C code
Formal verification of C codeFormal verification of C code
Formal verification of C code
 
C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному коду
 
AOT для Java: Мифы и Challenges
AOT для Java: Мифы и ChallengesAOT для Java: Мифы и Challenges
AOT для Java: Мифы и Challenges
 
модель акторов и C++ что, зачем и как ?
модель акторов и C++ что, зачем и как ?модель акторов и C++ что, зачем и как ?
модель акторов и C++ что, зачем и как ?
 
Лекция 1. Начало.
Лекция 1. Начало.Лекция 1. Начало.
Лекция 1. Начало.
 
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.
 
Лекция 4. Строки, байты, файлы и ввод/вывод.
 Лекция 4. Строки, байты, файлы и ввод/вывод. Лекция 4. Строки, байты, файлы и ввод/вывод.
Лекция 4. Строки, байты, файлы и ввод/вывод.
 
Making of external DSL for Django ORM - Павел Петлинский, Rambler&Co
Making of external DSL for Django ORM - Павел Петлинский, Rambler&CoMaking of external DSL for Django ORM - Павел Петлинский, Rambler&Co
Making of external DSL for Django ORM - Павел Петлинский, Rambler&Co
 
Язык программирования Scala / Владимир Успенский (TCS Bank)
Язык программирования Scala / Владимир Успенский (TCS Bank)Язык программирования Scala / Владимир Успенский (TCS Bank)
Язык программирования Scala / Владимир Успенский (TCS Bank)
 
Лекция 6. Классы 1.
Лекция 6. Классы 1.Лекция 6. Классы 1.
Лекция 6. Классы 1.
 

Destaque (20)

Lec 1
Lec 1Lec 1
Lec 1
 
Lec 15
Lec 15Lec 15
Lec 15
 
Lec 11
Lec 11Lec 11
Lec 11
 
Lec 14
Lec 14Lec 14
Lec 14
 
Lec 5
Lec 5Lec 5
Lec 5
 
Lec 6
Lec 6Lec 6
Lec 6
 
Lec 4
Lec 4Lec 4
Lec 4
 
Lec 3
Lec 3Lec 3
Lec 3
 
Scala for android
Scala for androidScala for android
Scala for android
 
Under the hood of scala implicits (Scala eXchange 2014)
Under the hood of scala implicits (Scala eXchange 2014)Under the hood of scala implicits (Scala eXchange 2014)
Under the hood of scala implicits (Scala eXchange 2014)
 
Scala #4
Scala #4Scala #4
Scala #4
 
Scala #2
Scala #2Scala #2
Scala #2
 
Scala lecture #4
Scala lecture #4Scala lecture #4
Scala lecture #4
 
Scala #3
Scala #3Scala #3
Scala #3
 
Scala magic
Scala magicScala magic
Scala magic
 
Under the hood of scala implicits (kl10tch 10.03.2015)
Under the hood of scala implicits (kl10tch 10.03.2015)Under the hood of scala implicits (kl10tch 10.03.2015)
Under the hood of scala implicits (kl10tch 10.03.2015)
 
Scala training
Scala trainingScala training
Scala training
 
Feature suggester
Feature suggesterFeature suggester
Feature suggester
 
Lec 2
Lec 2Lec 2
Lec 2
 
Scala #5
Scala #5Scala #5
Scala #5
 

Semelhante a Scala: что, как и зачем?

Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101Anton Arhipov
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?Vasil Remeniuk
 
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Yandex
 
Lift, play, akka, rails part1
Lift, play, akka, rails part1Lift, play, akka, rails part1
Lift, play, akka, rails part1Eduard Antsupov
 
How to cook a blockchain and not get burned
How to cook a blockchain and not get burned How to cook a blockchain and not get burned
How to cook a blockchain and not get burned Alexander Syrotenko
 
Scala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application DevelopmentScala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application DevelopmentAnton Kirillov
 
Вадим Челышов, Scala Engineer : Все ненавидят SBT
Вадим Челышов, Scala Engineer : Все ненавидят SBT Вадим Челышов, Scala Engineer : Все ненавидят SBT
Вадим Челышов, Scala Engineer : Все ненавидят SBT Provectus
 
Александр Гладыш — Lua
Александр Гладыш — LuaАлександр Гладыш — Lua
Александр Гладыш — LuaYury Yurevich
 
JPoint 2016 - Bytecode
JPoint 2016 - BytecodeJPoint 2016 - Bytecode
JPoint 2016 - BytecodeAnton Arhipov
 
Компьютерная графика. Введение в Processing
Компьютерная графика. Введение в ProcessingКомпьютерная графика. Введение в Processing
Компьютерная графика. Введение в ProcessingTatiana Volkova
 
Xe4 launch мобильная разработка всеволод_леонов
Xe4 launch мобильная разработка всеволод_леоновXe4 launch мобильная разработка всеволод_леонов
Xe4 launch мобильная разработка всеволод_леоновЕкатерина Макарова
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPITimur Shemsedinov
 
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...Magneta AI
 
Java Ahead-Of-Time compilation
Java Ahead-Of-Time compilationJava Ahead-Of-Time compilation
Java Ahead-Of-Time compilationNikita Lipsky
 
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Ruby Meditation
 
Денис Иванов
Денис ИвановДенис Иванов
Денис ИвановCodeFest
 
CodeFest 2013. Бурмако Е. — Макросы в Скале
CodeFest 2013. Бурмако Е. — Макросы в СкалеCodeFest 2013. Бурмако Е. — Макросы в Скале
CodeFest 2013. Бурмако Е. — Макросы в СкалеCodeFest
 
Tarantool, .net, newsql
Tarantool, .net, newsqlTarantool, .net, newsql
Tarantool, .net, newsqlAnatoly Popov
 

Semelhante a Scala: что, как и зачем? (20)

Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
 
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
 
Lift, play, akka, rails part1
Lift, play, akka, rails part1Lift, play, akka, rails part1
Lift, play, akka, rails part1
 
How to cook a blockchain and not get burned
How to cook a blockchain and not get burned How to cook a blockchain and not get burned
How to cook a blockchain and not get burned
 
Scala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application DevelopmentScala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application Development
 
Вадим Челышов, Scala Engineer : Все ненавидят SBT
Вадим Челышов, Scala Engineer : Все ненавидят SBT Вадим Челышов, Scala Engineer : Все ненавидят SBT
Вадим Челышов, Scala Engineer : Все ненавидят SBT
 
Александр Гладыш — Lua
Александр Гладыш — LuaАлександр Гладыш — Lua
Александр Гладыш — Lua
 
JPoint 2016 - Bytecode
JPoint 2016 - BytecodeJPoint 2016 - Bytecode
JPoint 2016 - Bytecode
 
Компьютерная графика. Введение в Processing
Компьютерная графика. Введение в ProcessingКомпьютерная графика. Введение в Processing
Компьютерная графика. Введение в Processing
 
Scala Rock-Painting
Scala Rock-PaintingScala Rock-Painting
Scala Rock-Painting
 
Xe4 launch мобильная разработка всеволод_леонов
Xe4 launch мобильная разработка всеволод_леоновXe4 launch мобильная разработка всеволод_леонов
Xe4 launch мобильная разработка всеволод_леонов
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPI
 
About Python
About PythonAbout Python
About Python
 
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
 
Java Ahead-Of-Time compilation
Java Ahead-Of-Time compilationJava Ahead-Of-Time compilation
Java Ahead-Of-Time compilation
 
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
 
Денис Иванов
Денис ИвановДенис Иванов
Денис Иванов
 
CodeFest 2013. Бурмако Е. — Макросы в Скале
CodeFest 2013. Бурмако Е. — Макросы в СкалеCodeFest 2013. Бурмако Е. — Макросы в Скале
CodeFest 2013. Бурмако Е. — Макросы в Скале
 
Tarantool, .net, newsql
Tarantool, .net, newsqlTarantool, .net, newsql
Tarantool, .net, newsql
 

Scala: что, как и зачем?

  • 1. Что, как и зачем? Тимушев Роман
  • 2. ОБО МНЕ • Scala с 2011 • Один из организаторов встреч Scala Moscow User Group • Работаю в Qubell
  • 3. О ВАС • Кто из вас • пишет на Java? • слышал о Scala? • пишет на Scala? • слышал что такое монада? • понимает, что монада это моноид в категории эндофункторов?
  • 4. ЧТО ТАКОЕ SCALA • Язык существует с 2003г. • Scalable language • Объединяет в себе OO и ФП-концепции • Статически типизирован • Компилируется в java-байткод • Open source
  • 5. ПЕРЕМЕННЫЕ И ЗНАЧЕНИЯ var a: String = "foo"! a = "bar" // разрешено! ! val b: String = "foo"! b = "bar" // запрещено
  • 6. ФУНКЦИИ def sum1(a: Int, b: Int): Int =! a + b! ! val sum2 =! (a: Int, b: Int) => a + b! ! val sum3: (Int, Int) => Int =! (a, b) => a + b! ! val sum4: (Int, Int) => Int =! _ + _
  • 7. КЛАССЫ, ОБЪЕКТЫ И ТРЕЙТЫ trait Dumpable {! def dump: String! def dump(out: PrintStream) { out.print(dump) }! }! ! class Foo extends Dumpable {! override def dump = "Foo"! }! ! val foo = new Foo! foo.dump(Console.out)! ! object Bar extends Dumpable {! override def dump = "Bar"! }! ! Bar.dump(Console.err)
  • 8. СИСТЕМА ТИПОВ • Всё есть объект:Any,AnyVal,AnyRef • Кортежи: scala> val tuple = (1, "a", true)! tuple: (Int, String, Boolean) = (1,a,true)! ! scala> tuple._2! res0: String = a! ! scala> val (x, y, _) = tuple! x: Int = 1! y: String = a
  • 10. ЧТО ЭТО, МОДА? If I were to pick a language today other than Java, it would be Scala. ! James Gosling,
 father of Java
  • 11. ВЫБОР ЯЗЫКА • Совместимость • Производительность • Поддержка • Продуктивность
  • 12. СОВМЕСТИМОСТЬ • Работает на платформе JVM • Windows, Mac, Linux,Android, кофеварки • Отличный JIT-компилятор • Отличный GC • Прозрачно интегрируется с Java-кодом • Смешанная компиляция • Можно использовать все доступные java-библиотеки • Старый код можно тоже не переписывать
  • 13. ПРОИЗВОДИТЕЛЬНОСТЬ • Какой код напишете, так и будет • Производительность сравнима с Java • Обычно потребляет немного больше памяти, чем Java
  • 14. ПОДДЕРЖКА • Коммерческая поддержка отTypesafe Inc. • Дружелюбное сообщество
  • 16. РАЗМЕР КОДА JAVA public class Person {! ! private final String name;! private final int age;! ! public Person(String name, int age) {! this.name = name;! this.age = age;! }! ! public String getName() {! return name;! }! ! public int getAge() {! return age;! }! ! @Override! public String toString() {! return "Person(" + name + ", " + age + ")";! }! ! @Override! public boolean equals(Object o) {! if (this == o) return true;! if (o == null || getClass() != o.getClass()) return false;! Person person = (Person) o;! if (age != person.age) return false;! if (name != null ? !name.equals(person.name) : person.name != null) return false;! return true;! }! ! @Override! public int hashCode() {! int result = name != null ? name.hashCode() : 0;! result = 31 * result + age;! return result;! }! ! }
  • 17. РАЗМЕР КОДА SCALA + Метод-фабрика + Метод copy + Деконструктор для pattern matching case class Person(name: String, age: Int)
  • 18. РАЗМЕР ИМЕЕТ ЗНАЧЕНИЕ • Число ошибок на строку кода — константа слабо зависящая от языка программирования • В поле зрения человека попадает ограниченный объём кода • Человек может сфокусировать внимание на определённом объёме информации
  • 19. ВЫВОД ТИПОВ • Scala ! ! val list = new ListBuffer[String]()! • Java ! ! ArrayList<String> list = new ArrayList<>();! • Scala ! ! val set = new HashMap[String, Int]().keySet! • Java ! ! Set<String> set = new HashMap<String, String>().keySet();!
  • 20. OPTION • Опциональное значение: None или Some(value) • Многие операции можно делать не извлекая значение • Извлечь тоже можно, но в отличие от null это делается явно • Все библиотеки используют этот тип • В Java 8 тоже есть Optional
  • 21. OPTION val capitals = Map("Russia" -> "Moscow",! "France" -> "Paris")! ! val a = capitals.get("Russia")! // Some("Moscow")! val b = capitals.get("Italy") // None! ! a.map(_.toUpperCase) // Some("MOSCOW")! b.map(_.toUpperCase) // None! ! a.getOrElse("Unknown") // "Moscow"! b.getOrElse("Unknown") // "Unknown"! ! for (x <- a; y <- b) yield s"$x, $y" // None
  • 22. PATTERN MATCHING sealed trait Shape! case class Circle(radius: Double) extends Shape! case class Rectangle(width: Double,! height: Double) extends Shape! ! val description = shape match {! case Rectangle(w, h) if w == h =>! s"square, side $w"! case Rectangle(w, h) =>! s"rectangle, $w x $h"! case Circle(r) =>! s"circle, radius $r"! }
  • 23. ПРОВЕРКА ПОЛНОТЫ sealed trait Shape! case class Circle(radius: Double) extends Shape! case class Rectangle(width: Double,! height: Double) extends Shape! ! val description = shape match {! case Circle(r) =>! s"circle, radius $r"! }! ! pm.scala:16: match may not be exhaustive.! It would fail on the following input: Rectangle(_, _)! val description = shape match {! ^
  • 24. FOR-EXPRESSIONS case class City(name: String,! streets: List[Street],! population: Int)! ! case class Street(name: String,! sights: List[String])! ! val cities: List[City]! ! val plan = cities! .filter(_.population > 1000)! .flatMap(_.streets)! .flatMap(s => s.sights.map(s -> _))
  • 25. FOR-EXPRESSIONS val plan = cities! .filter(_.population > 1000)! .flatMap(_.streets)! .flatMap(s => s.sights.map(s -> _))! ! val plan = for {! city <- cities if city.population > 1000! street <- city.streets! poi <- street.sights! } yield (street.name, poi)
  • 26. НЕ ТОЛЬКО КОЛЛЕКЦИИ def httpGet(url: String): Future[String] = ???! ! def getPost(idx: Int): Future[String] =! for {! posts <- httpGet("http://localhost/posts")! slug = posts.split("n")(idx)! post <- httpGet(s"http://localhost/$slug")! } yield post
  • 27. AD-HOC POLYMORPHISM trait Pretty {! def toPrettyString: String! } Привет, Мартин. Ты не мог бы отнаследовать классы стандартной библиотеки от Pretty? Это очень важно для нас…
  • 28. AD-HOC POLYMORPHISM implicit class StringPretty(x: String) extends Pretty {! def toPrettyString = x! }! ! implicit class IntPretty(x: Int) extends Pretty {! def toPrettyString = x.toString! }! ! implicit class ListPretty[T <% Pretty](x: List[T])! extends Pretty {! def toPrettyString =! x.map(_.toPrettyString).mkString("[", ", ", "]")! }
  • 29. AD-HOC POLYMORPHISM dump("Hello, Mera")! dump(List("a", "b"))! dump(42)! ! // ошибка компиляции! dump(1.0)
  • 30. ДРУГИЕ ПЛЮШКИ • Ленивые значения • Именованые параметры • Значения параметров по- умолчанию • Множественное наследование • Структурные типы • Определение операторов • Ко- и контра-вариантность • Типы высших порядков • XML-литералы • Интерполяция строк • Макросы • …
  • 31. СЛОЖНОСТЬ object Sized extends LowPrioritySized {! implicit def sizedOps[Repr, L <: Nat](s : Sized[Repr, L])! (implicit itl: IsTraversableLike[Repr]): SizedOps[itl.A, Repr, L] =! new SizedOps[itl.A, Repr, L](itl.conversion(s.unsized))! ! def apply[CC[_]] = new SizedBuilder[CC]! ! def apply[CC[_]]()! (implicit cbf : CanBuildFrom[Nothing, Nothing, CC[Nothing]]) =! new Sized[CC[Nothing], _0](cbf().result)! ! def wrap[Repr, L <: Nat](r : Repr) = new Sized[Repr, L](r)! ! def unapplySeq[Repr, L <: Nat](x : Sized[Repr, L]) = Some(x.unsized)! }
  • 32. ПРОСТОТА def csv[N <: Nat](hdrs: Sized[Seq[String], N],! rows: Sized[Seq[String], N]*) = ???! ! csv(! Sized("ID", "Name"),! Sized("1", "Nikolay"),! Sized("2", "Vasiliy"),! // compile-time error! Sized("3", "Ivan", "Ivanovich")! )
  • 33. БОРЬБА СО СЛОЖНОСТЬЮ • Обучение → делает сложное простым • Административные меры → запрет писать сложный код • Code review → понятен ли ваш код другим • Поддержка компилятора → явное подключение некоторых языковых конструкций
  • 34. ENABLING LANGUAGE FEATURES implicit def intToString(x: Int): String = x.toString! ! val x: String = 1 features.scala:7: implicit conversion method intToString should be enabled by making the implicit value scala.language.implicitConversions visible. import scala.language.implicitConversions
  • 35. КАДРОВЫЙ ВОПРОС • Перейти с Java на Scala для большинства не составляет проблемы • Готовых Scala-разработчиков мало, но их число растёт • Конкуренция на рынке вакансий ниже • Средний уровень Scala-разработчиков выше
  • 36. КАДРОВЫЙ ВОПРОС • Нужна небольшая талантливая команда —
 Scala может оказаться предпочтительнее • Большая команда для несложных задач —
 Java будет лучшим выбором
  • 37. УГОВОРИЛ, КАК НАЧАТЬ • Пишите на Scala так же как на Java • Начните с тестов • Поощряйте «хороший» скала-код: Option вместо null, иммутабельность • Желательно наличие эксперта в команде • Некоторые IDE умеют конвертировать Java код в Scala автоматически
  • 38. ПРОБЛЕМЫ • Более сложные концепции • Медленная компиляция • Бинарная совместимость • Недостаточная поддержка в IDE
  • 39. ПОЛЕЗНЫЕ БИБЛИОТЕКИ • Akka — многопоточные распределённые приложения • Slick — работа с базами данных • Shapeless, scalaz — выразительный и обобщённый код • Scalatest — удобное тестирование • SBT — система сборки
  • 40. AKKA • Акторы — легковесные сущности, асинхронно обменивающиеся сообщениями • О потоках и синхронизации заботится Akka • Простой переход к распределённому приложению • Устойчивость к ошибкам
  • 41. ПРИМЕР AKKA class Worker extends Actor {! ! val db = DB.connect()! ! override def postStop() {! db.close()! }! ! def receive = {! case Query(sql) => sender() ! db.query(sql)! }! ! }
  • 42. СУПЕРВИЗОР class Supervisor extends Actor {! ! override val supervisorStrategy =! OneForOneStrategy(maxNrOfRetries = 10,! withinTimeRange = 1 minute) {! case _: IOException => Restart! case _: Exception => Escalate! }! ! val worker = context.actorOf(Props[Worker])! ! def receive = {! case q: Query => worker forward q! }! ! }
  • 43. POOLING akka.actor.deployment {! /parent/workerRouter {! router = round-robin-pool! nr-of-instances = 5! }! }! ! val workers = context.actorOf(! FromConfig.props(Props[Worker]),! "workerRouter"! )
  • 44. REMOTING akka {! actor {! deployment {! /parent/worker {! remote =! "akka.tcp://ActorSystem@127.0.0.1:2553"! }! }! }! }
  • 45. SLICK • Схема и запросы — обычный Scala-код • Работа с базой данных так же проста, как с обычными коллекциями • Запросы типобезопасны
  • 46. ПРИМЕР SLICK // select NAME from COFFEES ! // where PRICE < 10.0! // order by NAME! coffees! .filter(_.price < 10.0)! .sortBy(_.name)! .map(_.name)! .list! ! // Seq[String]("Cappuccino", "Espresso")
  • 47. БИБЛИОТЕКИTYPELEVEL • Scalaz — упрощает программирование в функциональном стиле (монады, функторы, линзы и другие классы типов) • Shapeless — ещё более строгая типизация
  • 48. SCALAZ: MONOIDS val x = Map("a" -> List(1))! ! val y = Map("a" -> List(2),! "b" -> List(3))! ! // or println(x mappend y)! println(x |+| y)! ! "Map(a -> List(1, 2), b -> List(3))"
  • 49. SHAPELESS:TYPE-SAFE CAST // опасно! x.asInstanceOf[Map[String, List[Int]]]! ! // безопасно! x.cast[Map[String, List[Int]]]
  • 50. SCALATEST class ExampleSpec extends FreeSpec 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()! } ! }! }
  • 51. SCALATEST $ scala -cp scalatest_2.11-2.2.0.jar org.scalatest.run ExampleSpec Discovery starting. Discovery completed in 21 milliseconds. Run starting. Expected test count is: 2 ExampleSpec: A Stack - should pop values in last-in-first-out order - should throw NoSuchElementException if an empty stack is popped Run completed in 76 milliseconds. Total number of tests run: 2 Suites: completed 1, aborted 0 Tests: succeeded 2, failed 0, canceled 0, ignored 0, pending 0 All tests passed.
  • 52. ASSERTIONS scala> assert(a == b || c >= d) org.scalatest.exceptions.TestFailedException: 1 did not equal 2, and 3 was not greater than or equal to 4 at ... ! scala> assert(Some(2).isEmpty) org.scalatest.exceptions.TestFailedException: Some(2) was not empty at ...
  • 53. DIAGRAMMED ASSERTIONS scala> assert(a == b || c >= d) org.scalatest.exceptions.TestFailedException: ! assert(a == b || c >= d) | | | | | | | 1 | 2 | 3 | 4 | | false | false false ! at ...
  • 55. ССЫЛКИ • http://www.scala-lang.org/ • http://typesafe.com/platform/ • http://typelevel.org/ • http://www.scalatest.org/ • http://notes.implicit.ly/