Pull to refresh

Comments 82

Причина восьмая: scala implicit conversions
и метапрограммирование
А расскажите не усложняет ли это рефакторинг и вообще читаемость кода? Сам я не знаю Scala(пока) прочел про ваш восьмой пунт, и сразу вот такой вопрос возник.
Как показывает опыт команды — с внедрением языка упрощается и улучшается все)
implicit это вообще отдельная песня. Очень крутая штука! Правда в неумелых руках может привести к ужасным последствиям.
В большом проекте она и в умелых руках удивляет. Сюрпризы, которые можно разрешить в runtime дебаге
Тесты хорошо закрывают все проблемы, кроме имплиситных ексекьюшен контекстов.
Я ничерта не понимаю в Scala, но по паре-тройке обзорных статей, что я видел — он (она?) мне нравится. Действительно симпатичный язык.
Однако же… Поиск на Яндекс-Работе (Москва) даёт:
по слову Scala — 23 вакансии (причем если присмотреться, примерно треть из них это левые вакансии, попавшие в список по случайному совпадению слов)
С++ — 188
Python — 104
JavaScript — 151
Разница примерно на порядок.
Ну да, в ситуации когда пофиг чем заниматься, лишь бы работы побольше, Scala очень фиговый вариант)
Не работы побольше, а выбора побольше. Чтобы из множества вариантов выбрать наиболее подходящее.
Тут есть и обратный довод — чем больше выбора по работе, тем ниже оплата такой работы и выше конкуренция. Предлагаю понаблюдать за спросом не на яндекс. работе, а на тех же careers.stackoverflow.com, angel.co и прочих. Предложения от $150к в год не такая уж и редкость и вполне на уровне тех же явистов. Да, работодатель практически всегда подразумевает что Java вы знаете на не менее хорошем уровне, как и Scala. Да, несмотря на уже немолодой возраст Scala как языка у работодателя есть некий уровень допущения что все и сразу вы не сможете знать и часто имеется время на research вопросов.

То есть так или иначе просто писать на Scala вообще никак не притрагиваясь к Java коду — думаю что практически не получится. Либо если разработка чего-то специализированного, типа моделирования различных систем, где основа — только математика.

А в целом, Scala — хороший язык для выражения мыслей и понимания их остальными, а не «код ради кода». Единственно что хотелось бы — побольше именно нативных библиотек, чтобы не заморачиваться с обертками (те же итераторы, структуры/классы и прочее). Нативный JSON вроде должен в скором времени появиться, как и XPath (полноценный).
Ну яндекс.работа — это был просто быстрый пример.

Насчет конкуренции… Тут еще есть такой побочный эффект. Никто не хочет быть говнокодером — все хотят быть (в перспективе) сеньором, архитектором и так далее. Выбирая популярный язык (C++, JS, Java, etс), мы совершенно точно знаем, что потраченные на него годы не пропадут даром и какая-то работа будет всегда и везде. Если же мы хотим быть крутым специалистом на Scala, Rust или ещё каком-нибудь Dart, то свербит мысль типа — «а что будет через 5 лет? а не загнётся ли оно? а не выстрелит ли какой-нибудь молодой язык-конкурент, который будет ещё моднее и современнее?»
5 лет — срок, за который может загнуться что угодно и по разным причинам. Потраченные годы на саморазвитие точно не пропадут даром, ибо дорогой спрос есть только на тех, кто умеет решать задачи и достигать поставленных целей экономически обоснованными путями (дешево). А правильно выбранный язык и стек технологий может помочь в этом. И мониторить что эффективнее для одного, а что для другого, насколько развито то или иное community и в каком направлении идет — это постоянно актуальная задача, не имеющая частного решения.

Опциона на определенный уровень актуальности знаний для хеджа еще не придумали, к сожалению. Хотя, пенсия может и есть формально такой инструмент.

Жизнь сложная штука, да. Сюжет порой фиговый, но графика классная.
«Что угодно» — формально как бы верно, в жизни всякое бывает.
Однако же на практике я почему-то уверен на 99 и 9 в периоде, что тот же C++, живя уже 3 десятка лет, проживет ещё минимум столько же. Разумеется, видоизменяясь и совершенствуясь.
Насчет Скалы — совершенно не уверен (хотя желаю ей здоровья и всё такое).
Абсолютли. Сюда же:

За свою жизнь я не видел ни одного программиста C++, изучившего Java, а потом заявившего «Нет, мне не нравится этот язык, C++ лучше». Теперь у меня какое-то дежавю: я снова не вижу ни одного Java-программиста, изучившего Scala и отказавшегося от этого языка.


Для меня такие рассуждения звучат как полная фигня. В 95% случаев язык выбирает не программст или язык(и) вообще уже давно выбран(ы). Ну и см. предыдущее замечание про работу.
Можно изучить один язык программирования и использовать его всю жизнь. C++ и Java хорошие кандидаты для такой стратегии, потому что про них забудут ещё очень и очень не скоро. Но есть другая стратегия: двигаться вперёд, изучать новое, не стоять на месте, и эта стратегия не хуже первой. Какую выбирать, каждый решает сам.
Быть в курсе тенденций, иметь общее представление о новых языках — это одно. Но чтобы реально знать язык, библиотеки и прочее, надо его использовать и довольно много. А это я делаю только на работе. Поэтому если будет новый язык в проекте, выучу. Если нет, то нет.
+1
90% известных мне людей, пописавших продакшен на scala возвращаются в Java только в безвыходных ситуациях. И то с матами и чувством подступающей к горлу рвоты.
Зато в Европе ситуация намного лучше. Мне предлагали работу в Германии, после интервью, в котором я показал лишь базовое знание монадов.
Вакансии появятся, ибо за языком будущее)
К слову, ищу 3+ разработчиков scala или java->scala в команду в ТКС на большой проект.
Вакансии есть, людей мало
Теперь у меня какое-то дежавю: я снова не вижу ни одного Java-программиста, изучившего Scala и отказавшегося от этого языка.
Я пробовал и отказался. И дело не в языке — он крутой, а в инфраструктуре. Если sbt заменят на что-то более удобное, полечат проблему с компиляцией под разные версии Scala и сделаю базовые артефакты поменьше размером, то может быть сделаю еще попытку.
А можно поинтересоваться, чем вам неудобен sbt? Например, лично на мой взгляд, он гораздо удобнее мавена и даже гредла.

