Язык программирования Scala является «симбиозом» Java и C#. Это не первый язык, комбинирующий ООП с функциональным подходом, но он начал набирать обороты в тот момент, когда развитие Java замедлилось. Более того, создатели Scala решили, что язык должен работать на виртуальной машине JVM и предоставлять доступ к Java-библиотекам.

Мартин Одерски начал разрабатывать Scala в начале 2000-х в стенах Лаборатории методов программирования EPFL. Он же ранее занимался разработкой Generic Java и компилятора Java фирмы Sun.

Внутренний релиз Scala появился в 2003 году. Первый публичный релиз вышел в начале 2004 года на Java-платформе, а в июне того же года – на .NET Framework (правда, с 2012 года эта платформа не поддерживается). Scala 2.0 увидела свет в 2006 году. Его компиляторы и библиотеки распространяются под лицензией BSD.
Лицензия BSD (Berkeley Software Distribution license — Программная лицензия университета Беркли) — это лицензионное соглашение, впервые применённое для распространения UNIX-подобных операционных систем BSD.
17 января 2011 года команда разработчиков языка выиграла грант на исследование сроком в пять лет. Европейский исследовательский совет выделил им около €2,3 миллиона. В мае 2011-го участники сообщества Scala во главе с Одерским основали компанию Typesafe Inc. (в феврале 2016 года переименована в Lightbend Inc.). Созданная компания должна была осуществлять финансовую поддержку разработчиков, создавать сервисы для Scala. Зарабатывать Typesafe должна была на Scala-библиотеках. В 2011 году фирма получила $3 миллиона инвестиций от Greylock Partners.


Мартин Одерски — создатель Scala

Что «под капотом»


Язык Scala объединяет три вещи: статическую типизацию, объектно-ориентированный и функциональный подход. Как уже говорилось, Scala работает на виртуальной машине Java. Совместимость («свободное смешивание») этого языка с Java дает возможность писать на Scala Android-приложения. Кроме того, возможность компиляции в JavaScript позволяет разрабатывать веб-приложения на Scala.

Несмотря на некоторую схожесть и даже родственную связь этого языка с Java, целых 10 лет после появления Scala его «старший брат» хранил верность объектно-ориентированной парадигме. И только в 2014 году в Java 8 были включены элементы функционального подхода – лямбда-выражения.

Помимо упомянутых выше Java и C#, на Scala оказали влияние другие языки и технологии. Способ выражения свойств во многом заимствован из Sather. Из Smalltalk перекочевала концепция унифицированной объектной модели. Beta поделился идеей о вложенности всего подряд, включая классы. Абстрактные типы в Scala напоминают абстрактные типы сигнатур в SML и OCaml, обобщенные в контексте полноценных компонентов.

Кроме того, Scala перенял особенности таких функциональных языков, как Scheme, Standard ML и Haskell.

Целевая аудитория


Преимущества Scala оценили многие крупные компании – Twitter, LinkedIn, Foursquare, Novell, Siemens, GridGain. Однако в академических кругах это язык пока популярен больше.

Пользователь @platoff в статье достаточно подробно изложил свой взгляд по поводу целевой аудитории языка.
Я прекрасно понимаю, чем Scala привлекает неопытную молодежь (а она в основном и хочет Scala):

• Ореолом элитности: действительно прогресс в Scala делают умнейшие ребята, типа, дураки на Scala не пишут, и если ты пишешь на Scala, то ты умный. Оп, ребята, программирование — это не учеба в университете, ты не будешь более «умным» программистом, чем сложнее заморочку ты решишь.

• Сложностью: наверно многие из Scala-фанатов и любителей не осознают, да и не способны сформулировать, что их привлекает в сложности. Подсознательно кто-то думает, что сложность == мощь. Типа чем сложнее, тем мощнее.

Очень сложную задачу можно просто решить, переиспользуя сложные решения. В нашем случае компилятор должен брать на себя как можно больше сложности, упрощая решение. Компилятор Scala безусловно сложен, но есть проблема — язык, в котором эта сложность выражается. Пользоваться таким языком безумно сложно.

Ngoc Dao, создатель Xitrum Scala web framework, Ngoc-Dao смотрит на ситуацию с точки зрения функционального подхода:
Говоря о функциональном подходе в принципе, безотносительно Scala, на ум обычно приходит Haskell. Однако, рассуждая с практической точки зрения, лучше выучить Erlang. Не зря все-таки Facebook потратил $19 миллиардов на покупку WhatsApp, который написан как раз на нем.

Erlang сдвинет ваше мышление в сторону функционального подхода сильнее, чем Scala. Кроме того, Erlang намного проще и быстрее учить. Вы можете освоить его за неделю и сэкономить свое время.

Так что, мнение на счет универсальности Scala может быть и скептическим – ни два, ни полтора: функциональная парадигма реализована непросто, да и в плане «объектноориентированности» он тоже слишком сложен.

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

Рейтинги и индексы


Индекс TIOBE по итогам октября 2016 года показывает, что Java является самым популярным языком программирования. Он уверенно лидирует уже 15 лет подряд и был на втором месте только в 2001 году.



Между Java и Scala в этом рейтинге наблюдается большой разрыв. Впрочем, последний уступает также языкам Lua, Fortran, Lisp, Transact-SQL, Ada и F#, расположившись на 33 месте. Однако в рейтинге 50 мест, и Scala все-таки сумел обойти функционально-логические языки Haskell и Prologue.



В другом рейтинге у Scala дела не так плохи. Согласно данным IEEE Spectrum за 2016 год, он занимает 15 место. Java тоже находится в лидерах, но на этот раз на почетном втором месте. Составители рейтинга указывают, что область применения Scala у них ограничена только веб- и мобильной разработкой. Разработка для ПК во внимание не принимается. В то время как Java они воспринимают как язык разработки для всех трех платформ.



По данным опроса Github на начало 2016 года, у Scala дела идут еще лучше: он занимает 11 место. Java опять возглавляет рейтинг. Причем, здесь он идет с большим отрывом от C#.



Исследователи также рассчитали индекс удовлетворенности языком программирования. Он показывает, хотели бы программисты, использующие тот или иной язык, писать следующий проект на этом же языке:



В первой группе мы видим Swift и Scala, которые делят между собой звание «идеального языка»; еще можно отметить довольно высокую оценку Go. Java здесь занимает только четвертую строчку. Это первый показатель, по которому Scala смог обойти своих родственников – C# и Java.

Перспективы


Свое мнение о будущем Scala уже высказывал Барух Садогурский — Developer advocate в компании JFrog:
Меня несколько пугает то, что сейчас происходит со Scala, потому что есть тренд ухода от него: например, компания TypeSafe, которая пыталась зарабатывать деньги на библиотеках, связанных со Scala. Некоторое время назад было объявлено об уходе TypeSafe с сильного акцента на Scala на гораздо больший акцент в Java, потому что большая часть enterprise-разработки на Java, где собственно находятся деньги. Поэтому они наняли много новых людей, которые подтягивают какие-то Java-интерфейсы, которых раньше у них не было.

