Как будучи 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-код (взято отсюда):

private class LongOperation extends AsyncTask<String, Void, String> {
    @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:

Future {
    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 после года работы с ним.

Метки: , , .


Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.