И что там за проблема с компиляцией под разные версии Scala? Кажется, сейчас в sbt есть для этого все инструменты. Если правильно написать билдскрипт, что совсем не сложно, то для компиляции и деплоя артефактов для всех версий скалы можно написать просто +publish в консоли sbt. Да, к сожалению, есть проблемы с совместимостью, если вы используете компиляторозависимые вещи вроде макросов, и здесь приходится делать костыли, но, как мне кажется, проектов с такими особенностями совсем мало.

Размер артефактов — да, есть такая проблема. Поэтому, например, из основного дистрибутива скалы и начали вычищать лишнее, вроде XML.
плюсую за sbt, страшненький но зато мощный какой, казалось бы с первого взгляда такой не понятный, но gradle для меня почему то более непонятен на практике
Мне Scala нравится, и я на ней пишу проекты. И в целом, sbt работает, проекты собирает и т.д.
Но как только начинаешь смотреть на него не с позиции «лишь бы проект собрался», начинаешь удивляться как его вообще могли таким сделать.
Если сравнить с гредлом, то:
Во первых, у гредла есть просто супермега киллер фича. Это врапер. Возможность работать с проектом ничего не устанавливая это мегаудобно.
Во вторых, это понятная структура проекта. Просто build.gradle в котором все описано. Больше ничего не надо.
У Sbt структуру делали по очень сильной укурке, не иначе. Ничем другим невозможно объяснить эти кучи вложенных каталогов с отдельным каталогом для сборки непонятно чего. Версию sbt надо указывать в отдельном файле. Сама сборка описывается в двух файлах, build.sbt и Build.scala… и т.д. и т.п.
Так и хочется спросить, кто нибудь хоть пару минут задумывался как всем этим будут пользоваться? Походу лепили студенты двоечники по остаточному принципу…

Для меня гредл образец того как надо проектировать системы сборки.
Ну на самом деле sbt очень сильно проэволюционировал за последние несколько лет. Когда я его видел в версиях 0.11-0.12 и более ранних, у меня было совершенно такое же ощущение, что и у вас. Однако в версии 0.13, которая сейчас последняя, sbt стал весьма удобен. Для простых и средних проектов в sbt достаточно одного файла, build.sbt. Для сложных проектов с дополнительными настройками, кодо/тестогенерацией, публикацией артефактов и прочим в любом случае имеет смысл разделить один-единственный билдскрипт на несколько, каждый из которых отвечает за свою часть.

Соответственно, структура 99% проектов на sbt выглядит как файл build.sbt в корне и файл build.properties в каталоге project/, в котором указана версия sbt. Строго говоря, в gradle тоже два или более файлов: build.gradle и settings.gradle, в котором нужно указывать иерархию проектов, и у каждого проекта свой build.gradle. «Кучи» вложенных каталогов в sbt тоже нет — есть подкаталог project, в который кладутся scala-файлы и build.properties, но, как я уже сказал, в 99% случаев ничего, кроме build.properties там не будет, если вы сами не захотите. Также там в отдельном файле прописываются дополнительные плагины, если они вам нужны; да, в этом случае будет отдельный файл, когда в gradle плагины описываются в отдельной секции в основном скрипте, но лично на мой взгляд, это совершенно непринципиальная разница.

Вот, например, мой проект на sbt. Сборка состоит из нескольких проектов, причём все они определены в build.sbt. В project/ есть несколько файлов, это build.properties с версией, plugins.sbt с описанием плагинов, TestGeneration.scala с кодом, который генерирует тесты, и build.sbt, в котором указаны зависимости для TestGeneration (я, кстати, не знаю, можно ли так сделать в Gradle без отдельного плагина, хотя, наверное, можно). На мой взгляд, ничего особо сложного в структуре сборки там нет.

Замечание насчёт враппера справедливо наполовину: у sbt есть (неофициальный) скрипт, который работает точно так же, как и gradlew: если хотите, вы можете закоммитить его в свой проект и запускать sbt как ./sbt. Он выкачает нужную версию sbt автоматически. Этот же скрипт можно установить при желании и глобально. Но да, в стандартную поставку sbt возможность генерации враппера не входит, и я согласен, это было бы очень удобно.
>«Кучи» вложенных каталогов в sbt тоже нет — есть подкаталог project, в который кладутся scala-файлы и build.properties

http://i.imgur.com/CHnslzZ.png
А тогда что это за требуха там постоянно болтается? При чем я еще не все дерево каталогов развернул.
Почему этой требухи нет в гредле?
Зачем вообще было делать эту отдельную папочку для проекта?
Зачем вообще было делать 2 разных формата описания сборки: build.sbt и Build.scala?
Почему нельзя было указывать версию sbt в общем скрипте сборки?
Почему в гредле подумали над проектом и сделали враппер, один файл одного формата для обычного проекта и один дополнительный файл для многомодульного, а тут понавертели кучу всего?
target-подкаталоги — это результаты компиляции кода проекта. sbtшная сборка — это тоже scala-код, который нужно компилировать. Это неизбежно — groovy может запускаться под интерпретатором, а scala — нет. Собственно, поэтому этой требухи в гредле и нет.

Отдельная папочка для проекта сделана для унификации (сборка на sbt компилируется sbt) и для того, чтобы было куда положить скальные сборочные файлы. Не мусорить же ими в корне проекта? Почему не было разрешено положить Build.scala в корень проекта, я не знаю, но теперь это в любом случае неактуально — писать билды в scala-файлах уже нет необходимости.