Мы также видим другие библиотеки, которые были очень ориентированы на Scala. Например, Spark, где в новом релизе Java API подтянуты до уровня Scala, и, похоже на то, что дальше они будут развиваться не хуже API Scala, если даже не лучше. Я бы сказал, что в глобальной картине мы видим некоторый разворот в сторону Java.

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

Именно поэтому я никогда не был большим фанатом Scala, и тенденция ухода от Scala меня не удивляет. Безусловно Scala никуда не денется и продолжит развиваться, но в гораздо более нишевом формате.

Намного оптимистичнее смотрит на это Ashesh Ambasta, Lead backend engineer в CentralApp:
Я верю, что у Scala все-таки хорошие перпективы. Недаром многие крупные компании выбрали его. Несмотря на то, что путь, сочетающий ООП и ФП может показаться опасным и сбить с толку «пуритан», при аккуратном использовании, программирование на Scala может доставлять удовольствие.

Я не согласен с тем, что Scala в освоении труднее других языков программирования. Есть, конечно, определенный «барьер», связанный с необходимостью думать одновременно в разных парадигмах. Хотя на большинстве форумов этот язык почему-то обсуждают в контексте функционального программирования.

Мне приходилось слышать высказывания по типу: «Scala больше подходит для крупномасштабных систем, а не каких-то там Твиттеров». Но будет ошибкой полагать, что он создан только для этого. Я не думаю, что реализовать MVP (Minimum Viable Product) на Scala сложнее, чем на каком-то другом языке.

Я никогда не был особенно увлечен объектно-ориентированным программированием. С тех пор, как познакомился с Erlang, я к нему не возвращался. Затем я выбрал Scala для бэкэнд-разработки в новой компании и получил положительные отзывы. Это вселило в меня уверенность, что я сделал правильный выбор.


Куда пойти учиться?




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

HaruAtari:

Много лет пишу на php, надоело. Сейчас переучиваюсь на Scala-разработчика. Пока все идет хорошо, язык замечательный. Плюс совместимость с Java-библиотеками.

Но сегодня зашел на hh.ru и из любопытства посмотрел количество вакансий для Java/Scala-разрабов. Scala – 47, Java — 705. После этого несколько задумался. А я вообще смогу работу найти на этом языке? Есть ли какие-то перспективы в изучении Scala как основного языка сейчас. Есть ли перспективы в таком вложении сил? Или только java?

jkotkot:

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

opium:

Для России Scala в ближайшие годы — мертвый рынок, надо смотреть либо на зарубежный фриланс, либо на вакансии за границей.

gurinderu:

Что вы так сильно огорчились? Scala-разработчиков в разы меньше, чем Java, поэтому и разброс такой. Будет она востребована однозначно. К примеру, Tinkoff-банк использует Scala.

mrRontgen:

Отсутствие 100500 вакансий на hh – это не повод для паники. Язык молодой, но он очень стремительно набирает обороты. Насколько я знаю, Huawei начинают пилить интеграционные решения в России на Scala (вместо оракловских продуктов). Так что все не так плохо.

У Одерского и компании очень большие перспективы и амбиции. Так что, по моему мнению, Scala (или ее «апдейты») еще удивят программистов!
Поделиться с друзьями
-->

