Как перейти от Java к Scala в вашем проекте

Всем привет.
Периодически от Java-разработчиков, которые узнали о существовании Scala, звучат вопросы «Как начать использовать Scala в существующем Java-проекте? Сложно ли перейти от одного к другому? Много ли времени это займет? Как убедить начальство?» В нашем проекте именно такой переход и происходил, на сегодняшний день практически весь проект уже на Scala, поэтому решил поделиться рецептами и впечатлениями.

С чего все началось, оно же «А зачем оно мне вообще надо?»:
  1. хотелось изучить что-то новое и полезное в производстве;
  2. надоело писать много букв на Java, но и радикально переписывать все, скажем на Python, совсем не хотелось;

С учетом таких желаний выбор пал на обзор альтернативных JVM-based языков.
После обзора остановились на Scala. Понравились компактный синтаксис, strong typing, возможность писать в ОО-стиле и заявленное хорошее взаимодейтствие с Java-кодом в обе стороны. Тот факт, что Scala уже активно используют такие крупные компании, как Twitter, LinkedIn, Foursquare и так далее, внушил определенную уверенность в будущем языка.
У нас уже имелся проект на Maven с юнит-тестами на JUnit, поэтому важно было легко включить Scala без существенных затрат на адаптацию инфраструктуры.
Итак, по порядку.

Много ли времени это займет?


Общее впечатление для тех, кто сомневается, стоит ли начинать сей процесс — переходить на Scala и изучать ее постепенно абсолютно реально. До первого практического применения времени пройдет мало, я бы сказал день или два, ведь поначалу это может быть даже просто «Java с val и без точек с запятой». Пройдет время, и постепенно вы вдруг обнаружите у строк кучу непонятно откуда взявшихся бонусных методов (hello implicit), начнете использовать функции, замыкания, case-классы, паттерн-матчинг, коллекции ну и так далее… Вот честно, прям постепенно, без отрыва от будничной работы.

Как начать использовать Scala в существующем Java-проекте?


Для начала добавляем поддержку Scala в родительском pom.xml:
<project>
  ...
  <properties>
    <version-scala>2.10.3</version-scala>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.scala-lang</groupId>
      <artifactId>scala-library</artifactId>
      <version>${version-scala}</version>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>net.alchim31.maven</groupId>
          <artifactId>scala-maven-plugin</artifactId>
          <version>3.1.6</version>

          <configuration>
            <scalaVersion>${version-scala}</scalaVersion>
            <args>
              <arg>-deprecation</arg>
              <arg>-explaintypes</arg>
              <arg>-feature</arg>
              <arg>-optimise</arg>
              <arg>-unchecked</arg>
            </args>
          </configuration>

          <executions>
            <execution>
              <id>scala-compile</id>
              <phase>process-resources</phase>
              <goals>
                <goal>add-source</goal>
                <goal>compile</goal>
              </goals>
            </execution>
            <execution>
              <id>scala-compile-tests</id>
              <phase>process-test-resources</phase>
              <goals>
                <goal>testCompile</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>

    <plugins>
      <plugin>
        <groupId>net.alchim31.maven</groupId>
        <artifactId>scala-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

Далее… а хотя нет, собственно это всё.
Теперь mvn compile будет собирать все .scala-исходники, расположенные в src/main/scala (впрочем расположенные в src/main/java тоже соберутся). Также можно писать JUnit-тесты на Scala и выполнять mvn test. Важное замечание к этому плагину: mvn test будет собирать и выполнять только те .scala-тесты, которые лежат именно в src/test/scala, в противном случае они вообще будут проигнорированы. Поэтому сразу кладите ваши .scala в src/(main|test)/scala/. Что касается Gradle, то, насколько мне известно, проблем с поддержкой Scala там тоже нет.

Вообще говоря в последнее время стандартом де-факто для Scala-проектов становится SBT (Simple Build Tool, по сути как Gradle, только на Scala). Переход на SBT на мой взгляд будет иметь смысл, когда вам понадобятся например ScalaTest, ScalaCheck, Specs и так далее, так как SBT нативно интегрируется с ними, однако никто вам их не навязывает. Мы на SBT так и не перешли, его преимущества пока не перевесили необходимость перетрясти структуру проектов и их конфигурацию.

