Я бы поостерегся так сразу рекомендовать scalaz и Validation.
На данный момент лучшим вариантом для изучения представляется cats, а не scalaz. Как минимум потому, что проще и популярнее.
Без глубокого знакомства в ФП, просто как drop-in replacement для Either, Validation подходит плохо. Просто потому, что не монада нельзя использовать в for. Обилие toEither (или disjunction) в коде будет явным минусом.
Они связаны, но речь о первом. С точки зрения scala реализация для типа `T` type class `Monoid` — это требование наличия в текущем контексте implicit объекта/метода типа `Monoid[T]`. Отсюда, кстати, необычный для haskell эффект: в одной кодовой базе может быть 2 реализации одного type class, например если вам требуется 2 разных маршалинга в JSON для ваших типов (1 в БД, другой — в REST), вы можете написать/получить макросами 2 реализации `Format[T]` и в месте использования импортировать нужную. Отсюда же не очевидное неудобство, от которого сейчас избавляются в Dotty.
На самом деле «implicit classes» — это частный случай к implicit conversion. И по сути это ближе всего к extension methods, но с тем важным отличием, что возможно не только добавление отдельных методов, но и приведение к интерфейсам.
Хотите подробней — я ниже ссылку кинул — лучше Одерски я не расскажу, но могу ответить на конкретные вопросы, если возникнут.
Но если хотите объяснения что такое implicit, то лучше послушать Одерски: What to Leave Implicit. Только учтите, что все такие доклады больше рассчитаны на людей из java, а не из haskrll.
Полного аналога на haskell скорее всего нет. Но, в частности, type class из haskell и trait из rust в scala — частный случай использования implicit.
В частности в котлине не написать метод, аналогичный mempty из haskell, Monoid[T].empty из scala и Default::default() из rust.
Навскидку (с цейлоном у меня даже хуже, чем с котлином): Цейлон позволяет отличить MyClass<Integer> от MyClass<String> в case. Достигается за счет доп. информации в инстансах дженериков. Сломается если MyClass<T> создан в java. Как это взаимодействует с джавовыми либами, создающими экземпляре на основе рефлексии (маршалинг, БД, etc), я затрудняюсь предугадать.
Принципиальной разницы между type members и type parameters в общем-то нет — они это продемонстрировали унификацией.
И в scala зачастую поднимали type members в type parameters — см Aux паттерн в shapeless.
Но если придираться, то можно сказать, что wildcard type в Dotty просто нет: Dropped: Existential Types.
Это не единственная фича inline методов, требующая поддержки компилятором на вызывающей стороне. Насколько я помню inline методы из java не видны вообще.
Утверждается, что продолжения из java использовать не получится: https://stackoverflow.com/a/41561165.
И inline не получится: https://stackoverflow.com/a/42742119. Что логично, учитывая реификацию.
Мне импонирует ваша вера в то, что все так, как предполагается наиболее логичным, но, к сожалению, авторы Kotlin столкнулись с объективными трудностями, некоторые из которых разрешили ценой потери совместимости с java, в чем я их поддерживаю.
Еще когда-то они считали, что nullable типы покрывают все аспекты взаимодействия с java кодом в плане nullability, но пришлось вводить «сырые» типы. Это не хорошо и не плохо, это объективная реальность с которой приходится считаться.
Все на этом пути пожертвовали чем-то. И ceylon, и kolin, и scala. Стоит помнить чем именно они пожертвовали и ради чего.
Либо речь об очень ограниченном использовании Scala (на которой можно «писать Java код» без использования продвинутых фич), либо вы сильно преувеличиваете, либо качество результата оставляет желать лучшего.
Я курсы по scala веду. Народ за месяц осваивает slick, akka, akka-http, scalaTest, etc. Естественно не на глубоком уровне, но на глубоком уровне и java за месяц не освоить. Но они в состоянии использовать эти инструменты.
Курсы на coursera обучают скорее идеоматическому FP, чем именно скале. Например неплохо бы знать что такое параметрические тесты, но можно и без них обойтись.
Kotlin позволяет делать DSL (взять хотя бы DSL для Gradle или Anko), но его возможности довольно сильно ограничены и для меня это скорее плюс.
Пройдите по ссылке на vavr.io и посмотрите какие DSL таки можно делать на java. А на котлине… Вас не затруднит перечислить все варианты того, чем могут быть «f» и «v» в данном коде на Kotlin: m{f(v)}?
А если библиотека не развивается активно (но при этом достаточно стабильна и удовлетворяет потребности)?
Не видел такого, но однажды подключал не стабильную библиоткеку прямо как проект с github (это 1 строчка в sbt). В таком случае не надо вообще заморачиваться с версиями scala.
Extension функции в Kotlin это просто синтаксический сахар и реализуется через статические методы (как и в C#, откуда взята эта фича)
Я в курсе. А extension методы скалы — это просто синтаксический сахар над классами-обертками и вызываются соответствующим образом. Все аналогично. Хотите ссылку на аналогичный гайд для scala?
Про популярность — если брать объективные критерии: github и SO, то популярность растет. Но эти критерии не идеальны. Если брать мои субъективные ощущения, то популярность scala вокруг меня за год выросла раз в 10, что характеризует только крайне локальные изменения вокруг меня, а не картину в целом, как и любые другие субъективные критерии.
Вы попробуйте как-нибудь прийти в команду с проектом на Scala, который разрабатывается уже пару лет.
Вот как раз недавно в такой проект пришел и даже принял его разработку (старая команда планово ушла через пару недель совместной работы). Полет нормальный.
— Высокий порог вхождения
Люди почти без опыта программирования (с базовыми теоретическими знаниями java) осваивают scala без труда.
— Гибкость языка
Изобретать DSL можно и на java. И иногда это даже оправдано. А scalaz вообще-то используют либо при разработке библиотек, либо знатные извращенцы, которые на любом языке нагородят, например подключив vavr.io в java.
— Плохая совместимость с Java.
Зависит от. Но extension методы котлина вам будет не менее весело вызывать из java, чем аналогичные extension методы скалы. С параметрами по умолчанию та же проблема в обоих языках. Методы с implicit параметрами вы вызвать сможете, только передать их вручную придется. Единственное, что реально не вызываемо это макросы, но довольно логично, что библиотеки метапрограммирования на scala не вызывать из java, как inline методы котлина не вызвать снаружи.
— Проблемы обратной совместимости
Да, это не приятно. Но эта проблема на плечах разработчиков библиотек. sbt берет нужную версию автоматически. И на данный момент актуальных версий 2: 2.11 и 2.12.
— Конкретно для Android также критичен размер рантайма, насколько помню у Scala он слишком большой для Android.
Сам рантайм — нет. С доп. библиотеками — да. Решается через proguard.
Кроме того, по ощущениям бурный рост Scala остановился около года назад
Что вы подразумеваете под ростом скалы? Основной инструментарий (akka, play, slick, etc) развивается стабильно. Сама scala сейчас идет к версии 3.0 (см dotty). Проекты на scala — тут у меня выборки нет.
Спасибо за статью.
То есть какого-то общеупотребимого набора инструментов вроде lombok в C# нет?
А существование коммерческих решений для подобного — для меня это показывает разницу в мировоззрении. С тех пор как перешел на jvm я уже не могу себе представить платные решения для тивиальных действий — скорее приходится выбирать из нескольких свободных.
Структуры изменяемы по умолчанию.
И передача по значению — не всегда хорошо. Но иногда полезно, особенно при размещении в массиве. В jvm структуры сейчас добавляют, но только в immutable варианте.
И Data class — класс с полноценными методами, который можно проксировать, инструментировать и извращаться всеми остальными способами. Иногда и это важно.
Если на scala адаптируется какой-то алгоритм с while + break, то есть всего 2 варианта:
Второй вариант не всегда оправдан в случае «академического» алгоритма.
не монаданельзя использовать в for. Обилие toEither (или disjunction) в коде будет явным минусом.На самом деле «implicit classes» — это частный случай к implicit conversion. И по сути это ближе всего к extension methods, но с тем важным отличием, что возможно не только добавление отдельных методов, но и приведение к интерфейсам.
Хотите подробней — я ниже ссылку кинул — лучше Одерски я не расскажу, но могу ответить на конкретные вопросы, если возникнут.
В частности в котлине не написать метод, аналогичный mempty из haskell, Monoid[T].empty из scala и Default::default() из rust.
И в scala зачастую поднимали type members в type parameters — см Aux паттерн в shapeless.
Но если придираться, то можно сказать, что wildcard type в Dotty просто нет: Dropped: Existential Types.
А так — да, Dotty (Scala.next в начале).
Это, конечно, не java, но примеры систем типов, в которых это отслеживается, существуют.
И inline не получится: https://stackoverflow.com/a/42742119. Что логично, учитывая реификацию.
Мне импонирует ваша вера в то, что все так, как предполагается наиболее логичным, но, к сожалению, авторы Kotlin столкнулись с объективными трудностями, некоторые из которых разрешили ценой потери совместимости с java, в чем я их поддерживаю.
Еще когда-то они считали, что nullable типы покрывают все аспекты взаимодействия с java кодом в плане nullability, но пришлось вводить «сырые» типы. Это не хорошо и не плохо, это объективная реальность с которой приходится считаться.
Все на этом пути пожертвовали чем-то. И ceylon, и kolin, и scala. Стоит помнить чем именно они пожертвовали и ради чего.
https://github.com/lampepfl/dotty/issues/2491#issuecomment-304212551
В обсуждении восторги явно не доминировали и решили, что оно того не стоит.
Курсы на coursera обучают скорее идеоматическому FP, чем именно скале. Например неплохо бы знать что такое параметрические тесты, но можно и без них обойтись.
Пройдите по ссылке на vavr.io и посмотрите какие DSL таки можно делать на java. А на котлине… Вас не затруднит перечислить все варианты того, чем могут быть «f» и «v» в данном коде на Kotlin: m{f(v)}?
Не видел такого, но однажды подключал не стабильную библиоткеку прямо как проект с github (это 1 строчка в sbt). В таком случае не надо вообще заморачиваться с версиями scala.
Я в курсе. А extension методы скалы — это просто синтаксический сахар над классами-обертками и вызываются соответствующим образом. Все аналогично. Хотите ссылку на аналогичный гайд для scala?
Про популярность — если брать объективные критерии: github и SO, то популярность растет. Но эти критерии не идеальны. Если брать мои субъективные ощущения, то популярность scala вокруг меня за год выросла раз в 10, что характеризует только крайне локальные изменения вокруг меня, а не картину в целом, как и любые другие субъективные критерии.
Люди почти без опыта программирования (с базовыми теоретическими знаниями java) осваивают scala без труда.
Изобретать DSL можно и на java. И иногда это даже оправдано. А scalaz вообще-то используют либо при разработке библиотек, либо знатные извращенцы, которые на любом языке нагородят, например подключив vavr.io в java.
Зависит от. Но extension методы котлина вам будет не менее весело вызывать из java, чем аналогичные extension методы скалы. С параметрами по умолчанию та же проблема в обоих языках. Методы с implicit параметрами вы вызвать сможете, только передать их вручную придется. Единственное, что реально не вызываемо это макросы, но довольно логично, что библиотеки метапрограммирования на scala не вызывать из java, как inline методы котлина не вызвать снаружи.
Да, это не приятно. Но эта проблема на плечах разработчиков библиотек. sbt берет нужную версию автоматически. И на данный момент актуальных версий 2: 2.11 и 2.12.
Сам рантайм — нет. С доп. библиотеками — да. Решается через proguard.
Что вы подразумеваете под ростом скалы? Основной инструментарий (akka, play, slick, etc) развивается стабильно. Сама scala сейчас идет к версии 3.0 (см dotty). Проекты на scala — тут у меня выборки нет.
То есть какого-то общеупотребимого набора инструментов вроде lombok в C# нет?
А существование коммерческих решений для подобного — для меня это показывает разницу в мировоззрении. С тех пор как перешел на jvm я уже не могу себе представить платные решения для тивиальных действий — скорее приходится выбирать из нескольких свободных.
И передача по значению — не всегда хорошо. Но иногда полезно, особенно при размещении в массиве. В jvm структуры сейчас добавляют, но только в immutable варианте.
И Data class — класс с полноценными методами, который можно проксировать, инструментировать и извращаться всеми остальными способами. Иногда и это важно.