Два формата описания сборки — это, к сожалению, пережиток прошлого. В скале, когда sbt создавался, не было макросов и прочих удобств, и сборочные скрипты на чистой скале выглядели страшно. Scala — не скриптовый и не интерпретируемый язык, и сделать синтаксис как в груви там не получится. Для этого сделали упрощённый формат в build.sbt, в котором можно по-быстрому задать основные настройки, а если нужно что-то более сложное, то необходимо юзать скалу напрямую. Однако сейчас формат sbt и скальных билдов становится всё более унифицированным, и сейчас по сути в sbt-файлах можно свободно писать практически любой скальный код. Описывать именно параметры сборки, т.е. зависимости, версию языка, опции компилятора и прочее, в скальном билде сейчас наоборот не рекомендуется, лучше использовать build.sbt. В project, как я уже писал, нужно хранить прочий код, вроде генерации тестов и схожего барахла, и здесь как раз хорошо, что есть отдельный каталог для этого.

Насчёт версии сборки — потому что для того, чтобы вообще прочитать и проанализировать файл сборки, нужно иметь в наличии sbt, а как вы узнаете тогда, какую версию sbt качать? Насколько я вижу, в гредле версия тоже не определяется в build.gradle, а зависит от того, что было указано при вызове таски wrapper, и она запрятана где-то внутри каталога wrapper.

Насчёт отсутствия враппера в официальной поставке — ничего не могу сказать. Лично я не испытываю от его отсутствия неудобств, установить дополнительный пакет пакетным менеджером в систему несложно.
Да я в курсе почему там образуется столько мусора.
Мне просто не нравится такая корявоя реализация.

> Насколько я вижу, в гредле версия тоже не определяется в build.gradle

task wrapper(type: Wrapper) {
gradleVersion = '2.7'
}

вот это все что надо указать в в build.gradle
Это указание версии для враппера для таски gradle wrapper, а сам враппер нужно сгенерировать, чтобы получить скрипт для гредла нужной версии. Наличие этого в билде не означает, что вызвав gradle или ./gradlew в каталоге проекта, вы тут же получите гредл нужной версии — для этого вам нужно перегенерировать враппер, что можно сделать, только уже имея на руках гредл. Поэтому это совершенно неравноценные вещи, по сравнению с build.properties: аналогом build.properties у гредла будет gradle/wrapper/gradle-wrapper.properties:
#Wed Oct 28 20:26:00 MSK 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-bin.zip

где, собственно, и можно наблюдать конкретную версию гредла.

Да я в курсе почему там образуется столько мусора.
Мне просто не нравится такая корявоя реализация.

Выше вы писали, что не в курсе:
А тогда что это за требуха там постоянно болтается?… Почему этой требухи нет в гредле?

Собственно, на это я и отвечал. Какая, по-вашему, была бы не корявая реализация, с учётом того, что Scala нельзя интерпретировать так же, как груви?
Прежде чем писать ерунду про гредл, почитайте как он работает что ли.
Неохота вам сюда перепечатывать всю документацию…
Для того чтобы обновить версию гредла, мне достаточно обновить его версию в этой таске. Дальше он сам все обновит. Версия в gradle-wrapper.properties это вообще не конфиг для указания версии гредла, это результат работы вышеуказанной таски в которой указана версия, в виде адреса для скачивания архива с гредлом.

>Выше вы писали, что не в курсе

Есть такая штука, называется «риторический вопрос». Это вопрос на который не нужен ответ. ))
Я знаю как работает гредл; я делал на нём несколько проектов и довольно подробно изучал его документацию, и я даже писал к нему плагины. И именно поэтому мне правда интересно, как именно эта ваша магия работает. У меня её вызвать не получилось.

1. Создаю пустой каталог, в котором лежит build.gradle следующего содержания:
task wrapper(type: Wrapper) {
    gradleVersion = '2.4'
}


2. Поскольку у меня в системе уже установлен гредл, а каталог свежесозданный, в котором ничего, кроме build.gradle, нет, создаю враппер вызовом системного гредла:
% gradle wrapper

и проверяю версию:
% ./gradlew --version
------------------------------------------------------------
Gradle 2.4
------------------------------------------------------------

Build time:   2015-05-05 08:09:24 UTC
Build number: none
Revision:     5c9c3bc20ca1c281ac7972643f1e2d190f2c943c

Groovy:       2.3.10
Ant:          Apache Ant(TM) version 1.9.4 compiled on April 29 2014
JVM:          1.8.0_66 (Oracle Corporation 25.66-b17)
OS:           Mac OS X 10.10.5 x86_64


3. Изменяю версию в таске:
task wrapper(type: Wrapper) {
    gradleVersion = '2.7'
}


4. Проверяю версию:
% ./gradlew --version
------------------------------------------------------------
Gradle 2.4
------------------------------------------------------------

Build time:   2015-05-05 08:09:24 UTC
Build number: none
Revision:     5c9c3bc20ca1c281ac7972643f1e2d190f2c943c

Groovy:       2.3.10
Ant:          Apache Ant(TM) version 1.9.4 compiled on April 29 2014
JVM:          1.8.0_66 (Oracle Corporation 25.66-b17)
OS:           Mac OS X 10.10.5 x86_64

Как было 2.4, так и осталось.

5. А вот если я перезапущу таску на враппер:
% ./gradlew wrapper

То после этого версия будет новая, как и ожидалось:
% ./gradlew --version
------------------------------------------------------------
Gradle 2.7
------------------------------------------------------------

Build time:   2015-09-14 07:26:16 UTC
Build number: none
Revision:     c41505168da69fb0650f4e31c9e01b50ffc97893

Groovy:       2.3.10
Ant:          Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM:          1.8.0_66 (Oracle Corporation 25.66-b17)
OS:           Mac OS X 10.10.5 x86_64


6. Кроме того, на системный гредл версия в build.gradle не влияет (что естественно, потому что это просто настройка таски для гредла):
% gradle --version

------------------------------------------------------------
Gradle 2.8
------------------------------------------------------------

Build time:   2015-10-20 03:46:36 UTC
Build number: none
Revision:     b463d7980c40d44c4657dc80025275b84a29e31f

Groovy:       2.4.4
Ant:          Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM:          1.8.0_66 (Oracle Corporation 25.66-b17)
OS:           Mac OS X 10.10.5 x86_64


Сравним с тем скриптом для sbt, про который я писал выше.

1. Создаю новый каталог, в нём файл project/build.properties с версией:
sbt.version=0.13.5