Что касается IDE, мы работаем в IntelliJ IDEA, и в ней достаточно включить поддержку Scala в настройках (File → Settings → Plugins → чекаем Scala). После перезагрузки для всех модулей добавится настроенный из pom Scala-фасет, и можно будет билдить и самой IDEA без Maven'а. Плюс, если вы хотите переписать какой-то класс с Java на Scala, то у IDEA есть возможность конвертации, пункт «Convert to Scala» в меню для .java-файлов, или просто открыв .java и нажав Ctrl-Shift-G (.java-исходник останется на месте, что полезно как референс для сравнения и допиливания сконвертированного кода, потом его нужно удалить). Что касается Eclipse, то есть соответствующий плагин.

Сложно ли перейти от одного к другому?


Для нас ответом стало «нет», но куда ж совсем без сложностей:
  • в виду отсутствия for(;;) и break приходилось основательно перерабатывать некоторые сложные циклы. Впрочем это лишь пошло на пользу, так как код в стал чище и понятней. break можно временно компенсировать использованием scala.util.control.Breaks;
  • иногда все же сложно было использовать Scala из Java в виду более богатой type-system в Scala, или отсутствия в Java аналогов Scala traits с имплементацией, или отсутствия checked exceptions (в Scala-коде компилятор будет молчать как партизан, а скажем чтобы заставить Java код увидеть checked, в Scala есть аннотация @throws[SomeException], которая указывают компилятору сгенерить байт-код с throws);
  • не совсем сложность, отсутствует try with resources (для тех, у кого Java 7), который впрочем легко заменяется loan pattern'ом, то есть функцией вида…

// допустим весь ваш код находится в пакетах ru.blablabla…, тогда можно получить «халявный импорт» функции во всем пакете ru
package object ru {
  // по сути это прямая интерпретация http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20.3.1
  // можно вместо [A <: AutoCloseable] написать [A <: { def close() }], тогда это охватит всех у кого есть метод close, но будет использоваться рефлексия
  def using[A <: AutoCloseable, R](resource: A)(block: A => R): R = {
    var primary: Throwable = null
    try {
      block(resource)
    } catch {
      case ex: Throwable =>
        primary = ex // to allow suppresing
        throw ex
    } finally if (resource ne null) {
      if (primary eq null) {
        resource.close()
      } else try {
        resource.close()
      } catch {
        case ex: Throwable => primary.addSuppressed(ex)
      }
    }
  }
}

после чего можно использовать его в коде
package ru.habrahabr.hello
...
  val maybeSomeResult = using (Files.newBufferedReader(…)) { reader =>
    // use reader and maybe return some result
  }
...

Как убедить начальство?


Воспевать Scala я не собираюсь, просто опишу реальные дивиденты, которые мы получили:
  • стало значительно меньше букв. Конкретно в нашем проекте, даже простое конвертирование исходников с небольшими быстрыми доработками давало уменьшение количества строк в среднем на 25%, а в общем пропало порядка 9 тысяч строк из 37 тысяч. Это именно строки, самих букв стало еще меньше. Очевидно, что меньше букв значит быстрее решаем задачи и легче находим ошибки. Возможность писать классы в одну строку вообще сносит крышу поначалу;
  • богатейшая библиотека коллекций с кучей методов избавила от огромного количества рутинной работы с циклами. Все эти map filter find forall exists min par и т.д. и т.п. просто убивают намеки на возвращение к Java (один только par чего стоит). Все это богатство дополняют immutable-коллекции, которых так не хватает в JDK (в котором у Iterable нету size, у Collection уже есть add, Collections.unmodifiable… лишь добавляют защиту от дурака но не защищают от неверного использования). На мой взгляд, даже только ради этой библиотеки стоит изучить Scala (впрочем у JDK есть богатый выбор производительных concurrent-коллекций);
  • возросла экспрессивность кода, особенно часто употребляем Option[T] который в самом простом случае решает проблему проверок на null (читай, багов с этим связанных);
  • higher order functions и прочая функциональная составляющая Scala опять же позволяет писать более короткий, экспрессивный и переиспользуемый код (в Java 8 небольшим утешением конечно будут лямбды, но их еще дождаться надо);
  • implicit conversions в умеренных количествах позволили избежать замусоривания кода всякими оберточными классами;
  • == в Scala это как Objects.equals(o1, o2) в Java, прощай случайное сравнивание ссылок (впрочем если нужно именно это, есть eq и neq);
  • хорошее взаимодействие с Java лежит в основах дизайна Scala, поэтому интеграция всяких Java-фреймворков (Spring, Hibernate и тд) проходит довольно безболезненно. Например есть куча аннотаций типа @BeanProperty, которая говорит компилятору сгенерить для поля геттеры и сеттеры в стиле JavaBeans.

