Как будучи Java-программистом перестать сомневаться и перейти на Scala, а также о применимости Scala для Android (в соавторстве с Алексеем Пышненко)
18 декабря 2014
Нам нередко приходилось сталкиваться с сомнениями касательно перехода на Scala людей, которые в настоящее время пишут на Java. И в самом деле, насколько вообще перспективно переучиваться с простой, понятной и всем известной Java на какую-то там странную и никому неизвестную Scala? Кроме того, ситуацию осложняет тот факт, что поверхностное гугление находит помимо положительных отзывов о Scala и весьма негативные.
Примечание: Заметка написана в соавторстве с Алексеем Пышненко.
Действительно, как и в случае с любой другой технологией, существуют как положительные, так отрицательные отзывы. Но отрицательный отзывы обычно появляются из-за относительной (например, по сравнению с Java или PHP) высотой порога вхождения в язык. Такие элементы функционального программирования, как неизменяемые переменные, строгая статическая типизация или сопоставление с образцом, многим программистам непонятны, потому что это не то, чему их учили в школе на примере Pascal. В то же время эти программисты чувствуют себя довольно комфортно в своих интерпрайзах, поэтому не испытывают особой мотивации разбираться. Отсюда и появляются отзывы типа «Scala сложная, как C++», хотя это вовсе не так.
По существу, единственный реальный недостаток Scala — это относительно медленная компиляция. Но на современном железе (типа MacBook Pro и сравнимых машинах) это уже и не является проблемой. Что же касается высокого порога вхождения в язык, наш опыт показывает, что заинтересованный программист, написавший пару hello world’ов на Scala, уже где-то через полтора месяца работы над реальным проектом пишет на языке совершенно свободно. При этом те же программисты отмечают существенно бОльшую скорость разработки на Scala по сравнению с Java, а также существенно меньшее количество ошибок, особенно связанных с многопоточностью — за счет неизменяемости переменных и модели акторов (библиотека Akka).
Scala используется в Twitter (у них практически все, ну кроме БД, написано на Scala), Netflix (обработка HTTP, и множество бизнес-логики на Scala), Foursquare (написан и работает на Scala, веб-интерфейс на Scala), LinkedIn (веб-интерфейс написан на Scala, возможно и внутри что-то тоже), The Guardian, Sony, Siemens, Xerox, Novell, а также в Яндексе и многих других российских, украинских и белорусских компаниях (можете проверить по HeadHunter). Ежегодно выходит множество книг, посвященных Scala. Существует довольно большое, активное и дружелюбное сообщество программистов, ведущих блоги, выступающих на конференциях, пишущих подкасты и общающихся в списках рассылок. Посмотрите хотя бы рассылки scala-user@, akka-user@ и play-framework@ в группах Google.
Не стоит недооценивать важность комьюнити. Оно постоянно двигает язык вперед, и делает его все более мощным. На подходе Scala 3, которая сейчас называется Dotty. Это язык с dependent types, которые являются мечтой любого знакомого с ними программиста, желающего писать корректные программы. Помимо ученых, которые, надо сказать, работают далеко не на голом энтузиазме, языком занимается компания Typesafe, в которую не так давно было вложено немало инвестиций, самые значимые из которых составили 14 миллионов долларов. И они оправдывают эти инвестиции — популярность языка Scala растет с каждым днем, постоянно появляются все новые и новые вводные материалы для людей, заинтересованных, но не знакомых с языком, читаются доклады по теории типов на различных конференциях.
Что же касается опасения в отношении новых технологий, то его трудно не понять. Но, по всей видимости, в данном случае программист абсолютно ничего не теряет. Программируя на Scala, вы пишите под ту же JVM. Код на Scala даже может быть использован в коде на Java и наоборот. Притом несложно понять, как код на Scala транслируется в Java-классы, то есть вы просто пишите на Java с более приятным синтаксисом (кортежи, автоматический вывод типов). Те же Play, Akka и другие библиотеки успешно применяются программистами на Java. Так что, вы получаете универсальный опыт, применимый как для Scala, так и для Java.
Следует также отметить возможность разработки на Scala под Android (плюс см проект Scaliod).
Если вы когда-нибудь слышали про RxJava, то там представлен ровно тот подход, вокруг которого построена Scala — reactive programming. Это такой подход к event-driven архитектуре приложения, нацеленный на асинхронность во всем. В итоге все ваше приложение выглядит как совершенно прозрачная цепочка событий, где отлично видно причину и последствия любого действия пользователя. В итоге при какой-либо ошибке в бизнес-логике почти сразу же ясно, что пошло не так: отладка почти не отнимает времени. Ко всему прочему, код становится намного более компактным и выразительным, количество возможностей для обобщения логики разительно возрастает по сравнению с Java, при этом не теряя ни единой возможности, которую предоставляет Java.
Вот что говорят наши Android-программисты о достаточно скором для них переходе на Scala.
Очень заметно, как скорость разработки растет. Несмотря на то, что мы только вникаем в Scala, и не всегда все делаем правильно, а также тратим часть времени на обучение, скорость создания отдельного компонента / сущности / экрана заметно возросла, и продолжает расти.
В Scaloid, которым пользуется теперь наша команда, много очень удобных оберток над стандартными компонентами (SButton, SListView, и тд), которые сильно упрощают жизнь. Контекст теперь передается имплицитно, обработчики различных событий зачастую указываются прямо в конструкторе (имеется ввиду метод apply у companion object). Работа с коллекциями, несмотря на множество отзывов об их сложности со стороны опытных скалистов, стала намного приятнее. Теперь то, что в Java нужно было долго и упорно описывать, делается в несколько строк — map, flatMap, reverse, fold, что еще нужно?
Future сильно упростили код. AsyncTask’и хоть и вполне легковесны для Java, но ни в какое сравнение с легкостью и читабельностью Future они не идут. Код, обернутый во Future, отлично вписывается в код, работающий с UI. При чтении никакого переключения контекста не происходит, чего нельзя сказать о выделении собственного потока или использования AsyncTask.
Вот как можно сократить Java-код (взято отсюда):
@Override
protected String doInBackground(String... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
return "Executed";
}
@Override
protected void onPostExecute(String result) {
System.out.println("OnPostExecute");
}
@Override
protected void onPreExecute() {
System.out.println("OnPostExecute");
}
@Override
protected void onProgressUpdate(Void... values) {}
}
… переписав его на Scala:
println("OnPreExecute")
for (i <- 1 to 5) {
Thread.sleep(1000)
}
"Executed"
}.map(_ => "OnPostExecute")
.recover { case e => println(s"Error $e"); "OnError"}
В общем и целом, Scala сильно упростила разработку под Android. Больше нет ощущения борьбы с языком, которое иногда возникало в Java. Все просто идет своим чередом, одно вытекает из другого, все логично и красиво, и это здорово.
Мы надеемся, что данная заметка помогла вам развеять хотя бы часть сомнений по поводу Scala. Будем рады любым вашим комментариям в отношении написанного, а также ответным постам.
P.S. И кстати, даже Bruce Eckel любит Scala :)
Дополнение: Вас также может заинтересовать статья Мои впечатления от языка Scala после года работы с ним.
Метки: Java, Scala, Функциональное программирование.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.