2. Сохраняю скрипт в файл sbt, запускаю его:
% ./sbt -v
No extra sbt options have been defined
Detected sbt version 0.13.5
Starting sbt: invoke with -help for other options
Using default jvm options
Detected Java version: 1.8.0_66


3. Меняю версию в build.properties:
sbt.version=0.13.9


4. Проверяю версию:
./sbt -v
No extra sbt options have been defined
Detected sbt version 0.13.9
Starting sbt: invoke with -help for other options
Downloading sbt launcher for 0.13.9:
  From  http://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/0.13.9/sbt-launch.jar
    To  /Users/netvl/.sbt/launchers/0.13.9/sbt-launch.jar
Using default jvm options
Detected Java version: 1.8.0_66


5. Системный скрипт, кстати, тоже осведомлён о версиях sbt и выберет именно ту, которая указана в build.properties. Вообще, строго говоря, в системе устанавливается только скрипт-лаунчер, а версия sbt зависит только от build.properties, и сам sbt выкачивается в пользовательский каталог.

Не поймите меня неправильно, мне очень нравится гредл, и для Java-приложений я использую именно его и советую всем вокруг тоже. И у sbt есть множество проблем, в том числе и в семантике — например, я до сих пор не очень понимаю, как именно работают «автоматические» плагины, а система scope axis, скажем так, далека от интуитивно понятной; система плагинов в гредле мне тоже нравится больше. Но я просто хотел сказать, что в данном конкретном случае утверждать, что версия гредла указывается в build.gradle, а всё остальное делается автоматически, не совсем корректно.

Версия в gradle-wrapper.properties это вообще не конфиг для указания версии гредла, это результат работы вышеуказанной таски в которой указана версия, в виде адреса для скачивания архива с гредлом.

Безусловно. Я имел в виду, что именно gradle-wrapper.properties определяет версию, которая будет использоваться gradlew, и чтобы её обновить правильно, gradlew нужно перегенерировать вручную.
То что вы описали написано у них в доках.
task wrapper(type: Wrapper) {
gradleVersion = '2.4'
}
эта штука позволяет сгенерить враппер, дальше они советуют руками менять версию если надо(в gradle-wrapper.properties файле) либо генерить враппер заново
Как лихо вы выкинули встроенную функцию gradle, сделав какую-то фигю.
Сравнили все это с наколенным костылем для sbt и сделали вывод, что гредл фигня))

>Но я просто хотел сказать, что в данном конкретном случае утверждать, что версия гредла указывается в build.gradle, а всё остальное делается автоматически, не совсем корректно.

Это абсолютно корректно. Ибо враппер это встроенная функция гредла. Все что надо это изменить версию гредла в build.gradle.
В sbt этоq возможноcnb в принципе, хоть с запуском таски хоть без. Только наколенными костылями.

P.S. Рассказывать, что вы можете наскриптовать любое поведение, это глупо. Ибо написать можно все что угодно. Мы говорим о возможностях конкретных приложений, а не о том, чего можно навертеть при желании.
Как лихо вы выкинули встроенную функцию gradle, сделав какую-то фигю.

Я не понимаю, что вы имеете в виду. Я ничего никуда не выкидывал. Скажите, в чём конкретно я не прав в тех шагах, которые я привёл.

Это абсолютно корректно. Ибо враппер это встроенная функция гредла. Все что надо это изменить версию гредла в build.gradle.

Я не спорил, что генерация враппера — это встроенная функция. Я говорю про то, что для смены версии гредла недостаточно «изменить версию в build.gradle», дополнительно нужно ещё перегенерировать враппер заново. Здесь нет никакого «автоматически».

В sbt этоq возможноcnb в принципе, хоть с запуском таски хоть без. Только наколенными костылями.

Я не понимаю, почему стандартный скрипт из поставки sbt вы называете костылём. Это то же самое, что назвать команду gradle, которая устанавливается системным пакетным менеджером, костылём. Да, я не спорю, что в sbt нет официального аналога gradle wrapper; но это совершенно ортогональная к управлению версиями проблема. build.properties понимается как официальным скриптом, так и sbt-extras.

сделали вывод, что гредл фигня

Не понимаю, где вы это увидели. Наоборот, я сказал что гредл мне очень нравится.
>Я говорю про то, что для смены версии гредла недостаточно «изменить версию в build.gradle», дополнительно нужно ещё перегенерировать враппер заново. Здесь нет никакого «автоматически».

Дальше можете ничего не рассказывать.
Если встроенная таска, которая занимается обновлением гредла, и которой надо только указать версию — не «автоматически». То о чем вы тут вообще рассказываете? Писать скрипт для системы, которая сама ничего не умеет, это что ли «автоматически» ??
В общем понятно все с вами…
У нас с вами, видимо, разное понимание понятия «автоматически». Ещё раз:
  • для того, чтобы изменить версию гредла, которая будет использоваться при ./gradlew, нужно изменить версию в build.gradle и запустить ./gradlew wrapper
  • для того, чтобы изменить версию sbt, которая будет использоваться при ./sbt, нужно изменить версию в project/build.properties

Ключевой момент: в первом пункте нужно запустить команду для перегенерации враппера, во втором пункте делать ничего не нужно. Это именно то, что я подразумеваю под «автоматически».

Писать скрипт для системы, которая сама ничего не умеет, это что ли «автоматически» ??

