2. Scala в двух словах
• Краткость кода как в Ruby
• Возможности IDE как в Java
3. Ruby или Java?
• Ruby
меньше кода => меньше багов
• Java
умный компилятор => меньше багов
• Scala
меньше кода => меньше багов
умный компилятор => меньше багов
4. Erlang или Java?
• Java быстрее.
JVM быстрее Erlang VM.
• Erlang быстрее.
Проще создавать мастштабируемые прил.
• Scala быстрее.
JVM быстрее Erlang VM.
Проще создавать мастштабируемые прил.
5. Мартин Одерски
• Придумал Scala
• Написал компилятор Scala
• Написал компилятор Java
• Соавтор Java generics
• Смешанные Scala+Java проекты в Eclipse, etc
• Microsoft спонсирует Scala.NET
• Компиляция в JavaScript с Google Web Toolkit
10. Элитарность Scala
InfoQ: Тяжело ли найти разработчиков на Scala?
Дэвид Поллак:
Нет. Найти хороших Scala разработчиков легко.
Я могу организовать отличную команду из 10
человек, готовую к работе на следующей неделе.
Они не будут дешёвыми (средняя цена $250/час
плюс то, что возьму я). Они не будут локальными.
Но они будут отличными.
Тяжело найти аутсорсовую команду из 25 Scala
разработчиков за $40/час.
11. Количество фич в Scala
• Намного меньше, чем в C++ или C#
• Сравнимо с Java. Из Java удалены:
static члены
примитивные типы
break и continue
особое понятие об интерфейсах
wildcard’ы
raw типы
enum’ы
• Фичи Scala более унифицированные и гибкие
12. Пример кода на Java
public class Person implements Serializable {
private final String firstName;
private final String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
13. Пример кода на Java (продолжение)
public Person withFirstName(String firstName) {
return new Person(firstName, lastName);
}
public Person withLastName(String lastName) {
return new Person(firstName, lastName);
}
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Person person = (Person) o;
if (firstName != null ? !firstName.equals(person.firstName)
: person.firstName != null) {
return false;
}
14. Пример кода на Java (продолжение)
if (lastName != null ? !lastName.equals(person.lastName)
: person.lastName != null) {
return false;
}
return true;
}
public int hashCode() {
int result = firstName != null ? firstName.hashCode()
: 0;
result = 31 * result +
(lastName != null ? lastName.hashCode() : 0);
return result;
}
public String toString() {
return "Person(" + firstName + "," + lastName + ")";
}
}
15. То же самое на Scala
case class Person(firstName: String, lastName: String)
16. Использование
• Java
Person mr = new Person("Bob", "Dobbelina");
Person miss = new Person("Roberta", "MacSweeney");
Person mrs = miss.withLastName(mr.getLastName());
• Scala
val mr = Person("Bob", "Dobbelina")
val miss = Person("Roberta", "MacSweeney")
val mrs = miss copy (lastName = mr.lastName)
val mrs = miss.copy(lastName = mr.lastName)
val mrs = miss.copy(miss.firstName, mr.lastName)
17. Коллекции
case class User(id: Int, userName: String)
val users: List[User] = // ....
val resultUsers = new ArrayBuffer[User]
for (i <- 0 until users.size) {
if (users(i).userName != "test") {
resultUsers += users(i)
}
}
18. Коллекции
def formatUsers(users: List[User]): String = {
val result = new StringBuilder
for (i <- 0 until users.size) {
val userName = users(i).userName
if (userName != "test") {
result.append(userName)
if (i < users.size - 1) {
result.append(", “)
}
}
}
return result.toString
}
23. formatUsers версия 2.0
def formatUsers(users: List[User]) =
users map (_.userName) filter (_ != "test") mkString ", "
• Нет бага :-)
• Всего 3 шага
• Каждый шаг имеет смысл сам по себе
• Больше повторного использования кода
24. Повторное использование
• formatUsers версия 3.0
def formatUsersInParallel(users: List[User]) =
formatUsers(users.par)
• …
ScalaCL => граф.карта => быстрее в 10-100
раз
25. Java + Google Collections
public String formatUsers(final List<User> users) {
final Collection<String> filteredUserNames = FluentIterable
.from(users)
.transform(new Function<User, String>() {
@Override
public String apply(final User user) {
return user.getUserName();
}
})
.filter(new Predicate<String>() {
@Override
public boolean apply(final String userName) {
return !userName.equals("test");
}
})
.toImmutableList();
return Joiner.on(", ").join(filteredUserNames);
}
26. Паттерны проектирования банды 4-х
• Написание повторно используемого кода
на Java требует больших усилий
• На динамических языках и Scala многие из
этих паттернов тривиальны
• Критика паттернов Питером Норвигом
(директор по исследованиям в Google Inc.)
• ОО тоже когда-то было паттерном
29. Factory
object Car {
def apply(type: String) = {
type match {
case “Race" => new RaceCar
case "Normal" => new NormalCar
case _ => throw new Exception
}
}
}
val myCar = Car("Race“)
30. Visitor
trait Expr {
//...
}
case class Var(value: Int) extends Expr
case class Sum(ex1: Expr, ex2: Expr) extends Expr
object EvalVisitor {
def visit(expr: Expression) = expr match {
case (Var(v)) => v
case (Sum(e1, e2)) => visit(e1) + visit(e2)
}
}
31. Decorator
trait Reader {
type T
def read: T
}
trait BufferedReader extends Reader {
abstract override def read: T = {
// ... buffering code
super.read
}
}
class FileReader extends Reader {
type T = Char
def read: Char = // ... Read somehow
}
val bufferedReader = new FileReader with BufferedReader
32. ОО + ФП = Scala
• Объектная ориентация
- Любое значение – объект
- Любое действие – вызов метода у объекта
• Функциональная ориентация
- Любое действие – вызов функции
- Любая функция – значение, которое можно присвоить
переменной или передать другой функции
• Scala
- Любое значение – объект
- Любое действие – вызов метода у объекта
- Любой метод – функция
- Любая функция – объект
33. Чистое функциональное прог-ание
• Результат любой функции зависит только от
входных параметров
• Любая функция только возвращает результат
• А это значит, что напрямую нельзя:
- Менять значения переменных
- Модифицировать структуры данных
- Менять поля объектов
- Бросать исключения
- Печатать на консоль и читать с неё
- Читать или писать в файл
- Рисовать на экране
34. Работе со строками
• В Java – функциональный подход
• В Ruby – не функциональный подход
35. Сравним
def formatUsers(users: List[User]) =
users map (_.userName) filter (_ != "test") mkString ", "
def formatUsers(users: List[User]): String = {
val result = new StringBuilder
for (i <- 0 until users.size) {
val userName = users(i).userName
if (userName != "test") {
result.append(userName)
if (i < users.size - 1) {
result.append(", “)
}
}
}
return result.toString
}
36. Преимущества ФП
• Части кода не зависят друг от друга
• Код более понятный
• Меньше багов
• Проще параллелизовать
• Проще оптимизировать компилятору
Недостатки ФП
• Иногда больше расход ресурсов
• Иногда сложнее написать
• Иногда невозможно написать
38. Изучение Scala
• Уже 27 книг
• Бесплатные книги:
– Scala for the Impatient
Cay Horstmann
– Programming in Scala
Martin Odersky, Lex Spoon, Bill Venners
– Programming Scala
Alex Payne, Dean Wampler
• Статья для Java’истов: Scala for Java Refugees
39. Scala IDE
• Коммандная строка Scala REPL
• Eclipse
• IntelliJ IDEA
• NetBeans
• Emacs
• TextMate
• …
• Kojo – развлекательная Scala для детей