Прекрасне сьогодення і світле майбутнє Scala

image
Зовсім недавно на Хабре з'явилася стаття, яка дає не зовсім вірне уявлення про поточний стан речей в Scala-співтоваристві. У читача створюється помилкове враження про застій та загнивання в екосистемі Scala. У цій статті я хотів би виправити це і розповісти про нещодавно вийшли новинки і майбутні зміни.

У травні 2016 році на конференції Scala Days в Нью-Йорку Мартіном Одерски була представлена презентація, описує сьогодення та майбутнє мови Scala.

Scala 2.12
У листопаді 2016 року вийшла нова версія компілятора Scala 2.12, в якій трейты компілюються прямо в Java-інтерфейси з дефолтними методами, а лямбда-функції в Scala і Java стали повністю сумісними, так що тепер їх можна викликати в обох напрямках однаково зручно. Також це сприяло поліпшенню продуктивності Scala-коду на JRE 8.

Scala 2.13
На новий реліз комилятора scalac намічений рефакторинг стандартної бібліотеки. Особливу увагу буде приділено колекціям і можливо стандартна бібліотека буде розділена на компактне ядро і платформу, в яку увійде все, що не потрапило в ядро. Здається, ніби, розробка scalac буксує на місці. Можливо, це частково правда, бо сама мякотка розробляється зараз для нового компілятора Scala, охрещеного Dotty в честь теорії залежних типів, на якій він заснований.

Scala Dotty
Розробка нового компілятора ведеться вже кілька років силами команди EPFL, очолюваної Мартіном Одерски. Крім нього в ядро команди входить ще 5 чоловік, включаючи хабровчанина Дмитра Петрашко aka darkdimius. Основною для нової версії мови є Dependent Object Types calculus, розроблений Мартіном Одерски спеціально для потреб Scala.

З-за нової структури компілятора, суть якої пояснюється відео, швидкість компіляції вже вдвічі швидше, ніж у scalac. І це ще при обліку того, що розробники ще навіть не приступали до оптимізації компілятора. Так що все вже застарілі на даний момент міфи про незручність гальмівний компіляції Scala будуть остаточно розвінчані.

У Dotty буде оновлена система типів, будуть прибрані невикористані можливості мови. Багато речей будуть сильно спрощені. Але це все абстрактні слова. Давайте швидше перейдемо до прикладів.

Спочатку пройдемося по тому, що прибрали за непотрібністю.

  • Процедурний синтаксис
  • Класи з DelayedInit
  • Макроси, засновані на рефлексії
  • Рання ініціалізація трейтов
  • Екзистенційні типи
  • Проекції узагальнених типів
  • XML-вставки в код
Замість цього всього були додані нові улученные фічі:

  • Тепер замість with тип змінної додані типу-перетину

    val a : A & B

  • Тепер замість проблем з Either у нас є типи-об'єднання. У змінної може зберігатися або тип А або тип B. Це усуває купу бойлерплейта

    val a : A | B

  • Нарешті виправлені тюплы в лямбда-вирази.

    
    //
    val numbersAndLetters = List((1,"A"), (2,"B"))
    numbersAndLetters.map {
    case (number, letter) => ...
    }
    //Стало
    numbersAndLetters.map((number, letter) => ...)
    

  • трейтах можна оголошувати параметри

    
    trait WithParameter(name:String) {
    ...
    }
    

  • Оператори рівності == і нерівність != тепер типобезопасны
  • Параметрам-типами стало можна присвоювати імена. Стала можлива часткова параметризація.

    
    trait Map[type Key, Value type]
    Map[Key = Int]
    