Про что вы вообще говорите? Есть скрипт из официальной поставки sbt, который вы получите в /usr/local/bin или /usr/bin после brew install sbt/pacman -S sbt/прочее — он понимает build.properties. Есть скрипт из sbt-extras, который вы можете скачать из репозитория github.com/paulp/sbt-extras и поместить в корень проекта — он тоже понимает build.properties. Ткните, пожалуйста, пальцем, где здесь «сама ничего не умеет»? Если вам так не нравится слово «скрипт», то напомню, что и gradle, и gradlew — это тоже скрипты, которые вызывают соответствующие джарники. Разница с sbt исключительно в том, что гредл умеет генерировать враппер сам, а sbt — нет.
SBT достаточно «мощный» тут не поспоришь, но Gradle все же более лаконичный и логичный, поэтому тут я соглашусь скорее с solver
Если посмотреть Ваш пример и популярные Opensource проекты, которые билдятся sbt, то там совсем все по-другому — они пишут «ацкий» scala код именно внутри дериктории project во всяких Build.scala, Dependencies.scala etc(сам я тоже оставляю рутовый build.sbt почти пустым). И если честно, там совсем все не логично и эстетически красиво. Билдил проекты и Gradle и SBT, и почти одинаковые мультимодульные проекты гораздо проще собирать Graddle. Плюс ко всему SBT на порядок медленнее даже визуально. Еще у IDEA с SBT все намного печальнее, чем с Gradle(мне лично не хватает комплишена версий либ).
Но лично я, не смотря на все это, почему то не смог отказаться от SBT, в виду какого-то глубинного ощущения, что у этого инструмента есть будущее. Ну верю я в Typesafe, что поделаешь. Да и на всю тормознутость и нелогичность, все равно гораздо приятнее писать билды на scala, чам на groovy, не смотря на красоту gradle dsl.
популярные Opensource проекты, которые билдятся sbt

Это следствие того, что популярные проекты достаточно долго развиваются, и переделывать билд без веских на то причин никто не станет. Новые проекты, я думаю, всё-таки стараются следовать современным best practices. Dependencies.scala смысл имеет, на мой взгляд, но это на вкус и цвет.

Плюс ко всему SBT на порядок медленнее даже визуально. Еще у IDEA с SBT все намного печальнее, чем с Gradle(мне лично не хватает комплишена версий либ).

Здесь, к сожалению, не могу не согласиться :(
Совсем не обязательно пользоваться sbt. Я пока от него тоже отказался, т.к. он ещё сырой и в принципе не такой уж интуитивный. Зато для сборки scala-проектов вполне подходит gradle. В интернете давно описаны стандартные задачи для gradle, которые по умолчанию доступны в sbt, типа запуска scalatest или консоли в контексте проекта.
Помнится, некоторое время назад была статья про переход команды разработки с Python на Haskell от лица ПМ. Достаточно интересно описывались фактическое изменение требуемого времени на разработку и отладку.
Интересно было бы услышать про подобный опыт / цифры для конкретных команд, которые перешли с Java на Scala.

disclaimer — я не пишу на Java, мне просто в целом интересны эти подробности
Переход на что-то новое всегда сопровождается проблемами. В любой команде есть консерваторы, которые руками и ногами будут упираться до последнего. ИМХО легче создать новую команду, чем переводить с Java на Scala старую.
Проблемы в первые пол года. Дальше сплошная эйфория
Переходили 4 года назад. Цифры не считали, но по ощущениям скорость выросла в разы.
Сейчас проект разросся и все равно темп особо не убавился.
Спасибо за интересную статью. Я с вашего позволения хотел бы дополнить ее ссылкой на еще одну статью, в которой речь идет об опыте практического использования Scala в течение одного года. TL;DR — язык не без косяков, но в целом годный и хорошо подходит для многих практических задач. И как минимум не хуже Java.
Пожалуйста! Очень рад, что статья вам понравилась!
String mama = «Jane»;
final String papa = «John»;

Вторая строка неизменяемая, что гарантирует её неприкосновенность, что уменьшает вероятность багов, бла-бла-бла…

В Java строки в принципе неизменяемые. Так что и первая тоже. Совсем другое дело — локальная переменная mama, которой можно присвоить другую строку.
И откуда цифра в 28%?
Неправильно выразился. Имелась в виду неизменяемая переменная. Спасибо за замечание.
Scala неизменно отпугивает обилием ~, !, ->, <-, =>, !!, ~~ и прочих значков.
IDE жутко тормозят, парся сложный синтаксис.
Не спорю, если выучить синтаксис какой-то либы, то писать легко и приятно. Например, потратив пару дней на изучение парсеров/комбинаторов, я написал красивый и изящный код. Только вот беда, этот код понимаю я один. Если кому-то придется фиксить там баг, то ему придется потратить тоже пару дней, чтобы в результате написать 1 строчку.
А в слеудющий раз напишет за пару часов или минут. Это называется опыт.
Это аргумент для тех у кого оплата зависит от количества написанных строк.

В любом случае правильнее всё же сказать, что это не 1 строчка писалась целых пару дней. Это пару дней фиксился баг. И помимо написания 1 строчки кода сюда включены поиск ошибки, её анализ и обучение работе парсеров.

Вообще, то что изменилась всего 1 строчка — это приятный бонус. Меньше меняется кодовой базы — меньше вероятности внесения новых багов. Меньше писать новых тестов и переделывать старых.
> Scala неизменно отпугивает обилием ~, !, ->, <-, =>, !!, ~~ и прочих значков.

Значков, которые встроены в Scala примерно столько же, сколько и в других языках типа Java и C#. Да, Scala разрешает использовать значки в названиях методов, но никто же не заставляет.

> IDE жутко тормозят, парся сложный синтаксис.

Да, компиляция проходит медленее, чем в Java. Правда, вроде не столько из-за парсинга, сколько из-за автовывода и проверки типов. Т.е. делает более умные вещи, облегчая жизнь разработчику.

> Например, потратив пару дней на изучение парсеров/комбинаторов, я написал красивый и изящный код.

А какая альтернатива, например, для Java? JavaCC, Antlr — там разве не надо тратить время на изучение синтаксиса? Мощь Scala в том, что она позволяет решить проблемы с помощью DSL не выходя за рамки языка.
Из собственного опыта знакомства со Скалой сложилось впечатление, что воспринимать этот язык как Java, только лучше нельзя. В конечном счете скала другой язык, со своей инфраструктурой и best-practices. Серьезных причин для глубокого приобщения к ним я пока не нашел. В то же время писать после скалы на джава стало грустно. Вся многословность джавы стала сильно резать глаза. Поэтому для себя открыл Kotlin и «программирование на досуге» снова стало приносить удовольствие. Kotlin очень похож на Scala, но при этом не претендует на замену всей инфраструктуры Java (или просто еще не дорос до этого), лишен излишней сложности, быстрее компилируется и по понятным причинам (авторы языка и IDEA одни) можно ожидать великолепную поддержку в любимой IDE.
Печалит, только, что Kotlin еще даже не в бете (хотя уже близок!). А там еще года полтора-два нужно будет ждать, пока им реально можно будет пользоваться.
Еще довод: крутые фреймворки, написанные на Scala, такие как Akka, Spark, Play. Бывает, что намучившись с их Java API, люди прислушиваются к голосу здравого смысла и переводят разработку на Scala.
Play и Spark -это хорошие кандидаты для последующих статей. Надеюсь у меня будет время этим заняться!
>> За свою жизнь я не видел ни одного программиста C++, изучившего Java, а потом заявившего «Нет, мне не нравится этот язык, C++ лучше».

Посмотрите на меня =)

