Pull to refresh

Comments 56

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

В частности поэтому я ещё, например, немного скептически отношусь и к утверждению, что нововведения в C++ облегчают работу с кодом. Да, написание нового кода-то упрощается, но старый код никуда не делся, и возможности, которые уже не нужно использовать в новом коде, всё равно нужно знать и понимать. Поэтому необходимый объём знаний только увеличивается.
Слышал, что при переходе на Scala сильно растёт время сборки проекта, в том числе и инкрементальной. Что скажете?
Понятие «сильно», оно относительно.
Ну собирается у меня проект например не 30, а 50 сек. Разница, есть и формально получается дольше сборка.
Но реально проигрывая в сборке, мы выигрываем во всех остальных моментах. Меньше кода, он надежнее и т.д.
Сложно вот так с ходу объяснить, но на Scala у меня требуется просто меньше сборок на проект в процессе работы. Получается писать большие куски кода по сравнению с Java, которые просто работают.
мы сильной разницы не заметили. классы обычно не очень большие, поэтому инкрементальная сборка со своей задачей справляется хорошо. у упомянутого Maven-плагина для этих целей есть goal scala:cc, у IDEA compile-server, у SBT режим continuous compilation.
В грядущей версии 2.11 один из акцентов поставлен на ускорение сборки.
Если использовать SBT, то там есть режим демона ~compile. Все будет компилироваться по мере сохранения новых изменений вами. Еще это полезно, можно вывести отдельное окно терминала и смотреть на ошибки компиляции. Т.к. напирмер, плагин IDEA не все фейлы подсвечивает.
как нибудь решалась проблема 10-метрового джарника?
в нашем случае это не было проблемой, поэтому нет
А что за проблема «10-метрового джарника», можно чуть подробней?
да не то чтобы это всегда проблема.
было на проекте — размер war-а увеличился с 4 метров до 14. просто потому что сборщик добавил jar с всеми скаловскими вкусняшками.
Ну дык это вопрос не к scala, а к подходу сборки.
Можно посоветывать proguard вестимо. Для андроида только с ним и можно на scala писать.
Я недавно решал эту проблему и даже написал заметку об этом. Если вкратце, то билд скрипт вытаскивает из JAR'а со скала рантаймом нужные нам вещи (и только их) и упаковывает прямо в JAR итогого приложения. Правда не всё так просто.
А какие IDE поддерживают Scala? Хочется же автодополнения, удобной отладки и т.п.
Как я уже упомянул, есть плагины для IntelliJ IDEA и Eclipse, оба активно развиваются. О других не слышал. Дополнение и отладка в обеих поддерживаются на хорошем уровне. Какую IDE из них выбрать — дело вкуса мне кажется.
Клипсу не тыркал, но плагин в идее иногда бесит. Форматирование кода страдает, автозавершения конструций (например при объявлении функции) нету. Вдобавок не нашел, как в созданном проекте изменить компиллятор скалы.
Полагаю, речь не о 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).
Спасибо! Но пожалуй действительно надо уползать на сбт.
Есть плагин и под NetBeans
Для любителей есть ensime. Дополнения, отладка, интеграция с SBT, всё в наличии.
Как с производительностью? Я года 2 назад смотрел Scala последний раз, сложилось впечатление, что в целом немного медленней все работает.
Смотря что сравнивать. И самое главное, смотря чего ожидать.
Если одно и тоже писать на Java и Scala, то разница в пределах погрешностей. Что в общем-то логично.
Если сравнивать например коллекции, то коллекции Scala немного медленнее, что в общем-то тоже логично, ибо они функциональны.
Но опять же, разница не в 1000 раз. Если вам на проекте не надо 50М котировок в сек обсчитывать, то вы не заметите разницу.
Но точно заметите расширенные возможности работы с коллекциями. Которые востребованы практически в каждом проекте, ибо избавляют от большого количества рутины на Java и делают код проще и понятнее.
В некоторых случаях может и быстрее. Например 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 просто великолепна. Что даст прирост в производительности.
Особенно ярко это проявляется на неблокирующих драйверах БД.
Вообще говоря, смотря как писать. Если написать один и тот же код на Java и Scala, то разницы не будет, байт-код генерится один и тот же практически. Если же какой-нибудь алгоритм реализовать совершенно разными путями, можно и получить совершенно разные результаты (например см DZone). Scala может генерировать кучу объектов, например анонимных функций или промежуточных коллекций. Скажем в выражении вида someCollection.filter(x => …).map(x =>…) будет 2 анонимных класса для каждого (x => …) плюс временная коллекция между filter и map (более развернутый ответ например на StackOverflow)
Такого много пишут. Пробуют, не понравилось, пост ненависти. Причем конкретные претензии видел только один раз, но все равно свелось к вкусовщине. Уже поднадоело.
А есть ли смысл переходить на Scala с тем учетом, что нового появится в Java 8? Расширенные коллекции, функциональщина, default имплементация методов в интерфейсах (недо-трейты) и куча других плюшек и это уже в апреле 2014 года.

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

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

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

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

PS: Я имел ввиду что очень не хватало неизменяемой коллекции, у которой есть size.
Есть ещё очень много возможностей языка, которые в Java не скоро появятся. Новые строковые литералы, pattern match, параметры по умолчанию и именованные параметры, макросы, implicit'ы… Долго перечислять. Да один scala.reflect.ClassTag чего стоит!
Просто Scala как молодой язык (по сравнению с Java) развивается быстрее. Если вдруг Scala завладеет массами в таких же масштабах, как Java, думаю она тоже затормозит по добавлению фич всяких.
Вопрос будет ли в этом вообще смысл. Сложность скалы в полном объеме уже и так велика. Имхо, лучше будет подумать о создании собственной vm.
Кстати использование мавена со scala как то попахивает не очень, само по себе творение мистера ван-зила находится на довольно запущенной стадии гниения. Образно выражаясь прах к праху, мавен к java, а мы будем жить дальше и пользоваться sbt. Это не вопрос эстетики, ведь компиляция смешанных проектов (особенно со scala), будь этому ван-зилу неладно, занимает уйму времени.
UFO landed and left these words here
Ну прямо вот тик никуда от SBT не деться?
Все свои проекты собираю Gradle. И Java и Scala и смешанные. Умеет все, интеграция со всем что только можно придумать.
При этом простой как палка и нет идиотского XML.
А SBT да, как сказали в одном популярном подкасте: «сделано хищниками для чужих»(с).
Если устраивает Gradle, то зачем менять? Можно подождать пока SBT заматереет, либо пока деваться будет некуда. У SBT версия-то нынче всего-лишь 0.13.1, значит сами авторы считают ее далекой до завершения.
UFO landed and left these words here
Согласен с недостатками 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.
А sbt «eclipse with-sources=true» не помогает?

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

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

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


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

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

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

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


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

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

Ну а про котлин — попробуйте все-таки переписать в immutable стиле — мутабельность со временем запутывает все больше и больше.
Only those users with full accounts are able to leave comments. Log in, please.