В поточному вигляді компілятор dotc можна випробувати на це тестовому проекті. У майбутньому ж обіцяно додати в мову нових можливостей.

  • Неявні функціональні типу

    
    type CtxS = implicit Context => S
    def f(x:T):CtxS = {
    ... implicitly[Context] ...
    }
    f(e) //Context argument is passed implicitly
    

  • Поряд зі звичайними функціями з'являться ефекти, що гарантують чистоту

    
    A => B (can be impure)
    A -> B (pure)
    

  • Звичайні типи не зможуть бути null по дефолту. Значення, що прийшли з Java-коду завжди будуть опціональними.

    
    T? = T | Null
    val stream: PrintStream? = System.out.printStream
    

  • Магічне число 22 більше не буде лякати Scala розробників. Tuple22/Function22/Product22 стануть історією

    
    type (S, T, U) = (S (T, (U, Unit)))
    

  • Новий тип даних records. Щось типу тюплов з іменами. Приклад коду немає. Це поки що самий містичний концепт з представлених.

Також в Dotty спроектована система Tasty, що дозволяє не перекомпілювати бібліотеки під кожну версію компілятора, що було проблемним в Scala 2. І в порівнянні з другою версією Scala в Dotty обіцяють зробити хороші пояснення помилок при компіляції.

Dotty Linker
Вінцем на короні Dotty є Linker, розробляється Дмитром Петрашко. Це оптимізатор, що дозволяє компілювати код виключно для тих типів, які реально використовуються. Це дозволяє домогтися серйозного зменшення кількості коду і збільшення продуктивності. З допомогою лінкера сильно покращується навіть продуктивність підключаються бібліотек. Детальніше про це диво-оптимізаторі можна дізнатися в відео.

Scala meta
Замість старих макросів виходять нові зручні Scala Meta макроси, разрабатываемыемые Євгеном Бурмако. Поки що вони вийшли тільки для Scala 2.11 і тільки для анотацій, але не методів. Але вже можна сказати, що вони вийшли набагато зручніше попередньої версії. Тепер оголошення макросу та його імплементація не розділені, а робота з синтаксичними деревами просто чудова. Також scala.meta працюють із вихідними деревами, а не з вже злегка перетвореними як макроси, засновані на старій scala.reflect.
Детальніше про них можна почитати в цьому туториале.

Scala JS
Scala.js компілює код на Scala високопродуктивний Javascript код. Разом з Scalatags і ScalaCSS стає можлива повноцінна розробка веб-фронтенда. Величезним плюсом є можливість розшарювати сутності між клієнтом і сервером, і використовувати замість явного визначення HTTP API, віддалений виклик процедур. В останні кілька років з'явилося кілька добре налагоджених і використовуються в продакшені фреймворків з реактивними биндингами зразок Udash. Багато розробники використовують Scala.js, так як не хочуть мучитися з динамічним і «дивним» JS. Наведу приклад, використовуваний в офіційній документації.

javascript> ["10", "10", "10", "10"].map(parseInt)
[10, NaN, 2, 3] // What???
scala> List("10", "10", "10", "10").map(parseInt)
List(10, 10, 10, 10) // that's it 

Scala Native
Нещодавно вийшов Scala Native — компілятор в нативний бінарники, заснований на LLVM. Це дозволяє писати на Scala надшвидкий миттєво запускається код і використовувати галузеві структури даних.

Macroid і RoboScala
Так як Scala компілюється в Java код, то є можливим використання цієї мови для розробки під Android. Для цього існує спеціалізована библеотека Macroid, надає зручний для використання Android API. Так само існує можливість скомпілювати Scala код з IOS з допомогою RoboScala — обгортки навколо RoboVM

ScalaFX
Для розробки десктопного софта існує бібліотека ScalaFX, є обгорткою навколо відомої JavaFX.

Висновок
Хоч стаття і вийшла сильно сумбурною, але вона може послужити хорошим списком посилань на різні інструменти компіляції Scala під різні платформи, і джерелом інформації про майбутніх подіях і фичах. Всі представлені в статті інструменти і компілятори активно розробляються, поліпшуються і використовуються. Так що говорити про якийсь застій або навіть занепаді в екосистемі Scala не доводиться.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.