А Scala лучше Java — это факт. Впрочем, не нужно быть чем-то невероятным, чтобы быть лучше Java.
idea + плагин от jetbrains (не всё хорошо, но жить можно), scala-ide (на базе клипсы), ensime (имеет возможность скрещиваться с некоторыми текстовыми редакторами).
Я прошел пару курсов на Coursera по Scala от Одерски. И скажу что голову скала прочищает очень сильно, но продакш код я по прежнему пишу на Java 8 с использованием тех подходов что освоил в Scala и это главное ради чего ее стоит выучить. Современная ява и библиотеки совсем дают возможность писать без того содрогания что было во времена Java 6 в том числе с использованием функциональных и реактивных подходов.
вот только все равно кода больше и вагон императивности(
Пробовал Scala и Clojure. Остановился на Clojure просто лишь потому, что он приятнее, красивее и проще.
После Clojure писать на чем-то другом — настоящее мучение, честное слово :)
На мой взгляд, огромный плюс в Скале, это то, что каждый statement он же и expression. Мне тяжело теперь понять, почему if… else… не возвращают значения в Джаве. А самый угар это с try, ведь он почти всегда бывает на запросе данных.
Поясню, в Скале за try ответствена монада Try[x] которая либо содержит х, либо содержит исключение. В джаве для этого всегда надо писать много строк, инициализируя х как null, и в try блоке присваивать значение и лишь потом возвращать из функции. Это где то 4 строки к одной.
Причина первая: опыт показывает, что назад не возвращаются
Вижу, что большинство находится под вау-эффектом, поэтому вброшу свою лопату пессимизма. У коллеги был реальный проект на scala. В команде было два скалиста и несколько джаверов. Задача — процессинг событий сети и интеграция с системами. Что было замечено (с позиции менеджера проекта):
  • Вопреки «высокому порогу вхождения», джависты достаточно быстро освоили основные принципы Scala и начали строчить код.
  • У скалистов не было единообразия в коде, стиле и решениях. Джависты же писали более читабельный и единообразный код, следуя гайдлайнам джавы.
  • Скалисты пытались использовать как можно больше возможностей языка, тогда как джависты ограничивались лишь необходимым минимумом.
  • Скалисты постоянно злоупоребляли абстракциями, которые не имели к предметной области никакого отношения.
  • Скалисты вцелом пытались написать короче (объявляя это «красотой» решения), тогда как джависты — понятней.
  • Интересный факт: скалисты не могли сходу с уверенностью сказать о том, что делает тот или иной фрагмент кода, написанного другим, из-за огромного количества неявностей, предоставляемых Scala. Только после анализа контекста с помощью IDE, а иногда просто в дебаггере.
  • Постоянно приходилось использовать решения из экосистемы Java, которые иногда давали проблемы с интеграцией в Scala (code-enhancement, reflection, etc.)
  • Отдельный вопрос — экосистема Scala. Извечная полемика какую библиотеку использовать, что подключать и вообще зачем новая библиотека scala, если есть прекрасная старая из java.
  • Хоть и сложно давать оценку производительности, но какого-либо существенного прироста замечено не было. Коллега уверен, что на java все было бы сделано быстрее и качественней.
  • Не аргумент, но головная боль для менеджера: специалистов по scala на порядок меньше, чем по java. Всегда будет проблема ресурсов.

В итоге, коллега уверен, что делать проект на scala было ошибкой и очень рискованным решением.
Писал полтора года в команде из 10 разработчиков на Scala. Сначала все болели проблемами «а тут вот новая фишка, давай применим!», вместе с обратной крайностью — Java кодом на Scala. Через пол года все устаканилось. А теперь, когда пишу на Java иногда, мне тяжело понять, зачем надо так много строчек для мелочей. Тот проект все еще жив (я увы уже не с ними), обрастает фичами и все довольны.
Из всего выглядит только как одна проблема — кадры.
С некоторыми пунктами вполне можно согласиться. Но некоторые наверняка писались со слов «джавистов», слишком уж субъективно сформулированы. Это сильно напоминает мне собственный опыт общения с консервативно настроенными java-программистами, которых без понимания и мотивации с их стороны просто заставили использовать скалу. Результат вполне естественный — отторжение. Вот например:

> Скалисты пытались использовать как можно больше возможностей языка, тогда как джависты ограничивались лишь необходимым минимумом.

Кто определял меру необходимости? Уверен, что джависты.

> Скалисты постоянно злоупоребляли абстракциями, которые не имели к предметной области никакого отношения.

Злоупотребление абстракциями — любимое развлечение начинающих программистов, которые только познакомились с идеями ООП. Попытка объявить это недостатком конкретного ЯП настораживает…

> Скалисты вцелом пытались написать короче (объявляя это «красотой» решения), тогда как джависты — понятней.

Понятней для кого? Очевидно, для джавистов. И да, код на скала обычно сильно короче и красивее.

> Постоянно приходилось использовать решения из экосистемы Java, которые иногда давали проблемы с интеграцией в Scala

Ну да, небось пытались затащить в проект какой-нибудь Spring или Hibernate и огребли. Зачем вообще тогда скалу брали…

> Отдельный вопрос — экосистема Scala. Извечная полемика какую библиотеку использовать, что подключать и вообще зачем новая библиотека scala, если есть прекрасная старая из java.