Учиться Scala с большой вероятностью будет вся команда одновременно, поэтому если вдруг один из разработчиков решит покинуть команду, в команде все равно останется достаточный опыт, чтобы быстро научить новых разработчиков.

Итого, если вкратце описать результат, то «меньше букв — меньше багов — больше продуктивности».
С момента перехода на Scala новый код на Java писать более не приходилось, это была точка невозврата.
Хочется еще раз повториться, вовсе необязательно выделять на обучение сразу много времени (как вариант для начальства, «необязательно выделять много денег»).

PS: есть мнение, что Scala сложна и не подходит большинству Java-разработчиков (см перевод на Хабре тут habrahabr.ru/post/134897), но на мой взгляд входной порог у Scala небольшой, язык не заставляет с головой кидаться в омут и основательно изучать его перед практическим применением, а вот пользу может принести достаточно быстро.

Полезные ресурсы:
Acronis
Company

Comments 56

    +7
    Все правильно пишете.
    Но у Scala есть одна проблема. Люди почему-то думают, что Scala невероятно сложна, что если например Scala может функциональность, то надо обязательно ее везде юзать эту функциональность. Или если на Scala можно писать крутые однострочники, то надо обязательно весь код таким делать.
    В общем, людей бросает в крайности.
    Когда я говорю знакомым, что на Scala можно начинать с малого и вовсе необязательно сразу погружаться во все возможности языка, а для начала писать «Scala like Java», постепенно изучая и подключая более сложные конструкции языка. На меня смотрят большими глазами и начинают рассказывать про какую-то «идеоматическую скалу» и что если не использовать все и сразу, то скала (почему-то) перестает быть скалой и поэтому нет смысла на ней писать.
    Хотя на Scala вполне отлично выходит писать обычный, простой ООП код, только с плюшками Scala. А замороченную функциональность юзать там, где от нее есть профит.
      +1
      Это верно, но тут всё не так просто. В случае создания нового кода ты сам, разумеется, выбираешь, какие возможности использовать, а какие нет. Но если начинаешь работать с кодом других людей, которые себя искусственно не ограничивают в возможностях языка, то волей-неволей приходится вникать в них все сразу. И чем больше их в языке, тем сложнее программисту.

      В частности поэтому я ещё, например, немного скептически отношусь и к утверждению, что нововведения в C++ облегчают работу с кодом. Да, написание нового кода-то упрощается, но старый код никуда не делся, и возможности, которые уже не нужно использовать в новом коде, всё равно нужно знать и понимать. Поэтому необходимый объём знаний только увеличивается.
      +2
      Слышал, что при переходе на Scala сильно растёт время сборки проекта, в том числе и инкрементальной. Что скажете?
        +1
        Понятие «сильно», оно относительно.
        Ну собирается у меня проект например не 30, а 50 сек. Разница, есть и формально получается дольше сборка.
        Но реально проигрывая в сборке, мы выигрываем во всех остальных моментах. Меньше кода, он надежнее и т.д.
        Сложно вот так с ходу объяснить, но на Scala у меня требуется просто меньше сборок на проект в процессе работы. Получается писать большие куски кода по сравнению с Java, которые просто работают.
          +1
          мы сильной разницы не заметили. классы обычно не очень большие, поэтому инкрементальная сборка со своей задачей справляется хорошо. у упомянутого Maven-плагина для этих целей есть goal scala:cc, у IDEA compile-server, у SBT режим continuous compilation.
          0
          В грядущей версии 2.11 один из акцентов поставлен на ускорение сборки.
            +1
            Если использовать SBT, то там есть режим демона ~compile. Все будет компилироваться по мере сохранения новых изменений вами. Еще это полезно, можно вывести отдельное окно терминала и смотреть на ошибки компиляции. Т.к. напирмер, плагин IDEA не все фейлы подсвечивает.
            0
            как нибудь решалась проблема 10-метрового джарника?
              0
              в нашем случае это не было проблемой, поэтому нет
                0
                А что за проблема «10-метрового джарника», можно чуть подробней?
                  0
                  да не то чтобы это всегда проблема.
                  было на проекте — размер war-а увеличился с 4 метров до 14. просто потому что сборщик добавил jar с всеми скаловскими вкусняшками.
                    0
                    Ну дык это вопрос не к scala, а к подходу сборки.
                  0
                  Можно посоветывать proguard вестимо. Для андроида только с ним и можно на scala писать.
                    0
                    Я недавно решал эту проблему и даже написал заметку об этом. Если вкратце, то билд скрипт вытаскивает из JAR'а со скала рантаймом нужные нам вещи (и только их) и упаковывает прямо в JAR итогого приложения. Правда не всё так просто.
                    0
                    А какие IDE поддерживают Scala? Хочется же автодополнения, удобной отладки и т.п.
                      +3
                      IDEA
                        +1
                        Как я уже упомянул, есть плагины для IntelliJ IDEA и Eclipse, оба активно развиваются. О других не слышал. Дополнение и отладка в обеих поддерживаются на хорошем уровне. Какую IDE из них выбрать — дело вкуса мне кажется.
                          0
                          Клипсу не тыркал, но плагин в идее иногда бесит. Форматирование кода страдает, автозавершения конструций (например при объявлении функции) нету. Вдобавок не нашел, как в созданном проекте изменить компиллятор скалы.
                            +1
                            Полагаю, речь не о Maven-based проекте? Если так, то в IDEA меню File — Project Structure — Libraries, там добавить нужный вам org.scala-lang:scala-lang-compiler. Далее идем в список фасетов и в каждом Scala-фасете меняем Compiler library на только что добавленную. С Maven / SBT / Gradle вопрос снимается автоматом, возьмется указанный в соответствующем конфиге. В IDEA 12 и ранее, когда был FSC, можно вроде было только ему засетить эту либу и в фасетах выбрать use project FSC (вроде так было, не помню, у нас уже IDEA 13).
                              0
                              Спасибо! Но пожалуй действительно надо уползать на сбт.
                            0
                            Есть плагин и под NetBeans
                            +1
                            Для любителей есть ensime. Дополнения, отладка, интеграция с SBT, всё в наличии.
                            +1
                            Как с производительностью? Я года 2 назад смотрел Scala последний раз, сложилось впечатление, что в целом немного медленней все работает.
                              +2
                              Смотря что сравнивать. И самое главное, смотря чего ожидать.
                              Если одно и тоже писать на Java и Scala, то разница в пределах погрешностей. Что в общем-то логично.
                              Если сравнивать например коллекции, то коллекции Scala немного медленнее, что в общем-то тоже логично, ибо они функциональны.
                              Но опять же, разница не в 1000 раз. Если вам на проекте не надо 50М котировок в сек обсчитывать, то вы не заметите разницу.
                              Но точно заметите расширенные возможности работы с коллекциями. Которые востребованы практически в каждом проекте, ибо избавляют от большого количества рутины на Java и делают код проще и понятнее.
                                +1
                                В некоторых случаях может и быстрее. Например scala умеет оптимизировать хвостовую рекурсию.

                                Вот, например, реализация свертки ленивой (потенциально бесконечной) коллекции (Stream — ленивый LinkedList, элементы вычисляются один раз, но только по мере надобности):

                                  override final def foldLeft[B](z: B)(op: (B, A) => B): B = {
                                    if (this.isEmpty) z
                                    else tail.foldLeft(op(z, head))(op)
                                  }
                                

                                github

                                Мало того, что это не вызовет stackoverflow, так еще и обработанные элементы позволит обработать GC.

                                Недавно разбирался как эта оптимизация работает.

                                И работа с многопоточностью в scala просто великолепна. Что даст прирост в производительности.
                                Особенно ярко это проявляется на неблокирующих драйверах БД.
                                +1
                                Вообще говоря, смотря как писать. Если написать один и тот же код на Java и Scala, то разницы не будет, байт-код генерится один и тот же практически. Если же какой-нибудь алгоритм реализовать совершенно разными путями, можно и получить совершенно разные результаты (например см DZone). Scala может генерировать кучу объектов, например анонимных функций или промежуточных коллекций. Скажем в выражении вида someCollection.filter(x => …).map(x =>…) будет 2 анонимных класса для каждого (x => …) плюс временная коллекция между filter и map (более развернутый ответ например на StackOverflow)
                                  0
                                    0
                                    Такого много пишут. Пробуют, не понравилось, пост ненависти. Причем конкретные претензии видел только один раз, но все равно свелось к вкусовщине. Уже поднадоело.
                                    +1
                                    А есть ли смысл переходить на Scala с тем учетом, что нового появится в Java 8? Расширенные коллекции, функциональщина, default имплементация методов в интерфейсах (недо-трейты) и куча других плюшек и это уже в апреле 2014 года.

                                    P.S. Больше/меньше буковок при написании не считаю преимуществом. А вот если меньше буковок за счет синтаксического сахара… то это сомнительный плюс для Java разработчика. Почему бы тогда не перейти на C#? Там тоже очень много всего реализовано.
                                      +1
                                      Не соглашусь с вами. Хотя в шарпе гораздо больше плюшек он все равно останется в плане синтаксиса джавой на стероидах. Скала приносит гораздо больше чем просто упрощение кода, по мерее ее открытия она меняет некоторые подходы в лучшую сторону. Чего стоит одно только сопоставление с образцом или неизменяемость данных. Постепенно от адепта императивного подхода вы станете адептом декларативного подхода. Никакой шарп вам этого не подарит.

                                      Если немного отдалится от темы, посмотрите какие новые фичи шарпа появились с 5 и будут включены в 6 версию языка. Создается что впечатление что далее шарпу расти некуда.
                                        +2
                                        Уже разбирали по винтиками этот вопрос.
                                        Дело в том, что в java все эти недо-трейты и прочие плюшки, с большой буквы «недо».
                                        Все эти «Расширенные коллекции, функциональщина...», утрирую конечно, но это примерно как поставить рядом BMW х6 (Scala) и
                                        ВАЗ 2106 (Java) и на полном серьезе спрашивать, а есть ли смысл переходить с ВАЗ на BMW?
                                        И при этом перечислять, ну вот смотрите, у обоих есть руль, есть колеса, есть двигатель, есть куда бензин залить,
                                        в салоне 5 человек сидеть может… и т.д. Понимаете к чему я веду? Само наличие двигателя в машине не говорит о том, что он реально удобный, функциональный, что им удобно пользоваться и т.д.
                                        Просто детально сравните например, что могут коллекции в Scala и что предлагают в Java 8. И все встанет на свои места.
                                        Если вы не видите разницы, то вам безусловно нет смысла переходить.
                                        Я уже не говорю о том, что Scala это не просто расширенные коллекции или лямбды.
                                          –2
                                          Где то на хабре была статься про Framework Based программистов — попахивает сабжем. По теме — полностью устраивает Java даже в том виде, в котором ее предлагают в 8 ветке.
                                            0
                                            Тут спорить не имеет резона с вами, пока сами не копнете на некоторую глубину.
                                              0
                                              А никто не спорит: на вкус и цвет — фломастеры разные.
                                                0
                                                Тут дело совсем не во фломастерах.
                                                Ваша аналогия про Framework Based программистов вообще тут неуместна.
                                                И то, что вас устраивает Java тоже не в тему. А то щас прибегут все и будет:
                                                — Меня PHP полностью устраивает — Scala ненужна!
                                                — Да вы что? Erlang всем устраивает ни PHP ни Scala ни Java не нужы!
                                                и т.д. и т.п.
                                                Не об этом тема.
                                          0
                                          Мы начали этот процесс перехода 2 с лишним года назад, так что эти плюшки мы получили когда еще Java 7 не появилась. Насчет перехода на другой язык я в самом начале поста упомянул — переписывать всю codebase на не-JVM язык мы не собирались, это были бы нереальные временные затраты.
                                            0
                                            2 года назад Scala вроде была еще не настолько стабильной? Или нет? Я не напрямую имел дело с sbt и scala на Play фреймворке. Скорость компиляции ощутил на своей шкуре или что-то разработчики фреймворка перемудрили (малейшее изменение в шаблоне htlm на scala занимает чуть ли не 8-10 сек), ощущение что он перекомпилирует кучу зависимостей.

                                            Еще одна проблема или неудобство, каждый раз когда я смотрю чей-то код на Scala — мне каждый раз кажется что это новый язык, слишком сильно варьируется стиль написания кода на Scala.

                                            P.S. И почему это у Iterable должен быть size? Очень часто реализация подобного метода невозможна, например для курсора из БД или что-то в этом духе.
                                              0
                                              Согласен, не была, но бонусы можно было получать уже тогда. Хотя бы как «Java с val и без точек с запятой».
                                              Про Play не могу сказать, я сейчас с ним только знакомлюсь.
                                              Про разность стиля это да, доходит до крайностей, чему в том числе способствует возможность писать методы почти с произвольным названием из кучи символов. Но мы так не делаем, читабельность is the must.

                                              PS: Я имел ввиду что очень не хватало неизменяемой коллекции, у которой есть size.
                                            +1
                                            Есть ещё очень много возможностей языка, которые в Java не скоро появятся. Новые строковые литералы, pattern match, параметры по умолчанию и именованные параметры, макросы, implicit'ы… Долго перечислять. Да один scala.reflect.ClassTag чего стоит!
                                              0
                                              Просто Scala как молодой язык (по сравнению с Java) развивается быстрее. Если вдруг Scala завладеет массами в таких же масштабах, как Java, думаю она тоже затормозит по добавлению фич всяких.
                                                0
                                                Вопрос будет ли в этом вообще смысл. Сложность скалы в полном объеме уже и так велика. Имхо, лучше будет подумать о создании собственной vm.
                                            0
                                            Кстати использование мавена со scala как то попахивает не очень, само по себе творение мистера ван-зила находится на довольно запущенной стадии гниения. Образно выражаясь прах к праху, мавен к java, а мы будем жить дальше и пользоваться sbt. Это не вопрос эстетики, ведь компиляция смешанных проектов (особенно со scala), будь этому ван-зилу неладно, занимает уйму времени.
                                              +1
                                              Опишу все недостатки Scala, которые вижу (для меня достоинства перевешивают недостатки, но надо делать осознанный выбор).

                                              Сложность. Начинать может и просто, но достаточно быстро код уже будет нелегко понять новичку в Scala. Т.е. если вы вместе начали и до смерти вместе работаете, это хорошо. Если хочется найти нового человека в команду — либо искать специалиста по Scala (не знаю, много ли их на рынке и какие их зарплатные ожидания в сравнение с Java-программистами похожего уровня), либо брать Java-программиста и ждать определённое время, пока он дорастёт до вашего уровня. Опять же приходится читать чужой код достаточно часто (код библиотек, код в интернете) и для этого нужен уже навык. Многие слабые программисты, которые способны писать коммерческий код на Java, Scala осилить просто не смогут никак вообще, поэтому надо учитывать регион и с какими людьми вы работаете.

                                              Библиотека коллекций. Честно говоря она мне не нравится. Она очень сложная. Я её несколько раз пытался осилить, но не осиливал. Как «пользователь» ещё боле-мене можно пользоваться, но расширять её мне сложно. Java-библиотека не в пример проще, её расширять можно без проблем. Я думаю нужно инвестировать определённое время в это.

                                              Скорость сборки. В принципе всё уже сказали, могу только сказать, что c Java работать комфортнее, если есть hot deploy. На Java меняешь строку, делаешь альт-таб, в фоне файл моментельно компилируется, подгружается и через полсекунды-секунду он уже работает на сервере. В случае со Scala это будет в любом случае медленнее.

                                              Интероперабельность хорошая, но проблемы всегда возникают.

                                              Поддержка IDE не на уровне Java, хотя и на достаточном, для продуктивной работы. Но до уровня Java ещё очень далеко, если вообще когда-нибудь будет. Рефакторингов поменьше, бывают расхождения между компилятором и IDE.

                                              SBT мне лично показался плохим продуктом. Хотя пользуюсь. Зачем было делать build.sbt ограниченным из-за синтаксиса Scala, что мешало сделать свой язык с нормальным парсером без этих пустых строк и прочих Scalостей? Даже XML лучше. Какой то мутный вариант сборки со скриптом на Scala в project, зачем он нужен, зачем два варианта? WAR-файл я когда то так и не смог сделать на sbt, шелл-скриптом собирал. Документации много и читать приходится много, гораздо больше, чем в случае с мавеном, хотя это вспомогательный инструмент и не хочется тратить на него время. В общем не нравится мне этот инструмент, у maven-а свои недостатки, но он нравится больше. При этом SBT уже стандарт сборки в Scala и никуда от него не деться.

                                              Библиотек достаточно много, но не для всего есть. Java-библиотеки можно использовать, но хочется Scala (хотя бы обёртки). Небольшой диссонанс может иногда возникать, то ли делом заниматься, то ли код украшать написанием обёрток.
                                                0
                                                Ну прямо вот тик никуда от SBT не деться?
                                                Все свои проекты собираю Gradle. И Java и Scala и смешанные. Умеет все, интеграция со всем что только можно придумать.
                                                При этом простой как палка и нет идиотского XML.
                                                А SBT да, как сказали в одном популярном подкасте: «сделано хищниками для чужих»(с).
                                                  0
                                                  Если устраивает Gradle, то зачем менять? Можно подождать пока SBT заматереет, либо пока деваться будет некуда. У SBT версия-то нынче всего-лишь 0.13.1, значит сами авторы считают ее далекой до завершения.
                                                    0
                                                    Возможно не до конца погрузился в scala мир, из того, что видел — все пользуются SBT, а maven как временная мера, пока, так сказать, не осознал до конца. Буду знать, что не SBT единым и рад, если фатальных проблем при использовании maven со Scala не возникает. Возможно вернусь к нему.

                                                    Gradle, к стыду своему признаюсь, не видел. Изучу этот вопрос, как раз время свободное есть.
                                                    0
                                                    Согласен с недостатками sbt, но не согласен что это стандарт. В реальном продакшене я видел большинство проектов собираемых maven и небольшое количество на Gradle. Свои проекты перевёл на Gradle недавно. На sbt собираются только какие-то Scala библиотеки, вроде Squeryl.

                                                    Моя претензия к sbt в том, что он плохо поддаётся влючению в другие скрипты. Например, вот так не работает:
                                                    $ ./sbt eclipse with-sources=true
                                                    только вот так:
                                                    $ ./sbt
                                                    > eclipse with-sources=true

                                                    Что значительно менее удобно.

                                                    И документация плохая. Ничего подобного maven, и даже более молодому Gradle уступает.

                                                    Я люблю Scala и использую её в каждом JVM проекте, если есть возможность. Язык совершенно независим от SBT. Чтобы писать на Scala не обязательно целиком переходить на стек Typesafe.
                                                      0
                                                      А sbt «eclipse with-sources=true» не помогает?

                                                      У меня противоположные впечатления от sbt — это первая система сборки, которая не вызывает у меня полнейшего недоумения при попытке что-либо настроить.
                                                        0
                                                        Конкретно для eclipse, сработает. Но есть билд таски, для которых и так не помогает. Последний, с которым столкнулся — submit таск из курса по акторам на Coursera.

                                                        Но вообще я рад что кому-то sbt нравится. Пусть будет больше разных билд систем, будет откуда фичи портировать. Я пытался написать всего-лишь о том, что не обязательно использовать sbt для сборки Scala-проектов. Если не нравится, можно испольвать другой инструмент. А если нравится, то никто не против, конечно.

                                                        P.S. Ещё SBT очень заточен на Scala и Java. Собрать Groovy проект уже на порядок сложнее. А связка Java + Scala + Groovy довольно хорошо работает вместе…
                                                        0
                                                        Свои проекты перевёл на Gradle недавно.


                                                        Не показывает ли это что Groovy лучшая альтернатива?
                                                          0
                                                          Лучшая альтернатива чему?
                                                            0
                                                            Gradle сам по себе, в отрыве от языка достаточно хороший продукт. Он берет лучшее из тулзовин предыдущего поколения, с которыми знакомо подавляющее большинство java-разработчиков: декларативную модель проекта из maven и императивные таски из ant.

                                                            SBT же, на мой взгляд, активно использует несколько не очень релевантных современной сборке проектов идей: рекурсивные проекты; плоский список настроек билда, в котором должно быть все; конфигурационный файл с «упрощенным» синтаксисом, использования которого многие стараются избегать.

                                                            Что касается DSL, в Gradle скрипт, конечно, гораздо проще выглядит. В нем может разобраться даже новичок. Но лично я сомневаюсь, что это из-за Groovy. Scala позволяет писать DSL не хуже, причем с полным сохранением типобезопасности (представьте, ошибки в скрипте подчеркиваются непосредственно в IDE). У меня даже была идея написать front-end для SBT с Gradle-like синтаксисом. Первые попытки воспроизвести этот синтаксис показали, что в целом это возможно.
                                                              0
                                                              Scala и Groovy имеют одно маленькое, но принципиальное для написания DSL отличие. Если у вас в DSL есть конструкция типа

                                                              configuation {
                                                                http {
                                                                  host "example.com"
                                                                }
                                                              }
                                                              


                                                              То в Gradle внутри скобок this будет ссылкой на только что созданный объект, а в Scala this останется тем же, что и снаружи скобок. При написании DSL в Scala приходится самому следить за стеком. Это вполне возможно, но неудобно. Я недавно с этим боролся как раз: писал DSL для декларативного описания PDF через itext. Обратите внимание на метод call. Буду рад если кто-нибудь укажет на мою ошибку и более прозрачный способ написания подобных DSL.
                                                                +1
                                                                Вам скорее в Kotlin с такими DSL.

                                                                Этот DSL принципиально мутабельный — каждая функция ни чего не возвращает и при этом их порядок выполнения важен для результата.

                                                                В скале же принято использовать не мутабельные структуры, работать без состояния.

                                                                В первом приближении:
                                                                pdf ~
                                                                file("/tmp/HelloWorld.pdf") ~
                                                                paragraph(s"Hello World ${new Date()}!") ~
                                                                paragraph {
                                                                  phrase {
                                                                    chunk("This is initial text. ") ~
                                                                    chunk {
                                                                      text("testing text element ") ~
                                                                      font(style = BOLD, color = rgb"0x929083") ~
                                                                      background(rgb"ffe400")
                                                                    } ~
                                                                    {
                                                                      for (i <- 1 to 10)
                                                                        yield chunk(s"Chunk number $i ")
                                                                    }
                                                                  } ~
                                                                  phrase("Second Phrase. ") ~
                                                                  chunk("Chunk in the middle ") ~
                                                                  phrase("Third Phrase. ")
                                                                } ~
                                                                close
                                                                


                                                                Не изменяя глобальное состояние, а объединяя конструкции.

                                                                Это один из способов.

                                                                У меня были мысли написать для TeX синтаксис в таком же виде, как я писал для XPath, но я сильно погрустнел, узнав, что для него не существует описания в виде контекстно-независимой грамматики.
                                                                  0
                                                                  Большое спасибо за идею с Kotlin. Давно ждал повода разобраться с ним. Да, я знаю что такой DSL не совсем в стиле Scala, тем интереснее было попытаться его реализовать.

                                                                  Спасибо за ссылку на вашу статью, отличное описание. Жаль, что я её пропустил.
                                                                    0
                                                                    Учтите, что для макросов прошедший с момента написания статьи год — вечность.
                                                                    Сейчас то же можно реализовать лаконичнее и читабельнее.

                                                                    Ну а про котлин — попробуйте все-таки переписать в immutable стиле — мутабельность со временем запутывает все больше и больше.

                                                      Only users with full accounts can post comments. Log in, please.