Комментарии (112)


  1. iCpu
    02.11.2016 20:59
    +9

    Всегда задавался вопросом: как люди умудряются так быстро изучить столько языков, чтобы выносить о них столь ёмкие суждения? Тут на изучение Java на уровне читателя уходит три года, и всё равно пробелы остаются. А люди за год по 10 языков изучают… Или это я у мамы особенный?


    1. Insferatu
      02.11.2016 21:04
      +10

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


      1. iCpu
        02.11.2016 21:06
        +14

        А разве изучение языка заканчивается на синтаксисе? Э-э-э-э, не, брат, после изучения синтаксиса изучение языка только начинается.


        1. sshikov
          02.11.2016 21:17
          +6

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


          1. iCpu
            02.11.2016 21:37
            +2

            sshikov,Insferatu, с одной стороны, я вас понимаю и не спорю с этим. Вопрос не в конструкциях, а в, если позволите, закидонах компилятора\интерпретатора. Монады, иерархии, исключения, лямбды, коллекции и функторы — оно всё хорошо и просто на демонстрационных проектах. Но ведь изучение языка и на этом не заканчивается.
            Самое интересное начинается, когда знакомишься с закидонами отдельных языков, когда начинаешь видеть прыщи на напудренном личике компиляторов. Когда на Си начинаешь использовать callback, на плюсах — колдовать compile-time шаблоны, в шарпах синхронизировать потоки, изменять java-класс на лету не перезапуская приложения, оборачивешь в haskell'е подтекающий поток и пытаешься разобраться, какой из случайно подключенных файлов-библиотек заменяет твой метод в Ruby.


            1. sshikov
              02.11.2016 21:51
              +3

              Конечно изучение на синтаксисе не заканчивается. Но ведь и не обязательно с него начинается!

              То что вы описываете — это уже тонкости. Далеко не каждый с ними вообще столкнется. Можно спокойно программировать много лет, ничего про это не зная. Вы не будете экспертом — но вы не будете при этом и начинающим.


            1. Saffron
              02.11.2016 23:54
              +2

              > закидонах компилятора\интерпретатора

              Тогда это называется изучением компилятора (или платформы), но не изучением языка. Язык — штука идеализированная. И понять чего она стоит действительно не сложно. Иногда мне кажется, что можно ввести чеклист на две сотни опций, заполнив который, можно выяснить всё что нужно о функциях языка.


              1. iCpu
                03.11.2016 00:35
                +1

                Есть и такое. А есть пробелы в спецификации, в которых код может вести себя не так, как кажется. Например, у плюсов есть неопределённое поведение, которое, по хорошему, должно быть ошибкой, но не вызывает падение приложения, так как его отлов дороже. Кроме них есть ещё платформозависимое и аппаратнозависимое поведение.

                И это всё часть языка, потому что нельзя использовать язык отдельно от балласта. И во многом язык определяет всё остальное. Например, консервативный и строгий Си великолепно и быстро транслируется в ассемблер именно из-за его низкоуровневости. А изначальный математический подход хаскеля к данным как к неизменному множеству определил как необходимость монад, так и яркий сексуальный опыт выхода в многопоточность. Думаю, и Питон тоже сможет удивить постоянным неуместным копированием данных.

                Если ограничиться только синтаксисом и концепциями верхнего уровня, можно получить неверное общее мнение о языке. Одно время хабровчане фанатели от рубинов, сейчас эта любовь плавно перетекла к Go и Scala. Хотя и тот, и другой имеют очень много изъянов, прежде всего по ту сторону монитора. Последний, к примеру, не очень расторопен при компиляции, что для привыкшего к тестам дебагом программиста не очень приятно.


        1. Insferatu
          02.11.2016 21:19
          +3

          Я имел в виду не только синтаксис. Ведь в ядре разных языков (в их компиляторах или интерпретаторах) могут использоваться весьма схожие принципы. И если ты подробно изучал один язык раньше, то изучая новый ты заметишь всё те же знакомые принципы, и тратить времени на их понимание и изучение не придётся. Взять к примеру популярные Java и C#. Если человек с нуля учит Java, ему предстоит изучить что такое виртуальная машина, что такое JIT-компилятор, что такое сборщик мусора, и т.д. и т.п. А если вторым языком он начнёт учить C#, то он с удивлением обнаружит, что некоторые из этих концепции присутствуют и в нём. И достаточно лишь обратить внимание на различия между реализациями этих концепций. Вот и тратится на изучение гораздо меньше времени.


        1. OnYourLips
          02.11.2016 22:34
          +1

          У языков из аналогичной сферы применения аналогичные инструменты и идентичные подходы. Поэтому при опыте 5 лет в одной технологии вы аналогичную научитесь так же хорошо использовать не за 5 лет, а за 3 месяца.
          И как раз язык (точнее, его тонкости) будет наиболее сложной частью. А фреймворки, библиотеки и инструменты гораздо проще. Вы же в своей сфере постоянно новые изучаете?


    1. sshikov
      02.11.2016 21:08
      +8

      >Язык программирования Scala является «симбиозом» Java и C#

      Где вы откопали это утверждение? Авторы Scala разрабатывали новые языки (Pizza, GJ) задолго до появления c#, скажем так, примерно лет за пять. И в истории появления языка C# кажется не упоминается вовсе. Можно цитатку?


      1. vadim_shb
        02.11.2016 22:43

        Тоже резануло. Насколько я понимаю, он тогда уж на F# похож. Да и это еще вопрос кто был первым Scala, F# или современный C#.


        1. sshikov
          02.11.2016 22:59

          Я про это и толкую, кто первым — далеко не факт. Согласно википедии, c# появился в 2000. При этом с 1990 существовал скажем Haskell, который очевидно значительно большее влияние оказал на формирование идеологии Scala.

          При этом заметьте, что сегодняшний и тогдашний c# — это две большие разницы. В тогдашнем не было почти ничего такого, что могло бы вдохновить на создание нового языка на платформе JVM, тем более людей, которые в 2001 уже создали компилятор Pizza, где уже были явные намеки на ФП (функции как сущности первого класса, например).

          А проект этого языка, как и GJ (прототип generics) и подавно появились где-то в 1998, когда c# просто не было. Не мог он вдохновить никого, просто по времени не выходит.


        1. roman_kashitsyn
          02.11.2016 23:25
          +1

          Насколько я понимаю, он тогда уж на F# похож.

          В Scala довольно сильно похожа на OCaml. Конечно, отличий в синтаксисе довольно много, но идеологическое наследие довольно легко проследить. К примеру, систему модулей из ML в Scala смогли унифицировать с объектной системой: вместо module type теперь обычный интерфейс (trait), вместо module — object, вместо функторов — наследование.


          Хм, даже нашлась довольно интересная презентация на эту тему: http://lambdafoo.com/scala-syd-2015-modules/


          F# так вообще по сути OCaml на .NET и без функторов.


    1. Fen1kz
      03.11.2016 03:01

      3 года на уровне читателя что-то и правда многовато.


      1. iCpu
        03.11.2016 05:56

        Ну я же только читаю…


      1. megahertz
        03.11.2016 07:19

        Из индусов за это время делают писателей. Правда читатели из них так-себе :)


        1. iCpu
          03.11.2016 07:40

          Писателем можно стать за две недели, ума особого тут иметь не надо.


    1. Shifty_Fox
      03.11.2016 08:19
      +2

      Это первый язык 3 года… потому что вы учите не язык, а паттерны, общий фундамент. Я 5 лет изучал C++, прежде чем осознал, что неплохо в нем ориентируюсь. Но после, каждый следующий язык был таким же как C++, только с другими подходами, я просто понимал что это тоже самое, только по другому. Достаточно было 2-ух недель, чтобы понять что Java — это jvm байт код, что у него есть по синтаксису, что по стандартной библиотеке. Что lua или js — это уже в основном jit компиляция и возможность переиспользовать код в runtime, с соответственными потерями в производительности, что доступы к переменным в этих языках — это обращения к хеш массивам по строковым ключам. Я это понимал, потому что в принципе все это можно было бы сделать и на C++, но это было выражено в виде дополнительного синтаксиса, компилятора и новой стандартной библиотеки.


      1. iCpu
        03.11.2016 08:50
        +1

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

        Переход в другие парадигмы «на 5 минуток» точно так же не даёт эффекта. Да, я выучил, с чем едят монады и как делать функторы. Но я ещё не распробовал их вкус, на каких задачах я буду с удовольствием разжёвывать лямбды, а на каких я опорожню желудок и потребую обратно мои богомерзкие плюсы, потому что не могу контролировать накладные расходы этапа выполнения.


    1. AndreyRubankov
      03.11.2016 08:51

      Есть люди, у которых нету личной жизни, которые способны уделить время учебе, саморазвитию и работе по 10-12 часов в сутки. В универе без проблем можно попробовать 4 языка программирования сдавая лабораторные работы. На практике уже придется прыгать между вакансиями. А в свободное от работы время поработать над собственным проектом.


      1. iCpu
        03.11.2016 08:56

        «И я там был, на пары ходил, по ушам текло, в зачётку не попадало»©


  1. potan
    02.11.2016 21:03
    +7

    Ну я устроился Scala-разработчиком не зная Java. Мне это не особо мешает, тем более что sbt проще в использовании, чем Maven.
    Так как Scala-разработчиков сложно искать, у нас начали брать Java-разработчиков и переучивать. Пока это проблем не вызывало. Scala они осваивают очень быстро, сложность языка преувеличена.


    1. roman_kashitsyn
      03.11.2016 00:33
      +2

      сложность языка преувеличена

      Спорное утверждение. Сильно зависит от того, как на нём писать. Если на нём пишут недавно переученные Java-программисты, то, наверное, код принципиально не сильно отличается от аналогичного Java-кода и потому выглядит простым.
      На мой взгляд, это один из самых сложных языков. Он мне показался сложным даже после повторного прочтения Programming Scala во времена Scala 2.8, и с тех пор ещё много всего добавилось (макросы, к примеру). Система типов слишком тяжеловесная (generic classes, abstract types, existential types, compound types, path-dependent types, dear god please make it stop).
      Помню, пытался реализовать свой Option[T] для разминки. Казалось бы, должно быть просто, но в итоге убил кучу времени и всё равно получал ошибки компиляции, которые было сложно расшифровать. К примеру, написать аналогичный Maybe a в Haskell — дело десяти минут, даже если не использовал язык долгое время. Cake-pattern тоже тяжело даётся, даже после опыта с compile-time dependency injection через функторы в OCaml.


      1. iCpu
        03.11.2016 00:47

        dear-god-please-make-it-stop types — это исключения для экстренного выхода из приложения?


        1. roman_kashitsyn
          03.11.2016 00:54
          +2

          Это отсылка к слайду в презентации Роба Пайка "Another Go at Language Design"


          public static <I, O> ListenableFuture<O> chain(ListenableFuture<I> input, Function<? super I, ? extends ListenableFuture<? extends O>> function) dear god make it stop

          a recently observed chat status

          http://web.stanford.edu/class/ee380/Abstracts/100428-pike-stanford.pdf


          1. iCpu
            03.11.2016 01:02

            Оу, а ведь я её даже читал… Всё ещё великолепное имя для типа фатальных исключений.


      1. potan
        03.11.2016 14:15
        +1

        В Scala принято хорошее разделение опыта на два вида — реализации бизнес-логики и написания библиотек.
        Написать хорошую библиотеку, которой можно легко пользоваться, действительно сложно. Но, по большому счету, без этого обычно можно обойтись. Уже реализовано достаточно много доступных сторонних хороших библиотек (тот же Slick), которые внутри устроены сложно, но пользоваться ими легко.
        А тот код, который требуется для «энтерпрайза», пишется легко и обязвтельного глубокого знания сложных особенноетей Scala не требует.


        1. roman_kashitsyn
          03.11.2016 14:40

          Написать хорошую библиотеку, которой можно легко пользоваться, действительно сложно

          Написать хорошую библиотеку в принципе сложно, независимо от языка. Моё утверждение в другом: даже простые задачи в Scala существенно труднее, чем они должны быть, из-за сложности языка. Понятно, что энтерпрайз в основном заключается в перекладывания данных из одного XML в другой и валидаций, и бОльшая часть кода относительно простая, но когда требуется сделать что-то нетривиальное, я обычно думаю "как бы я абстрагировал это в Haskell?", получаю тривиальное решение, а потом пытаюсь смоделировать его в Scala.
          Вот все говорят про "тайп-классы на имплиситах", а мне вот тайп-классы нравятся гораздо больше. Синтаксически гораздо легче, и не нужно помнить замысловатые правила поиска неявных объектов в разных скопах.


          В OCaml, кстати, тоже имплиситы завезти хотят Modular Implicits


          1. Scf
            03.11.2016 14:47

            Не нужны тайп классы и имплиситы для промышленной разработки. Разве что для тестов — чтобы красивый DSL сделать.


            1. roman_kashitsyn
              03.11.2016 15:56

              имплиситы для промышленной разработки

              Да ладно, каждый первый первым делом объявляет всякие коннекторы к базе и тред-пулы имплиситами.


              1. fogone
                03.11.2016 16:12

                именно поэтому мне нравятся языки с эксплиситами


                1. potan
                  03.11.2016 16:55
                  +1

                  С имплиситами бизнес-логика выглядит заметно чище.
                  При рефакторинге возникают некоторые проблемы, но не очень большие, если есть опыт их решения.


                  1. fogone
                    03.11.2016 17:17

                    Проблема в том, что с имплиситами то, что выглядит чище по факту может чище не быть. В явном подходе хотя бы понятно, что куча дерьма не прикрыта газеткой.


                    1. potan
                      03.11.2016 19:01
                      +1

                      Совсем не обязательно. Вопрос в уровне абстракции, на котором работает программист. Если он оперирует «пользователями», «изделиями», «заданиями», ему ни к чему думать об коннекшенах к базе данных и тредпулах. А функциям из библиотеки они нужны. Имплиситы частично освобождают от их протаскивания во все места, где они могут потребоваться.


                      1. Scf
                        03.11.2016 19:05
                        -2

                        для протаскивания существует dependency injection. Скаловский подход с cake pattern, синглтонами и имплиситами ошибочен.


                        1. fogone
                          03.11.2016 19:18

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


                      1. fogone
                        03.11.2016 19:16

                        Так абстракции в любом случае скрывают конекшены и тредпулы от пользователей и зданий, причем тут имплиситы? А большинство потребностей в опосредованности связей для меня решает DI.


              1. Scf
                03.11.2016 16:22

                Вот потом этот каждый первый и идет в собственный бложик крыть скалу разными частями тела. За ее сложность.


                1. roman_kashitsyn
                  03.11.2016 16:43
                  +1

                  Ну вот видите, на мой комментарий ответили два разработчика, один считает подход очень удачным, другой — очень неудачным. Теперь найдите Haskell-программиста, который считает typeclasses плохой идеей.


                  1. Scf
                    03.11.2016 16:46
                    -1

                    Так хаскель, я надеюсь, не претендует на роль промышленного языка? Или на простоту?


                    1. roman_kashitsyn
                      03.11.2016 17:05
                      +1

                      Или на простоту?

                      А почему нет? Хаскель — это довольно простой и логичный язык. Я считаю его языком на порядок более простым, чем OCaml и, тем более, Scala. Там не нужно помнить множество правил, синтаксических конструкций, компот из разных систем типизаций и неявных объявлений, чтобы понимать, как компилятор будет интерпретировать твою программу.


                      Вся "сложность" Haskell в том, что думать по-другому и разбираться в абстракциях, чтобы использовать язык и библиотеки эффективно.


                      на роль промышленного языка?

                      Пожалуй, основная деталь, которая мешает Хаскеллу в проде — это вездесущая ленивость по-умолчанию. Она существенно затрудняет анализ производительности и при неумелом использовании ведёт к так называемым space leaks, которые могут выстрелить в самый неподходящий момент.
                      Эта одна из причин, по которой разработчики из Standard Chartered (которые владеют более чем миллионом строк кода на хаскеле), написали собственный компилятор Mu, который по-умолчанию использует энергичные вычисления.


                      1. Sirikid
                        03.11.2016 17:38

                        Хочу уточнить, это компилятор Haskell?


                        1. roman_kashitsyn
                          03.11.2016 17:45

                          Если быть точным, это компилятор энергичного диалекта Haskell https://www.youtube.com/watch?v=hgOzYZDrXL0.


                          1. Sirikid
                            03.11.2016 19:06

                            Жутко интересно, есть какая-нибудь инфа кроме этого видео? Нагуглил какой-то лисп с квадратными скобочками и PDF.


                            1. roman_kashitsyn
                              03.11.2016 19:23

                              какая-нибудь инфа кроме этого видео?

                              Честно, говоря, про него мало что известно, исходников нет. Я сам узнал о существовании Mu относительно недавно из презентации Дона Стюарта на Google Tech Talk Haskell in the Large.


                              Пару деталей можно найти в блоге Дона:


                              Yes, we use Mu, which is our Haskell compiler. It’s source compatible with GHC, but with strictness on by default.

                              Кстати, в GHC начиная с версии 8.0 есть прагма Strict с аналогичным эффектом.


                      1. 0xd34df00d
                        04.11.2016 09:31

                        А в ghc 8 {-# LANGUAGE Strict #-} запилили (только заметил, что вы это же и написали).

                        Правда, семантику топ-левел-байндингов оно не меняет, ЕМНИП.


                  1. potan
                    03.11.2016 16:59

                    Не надо путать два понятия.
                    Имплиситы используются далеко не только для реализации классов типов. И сложности возникают именно с другими вариантами применения.
                    Сам я имплиситов немного побаиваюсь, но их использование в библиотеках часто делает использование этих библиотек гораздо удобнее.


                    1. fogone
                      03.11.2016 17:26

                      Я не гнушаюсь использовать имплиситы для передачи типа дженерика, но только потому что неявность здесь минимальная, а это временами очень удобно. Но подход этот всё равно довольно сложен для понимания в деталях. В котлине вот придумали намного более простой способ решить эту проблему (информация о типе в inline-функции) и хотя применение этой фичи ограничено, простота делает его использование очень приятной.


          1. potan
            03.11.2016 16:53

            Я как раз утверждаю, что простые и средние задачи на Scala решать существенно проще, чем на большенстве других языков.
            Конечно, зависит от задачи. Очень многое на Haskell делается красиво и тривиально. Но когда начинается ввод/вывод и обработка ошибок Haskell почти ни чего не дает, по сравнению с распространенными языками.


            1. roman_kashitsyn
              03.11.2016 17:14
              +1

              Но когда начинается ввод/вывод и обработка ошибок Haskell почти ни чего не дает

              Вот тут я не совсем понял. Что именно "не даёт" Haskell? Чего-то не хватает в стандартной библиотеке?
              Библиотек для эффективного потокового ввода-вывода больше, чем должно быть, потому что приходится выбирать, какую из них использовать (извечный вопрос "Pipes или Conduits?").
              Для обработки ошибок есть Either, который весьма удобно использовать вместе с MonadError. Исключения тоже есть, но они считаются bad practice и не такие удобные, как в той же java.


              1. potan
                03.11.2016 18:50

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


                1. roman_kashitsyn
                  04.11.2016 02:19
                  +2

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

                  Ох, опять. Чтобы добавить корректную обработку ошибок в "готовый" код (т.е., видимо, в код, в котором её нет), нужно всё равно всё переписать, независимо от языка. Исключения не являются универсальным решением проблемы, скорее создают только больше проблем.


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

                  Вообще говоря, это очень спорные утверждения. Роль ленивый вычислений в обработке ошибок принципиальна. Именно благодаря ленивым вычислениям можно писать красивый монадический код с обработкой ошибок, в котором в каждой строчке не стоит if err != nil.


                  Смеха ради набросал небольшой примерчик, чтобы продемонстрировать идею и не быть голословным. Иногда всё работает успешно, в 10% случаев возвращается ошибка с описанием. Расширения языка используются в основном для небольшого сокращения бойлерплейта.


                  {-# LANGUAGE FlexibleContexts, ExistentialQuantification, Rank2Types #-}
                  import Control.Monad.Except
                  import System.Random (randomRIO)
                  import System.Environment (getArgs)
                  import System.Exit (exitFailure)
                  import System.IO (hPutStrLn, stderr)
                  
                  type Person = String
                  
                  data FbError
                    = NetworkError String
                    | ApiError String
                    | InvalidAccount Person
                    deriving (Eq, Show)
                  
                  type FbDownloader = ExceptT FbError IO
                  type FbFun a b = forall m . (MonadError FbError m, MonadIO m) => a -> m b
                  
                  fbDb :: [(Person, [Person])]
                  fbDb = [ ("alice", ["bob"])
                         , ("bob",   ["alice", "eve"])
                         , ("eve",   ["bob"])
                         ]
                  
                  getFriendsOf :: FbFun Person [Person]
                  getFriendsOf person = do
                     x <- liftIO $ randomRIO (1 :: Int, 100)
                     case x of
                       _ | x < 6  -> throwError (NetworkError $ "Failed to download friends of " ++ person)
                       _ | x < 11 -> throwError (ApiError "Your api key is invalid :[")
                       _ | otherwise -> do
                             liftIO $ hPutStrLn stderr ("Requesting friends of " ++ person ++ " ..." )
                             case lookup person fbDb of
                               Nothing -> throwError $ InvalidAccount person
                               Just ps -> return ps
                  
                  getFriendsOfAll :: FbFun [Person] [Person]
                  getFriendsOfAll = fmap concat . mapM getFriendsOf
                  
                  getFriendsOfFriends :: FbFun [Person] [Person]
                  getFriendsOfFriends people = getFriendsOfAll people >>= getFriendsOfAll
                  
                  runDownloader :: FbDownloader a -> IO (Either FbError a)
                  runDownloader = runExceptT
                  
                  main :: IO ()
                  main = do
                    names <- getArgs
                    result <- runDownloader $ getFriendsOfFriends names
                    case result of
                      Left  e -> hPutStrLn stderr (show e) >> exitFailure
                      Right l -> mapM_ putStrLn l


    1. lookid
      03.11.2016 06:31

      Тогда такой вопрос. Вы пишите быстрый, компактный и эффективный код? Вы можете добавить новую функциональность написав всего 2-3 строчки? Вы используете всю мощь языка и стандартной библиотеки? Или пишете код уровня «паскаль, 10 класс школы»? Вы умещаете 1000 строк класс из Java в 100 строк Scala?


      1. potan
        03.11.2016 14:27
        +3

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

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


  1. UbuRus
    02.11.2016 21:39
    -13

    > Язык программирования Scala является «симбиозом» Java и C#

    Зачем вы так C# обижаете.
    Симбиоз Java и C# это явно Kotlin.


    1. madhead
      11.11.2016 03:52

      За что этот комментарий заминусили?


      1. iCpu
        11.11.2016 06:35

        Расисты, сэр.


      1. fogone
        11.11.2016 11:15
        +1

        Возможно, дело в том, что заявление, что котлин это симбиоз сишарпа и джавы настолько же глупое, как и то в ответ на которое оно было написано?


  1. MaximChistov
    02.11.2016 21:47
    +7

    По КДПВ:
    java версия уже вот так выглядит:

    public List<Product> getProducts()
    {
        return orders.stream().flatMap(Order::getProducts).collect(toList());
    }
    

    (и по-моему это сильно читабельнее)


    1. splav_asv
      02.11.2016 22:41
      +1

      collect(toList())
      это опечатка и должно быть
      collect().toList()
      или действительно так странно?


      1. saksmt
        02.11.2016 22:54
        +1

        Это действительно так странно :)


      1. superyateam
        02.11.2016 23:57
        +1

        по идее там должно быть
        collect(Collectors.toList())
        параметр к методу collect — это то, во что собираем. Так что не так уж и странно.

        Автор комментария видимо «статически импортнул» Collectors.toList — поэтому и выглядит странно


        1. MaximChistov
          03.11.2016 00:03
          +2

          Ну мы всегда так делаем, тк это повышает читаемость(Collectors тут не добавляет новой инфы тк он пишется внутри функции с названием collect)


    1. murvit
      02.11.2016 22:54

      К КДПВ вообще много вопросов. И если

      ArrayList <Product>
      
      еще можно объяснить, то
      for (Order order : order)
      

      вообще не скомпилируется.


    1. Abdgirk
      02.11.2016 23:57
      +3

      вообще картинка на КДПВ не самая удачная. От нее у людей, не знакомых со scala возникает ложное ощущение что преимущество scala — это просто более удобный синтаксический сахар. Естественно, после этого возникает справедливое замечание, что в 8-й java (которая уже давненько вышла) тоже можно так делать. Но почему-то большинство асторов java vs scala (это я не про TS) забывает про возможно более итересные вещи — неблокирующие future, акцент на immutable данные и тд…


    1. MaximChistov
      03.11.2016 00:02
      +4

      *точнее

      return orders.stream().map(Order::getProducts).flatMap(List::stream).collect(toList());
      

      или
      return orders.stream().flatMap(o -> o.getProducts().stream()).collect(toList());
      


  1. iCpu
    02.11.2016 22:40
    +1

    [offtop] Поражаюсь любви некоторых граждан к дешёвым манипуляциям. Если нужно показать что-нибудь старым и замшелым, пририсуйте ЭЛТ-монитор. [/offtop]


  1. vbs
    02.11.2016 23:20
    +4

    Последнее время в статьях постоянно мелькает некто Барух Садогурский.
    Судя по тому, что о нем известно из сети, это больше медиа-персона, чем серьезный девелопер, а название компании JFrog не говорит ничего, равно как и должность Developer advocate.
    Я не являюсь профессионалом, код — хобби.
    Вполне допускаю, что персона что-то из себя представляет а я что-то упустил, однако насколько стоит ссылаться на его высказывания при оценке ЯП Scala?


  1. fogone
    02.11.2016 23:22
    -5


    1. missingdays
      02.11.2016 23:37
      +1

      Вы объявили поток Product, а надо было метод, возвращающий List. Как-то типы не очень сходятся.


      1. fogone
        03.11.2016 09:05

        Кому надо было? Во-первых, в скала-версии нет метода, в java-версии я его тоже выкинул. Во-вторых, в скала-версии мы и понятия не имеем, что за типы там используются, а так как java-версию на исходной картинке писал человек явно не знающий джаву, то я взял на себя смелость использовать те типы, которые посчитал нужными. Так что всё с типами хорошо.


        1. grossws
          03.11.2016 09:16

          В scala-версии как раз метод и объявлен. Вы просто def не заметили.


          1. fogone
            03.11.2016 09:55

            ваша правда — перепутал def с val. Но надо признать, что метод был бы не сильно больше:

            public Stream<Product> getProducts() {
                // если уж совсем честно, то здесь должно быть вот так
                // потому что стримы flatMap-ят только стримы, а getProducts()
                // врядли возвращает Stream
                return orders.stream().flatMap(o -> o.getProducts().stream());
            }
            

            Но основной смысл картинки был не в том, что java такой же лаконичный язык как скала, а в том, что исходная картинка пытается показать java-разработчика каким-то атавизмом, в то время как и компьютер у него в действительности такой же, да и язык достаточно современный, пусть и без " тайп-классов на имплиситах".


            1. Sirikid
              03.11.2016 11:23

              Если метод getProducts то лучше вернуть список, для стрима как раз products.


              1. fogone
                03.11.2016 12:45

                я так думаю, что это зависит от контекста. Возможно, для получения стрима метод лучше было назвать `findProducts()`, но еще раз — сути это никак не меняет — моя картинка была не про язык, а про то, что миф с картинки о том, что скала-программист это такой «факеа», а разработчик на java нелепый старпер — он в корне неверный. Более того, часто это один и тот же человек. А джава хоть и многословный язык, но достаточно современный и имеющий свой подход и концепцию.


                1. Sirikid
                  03.11.2016 13:06

                  Не видел гайдлайнов но в стандартной библиотеке часто именно так, findProducts это скорее для метода с аргументом-предикатом. По второму пункту полностью согласен, статья странная и картинка :[|||]:


    1. Shifty_Fox
      03.11.2016 08:23

      Тем более, что Scala сама выводит типы и не позволит такой ошибке даже случиться :)
      Еще вы как бы заранее завели метод Order::getProducts, а в Scala геттер создается на ходу.


      1. fogone
        03.11.2016 09:08

        Какой такой? В коде нет никакой ошибки. Один стрим flatMap-ится в другой. Да, вероятно getter ide создала, но это сути передергивания исходной картинки не меняет.


      1. AndreyRubankov
        03.11.2016 11:58

        Если сильно нужно, в java есть project lombok, который на препроцессоре аннотаций автоматом создаст вам геттеры. Кода меньше, немного аккуратнее выглядит, но играть с магией — это всегда опасно.


        1. grossws
          03.11.2016 12:06

          Я последнее время предпочитаю org.immutables:value, несколько удобнее в обращении, работает на том же уровне (annotations processor).


  1. sheknitrtch
    03.11.2016 00:07
    +5

    Меня смущает, что в статье рассказывая о языке Scala автор критикует не сам язык, а его популярность в IT индустрии. И в приведённых цитатах всё больше говорят «рынок», «вакансии», «зарплата». Критика в духе «все деньги в Java» ничего не говорит о качестве Scala. А противостояние Java vs. Scala переводится в сторону корпоративных заказчиков, денежных перспектив и бизнес-проблем. Мне, как программисту, скорее интересно услышать про скорость разработки, про выразительность и краткость, про новые абстракции и улучшенные Generic-классы.
    Тот факт, что компания TypeSafe не смогла заработать на продвижении Scala, на мой взгляд говорит лишь о закостенелости рынка Enterprise разработки (Я здесь побуду капитаном-очевидностью), и не должна отпугивать разработчиков от изучения функциональных языков программирования.
    В общем, статья скорее для менеджеров, чем для инженеров. А моё ИМХО: есть классный курс «Принципы функционального программирования на Scala», который ведёт сам Одерски.


    1. solver
      03.11.2016 11:54
      +2

      Все правильно и логично.
      И хоть меня закидают помидорами за такое мнение…
      Большинству компаний не нужны ни Scala ни развите Java. Им это просто не выгодно. У них есть куча продуктов на старых версиях Java, которые кто-то должен поддерживать и продавать. Для этого нужны люди.
      А как можно вообще заманить человека на унылую работу по поддержке легаси?
      Ведь не секрет, что большая часть Java проектов до сих пор не вышли даже за Java 6.
      Переписывать дорого и не факт что выйдет лучше чем было, плюс риски для клиентов.
      Вот и культивируются мысли молодых разработчиков, что в Java все деньги, дергаться не надо, это типа большие риски. Плюс текущая ситуация на рынке, ЗП за легаси платят неплохие.
      Все это вместе заставляет очень медленно проворачиваться колесо индустрии в целом.
      У этой ситуации нет простого решения, но надо понимать, почему на Scala в основном катят бочку не в техническом плане.


  1. ImLiar
    03.11.2016 02:21
    +7

    Всегда умиляло, когда нескалисты говорят «да там в восьмой джаве завезли лямбды и стримы, скала больше не нужна». И потом начинают сравнивать map/flatMap в языках. Ну здорово, теперь ламбада-функции есть и в джаве, искренне рад. дукалис.jpg

    Вот только никто почему-то не вспоминает про работу с асинхронностью с Future as monad из коробки.

    Или про тайп-классы на имплиситах, которые позволяют писать какие угодно дженерик решения для любых
    типов (да, да, даже для сторонних, стандартных, whatever, и всё это без оберток).

    Или про type-safe парадигму в скале, когда, во многом благодаря той самой «переусложненной» системе типов, можно смотреть на List[Any] или касты .instanceOf как на недоразумение неопытного разработчика.

    И да, работу на скалке тоже можно найти. И, что характерно, вероятно, что вы окажетесь в опытной и сильной команде, у которой всегда можно чему-то научиться, что должно быть, по моему мнению, решающим фактором на любой работе. И это по той простой причине, что порог вхождения в язык находится выше уровня «копипаст со stackoverflow, херак и в продакшн».

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


    1. velafrys
      03.11.2016 04:57
      +2

      Или про тайп-классы на имплиситах, которые позволяют писать какие угодно дженерик решения для любых
      типов (да, да, даже для сторонних, стандартных, whatever, и всё это без оберток).

      Сколько у вас человек в команде?


      1. ImLiar
        03.11.2016 21:15

        На одной работе 5 бэкэндщиков.
        На другой — 6.

        Не вижу корреляции.


    1. Scf
      03.11.2016 11:29
      +8

      Пишу на скале уже два года и ни за что не вернусь обратно. Даже если не лезть в систему типов и имплиситы, которые, имхо, вредны для ежедневного программирования, есть куча мелочей, которые в сумме дают сильный прирост скорости разработки. if/switch/code block as expressions, паттерн матчинг, однострочные объявления методов, сокращенный синтаксис вызова curried functions...


      Быть может, когда-нибудь накатаю статью на тему "чем scala лучше с точки зрения промышленного программиста".


    1. fogone
      03.11.2016 12:29

      Расскажите в двух словах, в чем уникальность «Future as monad» перед аналогичными решениями в java?


      1. Scf
        03.11.2016 12:50
        +1

        тем, что в джаве есть только CompletableFuture, который спроектирован, скажем так, неудачно. И даже если сделали (или сделают) нормальный порт на джаву, то тормозящим фактором станет уже синтаксис:


        task1.thenCompose(v1 -> {
          return task2.thenCompose(v2 -> {
            return runTask3(v1 + v2);
          });
        });

        и


        task1.flatMap { v1 =>
          task2.flatMap { v2 =>
            runTask3(v1 + v2)
          }
        }

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


        1. fogone
          03.11.2016 13:11

          соглашусь, что scala-версия выглядит несколько приятнее, но выпячивать эту фичу как весомый аргумент я бы наверное не стал. Тем более, вы написали так, что эта фича есть «из коробки», как будто именно это важно. А из коробки она есть и в джаве, к тому же если я правильно понял, что вы хотели написать, то скорее это будет вот так:

          supplyAsync(() -> "test").thenCombineAsync(supplyAsync(() -> "test2"), this::doSomething);
          


          В этом смысле на мой взгляд намного интереснее поддержка continuation-ов в kotlin 1.1, вероятно такой код можно было бы сделать:

          val v1 = await(runTask1())
          val v2 = await(runTask2())
          runTask3(v1, v2)
          


          1. fogone
            03.11.2016 13:20

            а если полностью идентичный код, то видимо так:

            supplyAsync(this::runTask1).thenCombineAsync(supplyAsync(this::runTask2), this::runTask3);
            


            1. Scf
              03.11.2016 13:33

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


              1. fogone
                03.11.2016 14:10

                кстати если уже есть task1 и task2, то еще проще:

                // как предложил @Sirikid ниже
                task1.thenCombine(task2, (v1, v2) -> runTask3(v1 + v2))
                task1.thenCombine(task2, Integer::sum).thenCompose(this::runTask3);
                

                по моему опыту использования scala, чаще всего её нужно или использовать как предлагают в best practice и тогда она становится достаточно сложной или java-way и тогда особые преимущества найти сложно, а местами даже скалу использовать менее удобно, например аннотации, которые несовместимы с java-аннотациями.


                1. Scf
                  03.11.2016 14:16

                  Ну как сказать… три разных синтаксиса для одной и той же задачи, причем все три специфичны для входных условий. одни хороши, когда у нас переменные, другие — когда функции, третьи — когда лямбды. Обратите внимание, в скале для этой задачи один и тот же синтаксис подходит для всех случаев, и этот синтаксис — прост.


                  И — откуда вообще мысль, что best practice — сложен? Посмотрите вот сюда: http://twitter.github.io/effectivescala/


                  Ничего страшного там нет.


                  1. Scf
                    03.11.2016 14:23

                    Что я хочу сказать — предложенные варианты на джаве могут быть короче, могут быть интереснее, но они сложнее. И это при этом, что в сложности обвиняют скалу.


                  1. Sirikid
                    03.11.2016 14:25

                    За ссылку спасибо, а вообще мне кажется делать flatMap из flatMap это уже странно.


                    1. Scf
                      03.11.2016 14:50

                      Можно Future.sequence(List(v1, v2)).map(_ + _).flatMap(runTask3)
                      Но мы же говорим о промышленном коде, а не олимпиадном, не так ли?


                  1. fogone
                    04.11.2016 19:52

                    Итого всё сделать и одним образом как в скале, только удобно когда флоу описывается плоско, в этом смысле эти возможности очень удобны


          1. Scf
            03.11.2016 13:28

            task1, task2 — это локальные переменные типа CompletableFuture<Integer>


            v1, v2 — это, соответственно, Integer


            CompletableFuture<Result> runTask3(int arg);


            1. Sirikid
              03.11.2016 13:46

              Если вы настаиваете именно на такой трактовке, то на Java это пишется вот так (извините, тегов нет):

              task1.thenCompose(v1 -> task2.thenCompose(v2 -> runTask3(v1 + v2))); // or
              task1.thenCombine(task2, (v1, v2) -> runTask(v1 + v2)); // or
              task1.thenCombine(task2, Integer::sum).thenCompose(this::runTask3);

              Самые необходимые лямбды в Java покрыты специальным синтаксисом, никто не заставляет для одного выражения писать фигурные скобки и return.


          1. seryh
            03.11.2016 14:13

            Раз уж пошли код сравнивать как можно без lisp в лице Clojure:


            (defn task-3 []
              (let [v1 (future (task-1))
                    v2 (future (task-2))]
                (future (+ @v1 @v2))))


        1. Sirikid
          03.11.2016 13:12

          del


        1. MaximChistov
          03.11.2016 14:28

          так для однострочников return и скобки не нужны
          и

          task1.thenCompose(v1 -> {
            return task2.thenCompose(v2 -> {
              return runTask3(v1 + v2);
            });
          });
          

          плавно превращается в:
          task1.thenCompose(v1 -> 
               task2.thenCompose(v2 ->  
                   runTask3(v1 + v2)
               )
          );
          


      1. ImLiar
        03.11.2016 21:24
        +2

        Например, можно писать так:

        for {
          a <- futureA
          b <- futureB
          c <- futureC
        } yield {
        ...
        }
        


        Компилятор сам разложит на map/flatMap (можно даже с if подключить filter). Это для начального уровня.

        Зайдя чуть дальше в ФП — там Future всё еще монада (ну ладно, тут я лукавлю, она монада, если забыть про эксепшены внутри, иначе left identity не выполняется, но не суть). А значит, можно подрубить монад-трансформеры и работать с Future[Option[A]] словно у вас праздник на улице. В коде ниже мы получаем доступ сразу до значения типа А внутри двух монад:

        for {
          a <- futureOptA.optionT //a: A
          b <- futureOptB.optionT //b: B
          c <- futureOptC.optionT //c: C
        } yield {
        ...
        }
        


        К слову, это довольно частый кейс при работе с асинхронными базами/драйверами. Вы ждете запись в будущем, которая может и не существовать в базе.

        Любопытства ради, хотелось бы увидеть решение на джаве. Слышал, там Option тоже завезли.


        1. Sirikid
          03.11.2016 23:38
          +2

          Как говорится Maybe без паттерн-матчинга деньги на ветер, хотя все же удобнее ифов


    1. ppopoff
      05.11.2016 19:19
      +5

      Не знаю, у меня было совершенно наоборот. Когда меня бросили в скалу, я ее сначала возненавидел, зато потом полюбил. И не за синтаксис, и не за вывод типов, и не за лямбды. А за мелочи, которые делают жизнь проще: Правильным образом перегружаемый == инвариантные массивы, ADT (которые позволяют делать исчерпывающую проверку при паттерн-матчинге), Кейс-классы знатно экономят время. А потом уже стандатный набор всего и вся.


  1. ShadowsMind
    03.11.2016 11:51
    +6

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

    Например из цитаты platoff можно сделать вывод, что Scala выбирает неопытная молодежь, хотя на самом деле все с точностью до наоборот. Цитата Баруха тоже не к месту, с чего Вы взяли, что мнение человека из Java/Groovy-мира является экспертным относительно Scala?! (ничего не имею против Баруха, с удовольствием слушаю подскаст всей их тусовки «Разбор полетов», но у него нет экспириенса в этой нише и это просто мнение сбоку по факту). Приведенные рейтинги всяких Teobe, IEEE Spectrum и прочих вообще не отражают реальности: Matlab, R, Asembly выше в рейтинге чем Scala — ага, кулл стори… Судить о языке по количеству вбиваний в гугл и каких-то абстрактных статистик в вакууме — это полнейший бред.
    Scala развивается громадными темпами, причем имеется в виду не только сам язык, но и экосистема и востребованность на рынке. Исходя из недавних отчетов stackoverflow.com scala-разработчики одни из самых довольных своей технологией + с одними из самых высоких заработков среди разработчиков. Похожие данные были и от Dou, которые тоже кстати напрямую работают с комьюнити(на Dou просто делаются опросы), а не как Teobe и КО, которые берут данные с потолка.

    Создается ложное впечатление, что у Scala все плохо, но перспективы есть. Все совсем не так — для Scala эти перспективы уже настали, сейчас все отлично и продолжает набирать обороты. Эта статья была бы актуальна этак году в 2009ом, но ни как не в текущих тренда и спроса на биг-дейта, анализ данных, распределенных систем и прочего, в чем Scala преуспела.

    В статье ни слова про уровень и количество конференций в ФП мире и в Scala в частности. Про положительный экспириенс фирм, которые используют Scala — недавно paypal выкладывали статью о том у них все отлично с Akka. Про крутые проекты/технологии, которые были реализованы на Scala — Spark, Akka, Kamon, Kafka и т.д. О том какие нововведения и перспективы ждут нас в ближайшем будущем — Scala 2.12, Dotty и прочее.

    Спрос на Scala весьма хороший в текущих реалиях, о каких “разворотах в сторону Java” вообще идет речь? На Linkedin даже обычным Scala разработчикам постоянно приходят предложения, не говоря уже о Spark специалистах. Еще можно посмотреть тут и сделать выводы: https://jobs.functionalworks.com/

    Вообще лучше смотреть кейноты ФП и Scala конференций, чтобы понимать что происходит в ФП и Scala-мире, а не из слов людей знающих о продакшене на Scala чуть меньше чем совсем ничего, набрасывающих и делающих выводы на основе Teobe-рейтингов и говорящих о “смерти” языка из-за обычного переименования Typesafe -> Lightbend…
    Вот еще хорошее видео, с объективной оценкой о том “Какое место Scala занимает в IT-индустрии” — https://www.youtube.com/watch?v=jTomnoJ3TyQ


    1. sshikov
      03.11.2016 16:08
      -1

      >На Linkedin даже обычным Scala разработчикам постоянно приходят предложения

      Это тоже плохой показатель. Он демонстрирует только наличие дефицита — но ничего не говорит о числе предложений.


      1. ShadowsMind
        03.11.2016 16:22

        Как это не говорит, предложения с воздуха по Вашему берутся что ли? Все же просто — какой-либо бизнес выбирает Scala, пилят продукт, растут, ищут новых разрабов. Не пойму в чем тут плохость показателя — в IT всюду дефицит кадров, не успевают специалисты появляться настолько быстро, насколько этого требует рынок.


        1. sshikov
          06.11.2016 20:42

          А вот так и не говорит. Меня, было дело, просто достали с linkedin предложениями поработать над BPM проектом. Раз 10 предлагали. Как вы думаете, сколько было вакансий? Одна. Ее просто не могли закрыть полгода, поэтому всем, у кого в профиле фигурирует BPM, написал каждый не ленивый HR, по одному разу.


  1. stokker
    04.11.2016 01:21

    Очень узкое место займет — высокий порог входа не для энтерпрайза. Поэтому будет использоваться для отдельных крупных проектов, для которых разработчиков будут искать по всему свету…


  1. guai
    10.11.2016 10:06

    Какая точная картинка! Один сидит пилит код, второй ждет, пока скомпилируется :)