Ага, как я и предположил по предыдущему пункту. Джависты натащили в проект «прекрасных старых» библиотек и сами же потом начали возмущаться, что они плохо подходят.

> Хоть и сложно давать оценку производительности, но какого-либо существенного прироста замечено не было. Коллега уверен, что на java все было бы сделано быстрее и качественней.

«Коллега» — это видимо тот, с чьих слов записаны эти пункты. Мне один такой коллега расказывал, что он со своими познаниями в java.util.concurrent может написать на джаве Акку за неделю. Что с ним стало через год? Пишет Spark-коннектор для распределенной системы. На скале, конечно.

И да, первый и последний пункт противоречат друг другу. Это один из признаков, что у менеджера не все в порядке с головой. Как иначе объяснить то, что он столкнул людей лбами в своем проекте, настолько, что они разделились на две группировки «скалисты» и «джависты». Видимо, скалисты оказались в меньшинстве как количественно так и по сеньорности, и все запиливали демотивированные джависты, у которых выбили почву из под ног незнакомым стеком технологий. В итоге получилось так себе, но стоит ли винить во всем язык программирования?

P.S. Не взыщите, если неверно восстановил ситуацию. Делать глубокие выводы по одному комментарию — дело неблагодарное. Но уж очень знакомыми кажутся аргументы.
Я не совсем в курсе всех нюансов проекта, но вывод вполне определенный. Программеры приводят вполне аргументированные доводы как за, так и против новой технологии. Однако есть совершенно отличная точка зрения менеджера проекта, которая больше базируется на целесообразности использования той или иной технологии, которая в конечном итоге выражается в человекочасах, рисках и, соответственно, деньгах. С этой точки зрения люди приходят к совершенно иным выводам. Все потому, что менеджеры оценивают технологии с точки зрения эффективности решения конкретной задачи, тогда как программеры практически всегда в технологии видят неограниченные возможности, которые она им предоставляет. Поэтому «вау» вторых часто выливается в убыток для первых. И очень часто бывает так, что старая дубовая технология превосходит по надежности и минимизации затрат любую новую, которая казалось бы призвана сделать работу еще более эффективной. Любая инновация всегда рискована.

Злоупотребление абстракциями — любимое развлечение начинающих программистов, которые только познакомились с идеями ООП.
В данном контексте это не ООП, а модный ФП. Scalaz, shapeless и прочая академическая лабуда, превращает код в перлоподобную кашу, и никак не относится к решаемой задаче.

В итоге получилось так себе, но стоит ли винить во всем язык программирования?
Я и не виню ни в чем. Но статья именно про переход из Java в Scala, типа «Вы еще пишите на Java? Тогда мы идем к Вам.» Поэтому я пытаюсь задать правомерный вопрос: «а действительно ли стоит»? Новый язык, новый стек технологий (очень лимитированный и зеленый, по сравнению с Java), интеграция с Java очень условная, поддерживается такими компаниями как (кто?). Кроме того сам язык достаточно эстетически неприятный, неминималистичный, передроченый всевозможными концептами из разных парадигм (чувствуется жесткий методичный немецкий подход) Этакий монстр Франкенштейна-Одерски. Вобщем, на любителя. В своих проектах я по мере необходимости пользую Groovy, который тоже позволяет убрать под ковер многабукв. С нетерпением жду релиза Kotlin-а. Со Scala много раз не срасталось.
Да, согласен, что подход «вот вы ту все пишите на беспонтовой джаве, а я вас сейчас быстренько пересажу на модную скалу» в реальной жизни не работает. Только если все (и менеджмент — в первую очередь) четко понимают, зачем конкретно они взяли скалу, почему нельзя решить поставленные задачи в рамках джавы, тогда переход идет относительно спокойно. Постепенно изучаются фрейморки, принятые подходы и практики, начинает расти продуктивность.

> сам язык достаточно эстетически неприятный, неминималистичный, передроченый всевозможными концептами

Ну тут уж кому шашечки, а кому — ехать. Можно долго искать эстетичный, минималистичный и глубоко концептуальный ЯП, и закончить брейнфаком :) Скала в этом плане далеко не идеальный язык, конечно. Но я смотрю на другие языки и понимаю, что Одерский и ко умудрились замесить именно такие фичи и в таких пропорциях, что это стало огромным шагом вперед по сравнению с остальными.
Согласен. И все-таки, я склоняюсь, что Scala еще достаточно молодой язык. Нужно, чтобы прошло время, технология устаканилась, язык был принят на вооружение сообществом и компаниями и завоевал свои ниши. Все-таки стек Typesafe еще слишком специфический и ограниченный по сравнению с тем же Spring. А все остальное в экосистеме пока жутко зеленое и нестабильное.
>зачем конкретно они взяли скалу, почему нельзя решить поставленные задачи в рамках джавы

Вот этот аргумент рушит любую смену языка в рамках JVM.
Ибо нет задачи, которую можно решить в Scala/Clojure/Groovy и т.д. и нельзя решить в Java.
Т.е. если так ставить вопрос, то смысла в других языках просто нет и их незачем делать.
Основной смысл любого языка — выражать мысли. Хороший язык позволяет писать в терминах максимально близких к решаемой задаче. Java в этом плане нехороший язык. Например для описания простого property в Java Bean нужно имя написать 6-8 раз. Кроме того основная проблема Java — он семантически не расширяем. На основе него нельзя создать свой метаязык (domain-specific language), описывающий термины предметной области (с этим плохо пытаются справиться frameworks+annotations). Поэтому существуют такие JVM-языки как Groovy, Kotlin, Xtend, Gosu, Ceylon, которые призваны исправить некоторые недостатки Java, оставаясь в рамках совместимости и интероберабельности. Ибо компилироваться в JVM и игнорировать экосистему Java просто глупо — язык станет ненужным.

Теперь о Scala. Она изначально вообще задумывалась быть независимой от рантайма. Первые версии компилировались в JVM и .NET. Но по какой-то причине с .NET не сложилось — теперь это полудохлый независимый проект. Так что по меньшей мере некорректно говорить о Scala как продолжение Java, о чем собственно и заявляют создатели.

Какова же цель создания Scala? Со слов Одерски, он мечтал сделать единый универсальный гибкий и расширяемый язык (lingua franca) для всего, на котором можно было бы описывать предметные области и создавать собственные языки (DSL). За основу концепта была взята Java с примесью ФП и кучей сахара. Для семантического расширения языка предусмотрена мощная система типов, которая, в прочем, плохо ложится на ООП-core, в отличие от того же Haskell-а, в котором ООП не зашит в язык, а выводится искусственно. Ради расширяемой семантики язык загромоздили тоннами синтаксического сахара, implicit-ов и соглашений. Но вскоре поняли, что и этого недостаточно. Взляд создателей пал на Nemerle, который культурно предоставлял метапрограммирование через AST и макросы. Кому-то очень понравилась идея, а также душила жаба, что подобной фигни еще нет в scala. Поэтому вот вам: scala.meta, scala.macros.

Теперь о вашем вопросе: смысл Scala? Для истинных ценителей ФП есть красивейший Haskell. Как показывает практика, на скалу переходят именно искатели лучшей джавы, вопреки тому, что она для этого изначально не задумывалась. А для чего задумывалась? Сразу для всего в общем, и ни для чего в конкретике.
>Теперь о вашем вопросе: смысл Scala? Для истинных ценителей ФП есть красивейший Haskell.

Не было у меня такого вопроса никогда. Какие нафиг истинные ценители? Мы тут вполне себе приземленные продукты делаем, а не философию программирования пишем. У вас в голове какой-то свой мир крутится и вы отвечаете на свои собственные заморочки.

>Как показывает практика, на скалу переходят именно искатели лучшей джавы, вопреки тому, что она для этого изначально не задумывалась.

Что это за ерунда? Какие нафиг искатели лучшей Java?

>А для чего задумывалась? Сразу для всего в общем, и ни для чего в конкретике.

Завязывайте с веществами)

P.S. Судя по всему, вы тот самый менеджер, который ничего не делает, а только любит пофилософствовать на тему ИТ, начитавшись интернетов. При чем без реального опыта применения этого самого ИТ.
Очень глубокомысленный пост. Мне понравился.

Согласен с критикой джавы. Не согласен, что в скале есть какие-то серьезные проблемы интероперабельности. Да, свои коллекции, свои парадигмы. Но можно писать джава-стайл с джава-коллекциями, аннотациями, спрингом и хибернейтом (хотя последнее, честно говоря, не пробовал).

Про историю создания со многим можно согласиться.ю но некоторые моменты хотелось бы прокомментировать:

> мощная система типов, которая, в прочем, плохо ложится на ООП-core, в отличие от того же Haskell-а

Ну не знаю, как там по сравнению с хаскелем, а по сравнению с джавой, скала далеко впереди и по ООП- и по ФП-компоненте.

> язык загромоздили тоннами синтаксического сахара

По-моему, количество реального синтаксического сахара сильно преувеличивается. Так при желании всю скалу можно назвать сахаром поверх джавы.

>… метапрограммирование через AST и макросы. Кому-то очень понравилась идея, а также душила жаба, что подобной фигни еще нет в scala.

Была фигня, называлась плагины к компилятору. Просто сделали еще более высокоуровневое и безопасное API к компилятору. Это вполне вписывается в концепцию расширяемого языка.

> Для истинных ценителей ФП есть красивейший Haskell.

Ну да, красивейший хаскель не взлетел. Как и прекрасный F#, за которым популярная платформа производства крупнейшей корпорации. Видимо, истиных ценителей чистого ФП не так много. Но и в чисто императивном стиле писать надоело. На первый план выходят гибридные языки, скала как раз яркий представитель этой группы. Выходит, так оно и задумывалось.
А кто, собственно, заставляет пользоваться всеми этими макросами и компиляторонаворотами? И чего плохого, когда есть возможность использовать и функциональную и ООП парадигму одновременно? Сахара я в Скале не так уж много припоминаю, for comprehension, apply(), unapply в pattern matching… Implicits… ну если мы мешаем значения и параметризированые типы, то оборачивание всего в тип займет немало кода. Плюс ретроактивное расширение функциональности.
Основная проблема Скалы это отсутствие четких гайдлайнс как писать. Поэтому новички могут и схватить радостно какие нибудь макросы и AST. Но тут уже нам нужны мозги и мозги сообщества, чтобы отличить добро от зла.
> нет задачи, которую можно решить в Scala/Clojure/Groovy и т.д. и нельзя решить в Java.

Хорошо. Тогда переформулирую так:

Только если все (и менеджмент — в первую очередь) четко понимают, зачем конкретно они взяли скалу, благодаря каким фреймворкам/фичам языка можно решить поставленные задачи эффективнее, чем рамках джавы, тогда переход идет относительно спокойно.
Да нормальный скала язык, менеджеры свою ошибку прикрывают проблемами языка, вот и все.
Я могу тут на пол статьи расписать проблемы Spring которые ежедневно мешают мне работать. Постоянно приходится либо что то дописывать либо брать стороннюю либу которая поможет работать.

Scala давно принят на вооружение многими компаниями, вон Twitter, Тинькоф все довольны. Конкретно в этом случае именно проблема управления. Кто принимал решения взять Scala, кто являлся техническим лидером в этом вопросе? Если джуниор Петя без грамма знаний и власти, то сори другого исхода быть не могло.

Я в своей компании не использую Scala хотя и пишу дома только на ней. Не делаю этого потому что понимаю что после меня никто там ничего не исправит и не доделает, а значит пишем на Java и не испытываем проблем.
UFO just landed and posted this here
> если вы изучите Scala и посмотрите на функциональность Java с той колокольни, то открывшийся вид вполне может вызвать у вас улыбку. Просто попробуйте!

О, излюбленный аргумент лисперов. http://www.paulgraham.com/avg.html «The Blub Paradox».

Ну, раз уж вы этим аргументом воспользовались, то и я предложу по той же причине посмотреть Common Lisp.: ) Без сарказма. Мне потраченное на него время не жалко.
Sign up to leave a comment.

Articles