scala для чего применяется
Зачем нужен Scala?
Разбираем, почему это не самый популярный язык.
Встречали в вакансиях позицию разработчика на Scala? Это редкий зверь, но платят нормально. Разберёмся, что это такое и зачем нужно.
Разработчик языка рассчитывал, что Scala станет преемником Java: он наследует многое хорошее из Java, работает по схожим принципам и добавляет что-то своё. И хотя Scala не стал таким же распространённым, всё равно стоит понять, из чего он сделан.
Плюсы Scala
Scala, как и Java, работает под JVM — виртуальной машиной Java (Java Virtual Machine). JVM — это такая прослойка между программой и железом. Благодаря этой прослойке один и тот же код можно исполнить на чём угодно, для чего есть JVM: и на компьютере, и на терминале оплаты, и на умном холодильнике. Не нужно каждый раз думать: «А какие там драйверы экрана?» или «С какой скоростью работает сетевой шлюз?» — всё это берёт на себя JVM, а мы пишем только логику и интерфейс.
Минусы Scala
Но если всё было бы так просто, про Java все давно бы забыли, но этого не произошло. Более того, сейчас не так много Scala-вакансий на рынке, чтобы говорить о популярности этого языка. На это есть несколько причин:
Синтаксис
С точки зрения кода в Scala всё то же самое, что и в Java-языках, кроме некоторых ООП-особенностей, поэтому начнём с привычных деталей, а потом перейдём к отличиям.
Основы. Каждая команда заканчивается точкой с запятой, а присваивание и математические операторы такие же, как в Java и JavaScript.
Типов данных — много, как в любом типизированном языке. Как и в Ruby, каждый тип — это объект, который можно менять, добавлять в него новые методы.
Переменные. Объявляются с помощью служебных слов val и var, но разница между ними в Scala настолько размытая и непрозрачная, что иногда даже опытным разработчикам сложно понять, какое слово будет уместнее в каждой ситуации.
Условные операторы и циклы. Всё привычно — for, while и do-while, но с одним отличием: в цикле for применяется упрощённая запись для организации переменной цикла. Обратите внимание на код ниже — сколько танцев с бубном ради одного цикла, который сам занимает три строки (не считая комментария):
Кто и для чего использует Scala
У Scala нет явно выраженной области применения, как у некоторых других языков. С другой стороны, из-за объединения ООП и функционального программирования этот язык прижился в тех командах, которым нужно совмещать в работе оба подхода.
Второе преимущество — возможность запустить код в любом JVM-окружении, поэтому Scala выбирают те, кому нравится объектный подход, но не нравится то, как это сделано в Java.
Основные популярные фреймворки — Play и Lift, и их используют в основном СМИ и новостные сайты:
С чего начать
Если хотите изучить основы Scala и попробовать свои силы в объектно-ориентированном программировании в мире Java, то вот с чего можно начать.
Большая статья в RSDN Magazine — «Обзор языка программирования Scala». Хороший и понятный материал, но подан в сухом академическом стиле.
«Scala в примерах» в Викиучебнике — написано попроще, но без введения для новичков.
«Руководство по Scala» в Записках задумчивого программиста — просто, понятно, но иногда автор не даёт подробных объяснений тому, что происходит в коде.
Scala как первый язык
Эта статья, как и мой предыдущий пост, не похожа на то, что обычно публикуют на Хабре. Здесь не объясняется никаких новых или старых концепций, я не рассказываю что такое ООП и функциональное программирование, сложного кода почти нет. Я хочу пригласить вас к дискуссии стоит ли начинать программировать с языка Scala.
Меня иногда просят научить программированию или помочь с поиском подходящего курса. Я хорошо понимаю недостатки и сложности со скалой, но думаю, что Scala 3 — подходящий язык, для того чтобы начать обучение с него, если правильно составить курс. Вся языковая мощь и сложность, конечно, не нужны начинающему программисту, но ему и незачем о них знать. На скале можно писать вполне простой и понятный код, постепенно наращивая инструментарий.
Я согласен с теми комментаторами, кто считает что для этого нужен толковый преподаватель. Это безусловно. Или талантливый преподаватель, который разбирается в предмете, или хорошая книжка, или толковый курс просто необходимы. Иначе есть риск захлебнуться, так и не научившись плавать.
И тем не менее я считаю, что Scala — это язык будущего.
Лестница в логотипе отсылает к институту EPFL в Лозанне. Там придумали этот язык
Если коротко, то Scala — это возможность научиться функциональному программированию на безопасном языке, у которого есть большое будущее
Умный компилятор
У скалы один из самых умных и сложных компиляторов. Это приводит к медленным билдам (особенно в первых версиях языка), и за это скалу хейтят. Но зато мы можем отдать компилятору очень много работы по анализу кода, проверке его на безопасность и отсутствие ошибок, что очень важно для программиста. Эта сложность — на стороне разработчика, в том числе и начинающего, которому компилятор очень помогает и облегчает работу.
Скала — это единственный язык, где я пишу код, и он сразу работает без утомительной отладки. Конечно, так происходит не всегда, но с джавой, джаваскриптом, си, паскалем и бейсиком так не происходило никогда. Я люблю говорить, что джава — это язык для компилятора, а скала — это язык для программиста.
JVM-экосистема
Как известно, Джеймс Гослинг, создатель языка джава, считает самой лучшей ее частью джава-машину. Действительно, много инженеров потратило десятки человеко-лет на разработку виртуальной машины и достигли скоростей, в некоторых случаях превышающих Си++. Вот исследование производительности JVM в мобильных устройствах, в нем чаще побеждает нативный код на Си, но в одном случае победила JVM: Java vs C app performance.
На Android 6 AArch64 JVM победила Си в математических вычислениях, хотя и проиграла во всех других видах
Java Memory Model (Модель памяти для многопоточных вычислений) — это зрелая, непротиворечивая, проверенная многими годами промышленного программирования парадигма, которая при правильном использовании гарантирует достаточный уровень абстракции и безопасности. Благодаря этому возможны удобные конструкции для параллельного программирования, доступные даже начинающим.
Кроме того, на джаве написаны миллионы строк кода, которые вы можете использовать из скалы или без проблем в нее транслировать.
Кстати, Джеймсу Гослингу скала тоже нравится.
Но в этом всем есть и минусы. Как мы знаем, высокоуровневые абстракции протекают, и для того чтобы программировать на скале, важно знать как устроена виртуальная машина джава, и учитывать ее особенности. Например, такие как Type Erasure. Это довольно серьезный минус, но плюсы от использования JVM его перевешивают.
Эволюция vs революция
В экосистеме скалы приняты довольно слабые гарантии обратной совместимости по сравнению с джавой. С одной стороны, это приводит к тому, что разработчикам постоянно приходится поддерживать свой код в форме при переходе на новую версию языка или библиотек. Кроме того, разработчикам библиотек приходится прибегать к кросс-компиляции для того чтобы обеспечить несколько версий скомпилированных библиотек, подходящих для нескольких версий языка. Это, безусловно, минус.
Но с другой стороны такой подход обеспечивает быстрое и динамичное развитие языка, которое не может себе позволить джава. Именно поэтому я думаю что будущее — за скалой.
К тому же, в Scala 3 появилось типизированное абстрактное синтаксическое дерево компилятора TASTY, которое позволит взаимодействовать классам, собранным разными версиями компилятора. Разумеется, начинающим программистам нет нужды разбираться в этом.
Scala 3
Благодаря более слабым гарантиям обратной совместимости, разработчики языка получили возможность пересмотреть его основы, включая синтаксис.
Первоначальным посылом к созданию скалы было сделать язык промышленного уровня, на котором будет приятно программировать. Это действительно был большой шаг вперед.
Но некоторые решения, принятые более 15 лет назад, были неверными и приводили к неочевидному, либо многословному коду. И сейчас создатели языка делают его действительно лучше. После этих изменений шансы скалы в качестве первого языка программирования заметно вырастают.
Я уже пару лет с нетерпением жду его выхода и мечтаю начать писать на нём. Вот сжатый рассказ Мартина Одерски про новую версию языка: Countdown to Scala 3 by Martin Odersky. Для опытных разработчиков — интересная статья Annoying things in Scala 2 that’ll be (mostly) gone in Scala 3
Dependent Object Types — это теоретические основы языка Scala 3, разработанные его основателем Мартином Одерски. Мало какой язык может похвастать математически точным исчислением, лежащем в его основе.
Мартин Одерски
Согласитесь, приятно учить язык с таким бэкграундом, хотя начинающим программистам знать о нём не обязательно.
Выразительность и лаконичность
То, что я больше всего люблю в языке — это его сжатость и лаконичность. Я ненавижу длиннейшие конструкции джавы, в которых приходится сложно и многословно объяснять компилятору простые вещи. Моя любимая шутка про джаву — что это такой язык, в котором уан-лайнер занимает около 30 строк. Так вот, в скале уан-лайнер — это уан-лайнер.
Я думаю, что это качество важно не только для опытных разработчиков, но и для тех кто только изучает язык. Думаю, выразительность — это та причина, по которой так популярны динамические и скриптовые языки. Уверен, скала способна с ними в этом поспорить. И даже сама послужить отличным скриптовым языком.
Конечно, лаконичность не должна наносить ущерб читаемости кода. Таких неудачных примеров в программировании полно, вспомним регулярные выражения, паттерн-матчинг и парсер-комбинаторы. Понятно, что для написания библиотек важно понимать сложные концепции и знать много умных слов. Но для того, чтобы ими пользоваться и писать простой код, всего этого знать не надо. Минимальный уровень скалы, который подойдет начинающим, очень простой.
Вот мой любимый пример для библиотечного кода на скале. Конечно, он не предназначен для начинающих разработчиков:
В новой версии языка даже есть возможность писать намного меньше фигурных скобок, если есть желание. Это будет выглядеть примерно так:
Статическая типизация
По-моему это самое важное, что должно быть в первом языке программирования. Программисту важно понимать, что не стоит складывать яблоки с апельсинами.
Именно по этой причине на мой взгляд не стоит начинать обучение с Питона, Руби, Джаваскрипта, Си и Си++. Динамическая типизация — это верный способ выстрелить себе в ногу.
Другое дело, что статическая типизация неудобна, неочевидна и требует дополнительного бойлер-плейта. Скала вполне успешно позволяет избавиться от этих недостатков в простых программах.
Объектно-ориентированное программирование — это самая популярная парадигма, без которой не обходится ни один современный язык программирования.
В скале эта парадигма изначально присуща языку, в отличии от Питона, Си/Си++ и в каком-то смысле джаваскрипта. Разумеется, сейчас у этих языков с ООП полный порядок.
Функциональное программирование
Функциональное программирование — это многообещающая тенденция. Скале она присуща в не меньшей степени чем ООП, и они взаимно обогащают друг друга благодаря этому языку. Рискну предположить, что скала — первый язык промышленного уровня с такими свойствами. Сейчас за ним подтягивается Котлин и другие более новые языки.
Начинающим разработчикам стоит узнать про функциональное программирование подробнее, этот подход позволяет писать гибкий, надежный и хорошо масштабируемый код. Вот несколько хабропостов о нём:
Иммутабельность
Вообще-то это свойство функционального программирования. Мне кажется очень важным прививать умение пользоваться неизменяемыми структурами данных с самого начала. Это позволит в будущем создавать безопасный многопоточный код. И не только многопоточный.
Расширяемость
Как известно, название языка изначально преподносилось как аббревиатура Scalable Language. Особенности языка позволяют писать гибкие и красивые DSL, удобные даже для не-программистов, вкладывать абстракции друг в друга, создавать очень удобные библиотеки и простые скрипты.
Часто этот инструмент обращается против пользователей библиотек, повышая порог входа в их API. Но в умелых руках такая гибкость может обратиться в большое благо. Опытные разработчики могу создавать на Scala простое и удобное API, тем самым заметно облегчая жизнь начинающим программистам.
В целом язык скала предоставляет большое количество мощных инструментов, и обратная сторона этого — высокий порог входа, особенно в отсутствии хорошего курса, учебника, или наставника.
Но думаю, что с хорошим наставником или туториалом вполне можно начинать изучать программирование с языка скала и получать правильные привычки статической типизации, функционального программирования и иммутабельных структур данных.
Источник: https://prwatech.in/blog/apache-spark/introduction-to-scala-programming-language/
Рынок вакансий
Конечно, вакансий для скала-программистов значительно меньше, чем для джава-программистов. Но зато Scala выше оплачивается.
https://insights.stackoverflow.com/survey/2019
Вот вам картинка про области применения скалы:
Источник: https://prwatech.in/blog/apache-spark/introduction-to-scala-programming-language/
Мои первые книжки
Самая лучшая книжка про скалу, которую я читал — Scala by Example Мартина Одерски, написанная уже 10 лет назад. Прежде чем начинать сейчас читать книгу по скале, очень рекомендую убедиться что она обновлена до версии Scala 3.
А любимый курс — это Functional Programming in Scala, я проходил его в самой первой версии, с тех пор он, конечно, успел измениться. Первые уроки этого курса основываются все на той же Scala by Example. Сейчас команда курса работает над его обновлением.
Если вы хотите поиграть скалой или дотти, не устанавливая IDE — добро пожаловать в Scastie.
Пример кода
Много примеров короткого кода на скале можно найти вот в этом обсуждении: Samples of Scala and Java code where Scala code looks simpler/has fewer lines? Вот один из них:
Scala
Java 8
Java 7
Поступь прогресса
На прощанье — шутка Кея Хорстмана «The March of Progress»
1980: C
1988: C++
1996: Java
2004: Java
2008: Scala and Groovy
2012: Scala 2.10
На этом я рискну опубликовать этот пост, но по-прежнему планирую его дописывать по результатам обсуждения с вами.
Зачем человеку Scala?
Не так давно мы допечатали книгу Одерски, Спуна и Веннерса о Scala 2.12. Ведь до Scala 3 еще далеко.
Автор сегодняшней статьи — Адам Уорски, сооснователь компании «SoftwareMill» и опытный Scala-разработчик. У него получилось интересное резюме сильных сторон современного языка Scala, которое мы и предлагаем вашему вниманию.
После пленарной лекции Мартина Одерски на ScalaDays, где он изложил планы на Scala 3 и пленарной лекции Джона де Гоуса на конференции Scalapeño о будущем Scala в сообществе Scala продолжаются оживленные дискуссии. Не считая обсуждения этих пленарных выступлений, многочисленные дискуссии идут в twitter, в сообществах Slack, а также на reddit (см. напр. 1, 2).
Все это очень интересно и познавательно для специалистов, уже работающих в экосистеме Scala. Однако, значительная часть споров связана с различными интуитивно ощутимыми или фактическими недостатками Scala как языка. Эти моменты могут отпугивать людей «со стороны», вызывая у них вопросы: «А зачем мне вообще пользоваться Scala?», «А вдруг это тупиковый путь?», «Повторит ли Scala 3 успех Python 3?» и т.д. Как и в большинстве дискуссий, внимание приковывают самые слабые и эмоциональные тезисы, и эти дебаты — не исключение.
Поэтому сделаем шаг назад: зачем вам вообще мог бы потребоваться язык Scala? Каковы технические и деловые доводы в пользу работы с эти языком?
Предметная область проекта
Начнем с того, что язык Scala особенно хорош для определенных предметных областей (но не для всех!). Важнейшее достоинство Scala – это гибкость при определении абстракций. В вашем распоряжении – ряд простейших «кирпичиков» для этого; иногда определить абстракцию не сложнее, чем использовать класс, методы и лямбда-выражения. Иногда приходится использовать неявный параметр или метод расширения; в редких случаях остается только прибегать к макрокомандам. Однако, есть варианты.
Таким образом, Scala отлично вам подойдет, если требуется сориентироваться в сложной предметной области. Например, речь может идти о распределенном или конкурентном программировании. Наладить параллелизм очень сложно, а в Scala есть ряд библиотек, упрощающих эту задачу путем построения абстракций. Для этого существует два основных подхода: акторный, реализуемый при помощи Akka, и в духе FP, представленный Monix/cats-effect и Scalaz/ZIO (если бы вы хотели подробнее почитать о сравнении этих инструментов – я написал серию статей как раз на эту тему).
Однако, разумеется, речь может идти и о других предметных областях. Возможности Scala также позволяют вывести на новый уровень моделирование типичных бизнес-приложений. Но в данном случае речь уже о сложности другого порядка. В случае с распределенными системами мы сталкиваемся с технической сложностью. При программировании бизнес-логики в приложениях речь идет уже о сложности предметной области как таковой. Например, в книге Дебасиша Гхоша (Debasish Ghosh) “Functional and reactive domain modeling” объясняется, как совместить DDD с функциональным и реактивным программированием.
Отметим: рассказывая о Scala, все любят подчеркивать широту возможностей этого языка, подчеркивая, что именно по причине такой разносторонности этот язык столь сложен. Это не совсем верно.
Как упоминалось выше, в Scala есть ряд базовых конструкций, из которых можно собирать абстракции. Однако, все их можно комбинировать друг с другом, благодаря чему язык и приобретает такую гибкость. Большинство новаторских проектов, которые могут вам попадаться, сводятся к тем или иным сочетаниям типов высшего порядка, неявных параметров и выделения подтипов.
Таким образом, при относительно небольшом количестве базовых возможностей (по размеру грамматики Scala проще Kotlin, Java или Swift!) — что, в свою очередь, облегчает обучение – варианты комбинаций гораздо многочисленнее.
Не слишком ли широкий выбор? Не думаю. Программист, как компетентный и ответственный профессионал, более чем в состоянии выбрать наилучший вариант, чтобы решить конкретную задачу. Подробнее об этом см. в статье “Простой стек Scala”.
Сейчас много говорят, что Kotlin вытеснил Scala в качестве “как Java, только лучше”. Но я считаю, что именно Scala, а не Kotlin, по-прежнему заслуживает такого звания. На то есть две основные причины:
Что такое типы классов? Роль их примерно такова, как у паттернов проектирования в Java, однако, они более гибкие и простые в использовании, как только вы крепко усвоите их смысл. По этому поводу есть несколько отличных руководств, например, 1, 2.
Естественно, и у Scala, и у Kotlin есть ряд общих преимуществ по сравнению с Java, например:
В то же время, оба языка открывают доступ к экосистеме библиотек и фреймворков JVM.
Чем насыщеннее система типов (в Scala она богаче, чем в Kotlin, а в Kotlin – богаче чем в Java), тем больше работы по верификации выполняется компилятором, а не человеком. Именно для этого и созданы компьютеры: выполнять скучные, рутинные повторяющиеся задачи. Проверка применимости типов – определенно, как раз одна из таких задач.
При этом насыщенная система типов полезна не только при написании кода, но и, в гораздо большей степени при чтении кода. Когда тебе легко сориентироваться в базе кода, понять, что он делает, а, к тому же, не страшно (или не так страшно) браться за его рефакторинг, это очень положительно характеризует язык как с технической, так и с прикладной точки зрения.
Еще один вопрос, часто поднимаемый в таких дискуссиях – должен ли язык Scala и далее придерживаться синтеза ООП и ФП, либо развиваться по чисто функциональному пути. Я – сторонник синтеза, особенно потому, что ФП и ООП на мой взгляд – не альтернативные подходы, а дополняющие друг друга.
ФП – это программирование при помощи функций, правда, не любых, а референциально прозрачных (см. этот ответ на reddit в более раннем треде, где превосходно объясняется референциальная прозрачность). В ООП коммуникация с объектами организована при помощи “сообщений” или, в нашей терминологии, вызовов виртуальных методов. Нет ни одной причины, по которой два этих подхода не могли бы сосуществовать, и Scala это уже продемонстрировал!
В твите о достоинствах Scala Джон де Гоус упоминает некоторые черты ООП, полезные и при чисто функциональном подходе, в частности, модули первого класса (получаемые путем композиции объектов), точечный синтаксис (вызов методов в объектах) и классы/экземпляры типов как конструкции первого класса. Все это – элементы успешной комбинации двух парадигм. Может быть, еще какие-то не за горами?
Проект «синтеза» еще не закончен, здесь определенно остается поле для обсуждения. Один из незавершенных аспектов – это предлагаемый синтаксис методов расширения, который должен прийти на смену гораздо более путаным неявным преобразованиям. Другой – оптимизация синтаксиса классов типов; предложение по этому поводу, высказанное некоторое время назад, явно сырое и не охватывает некоторые из наиболее распространенных случаев использования монад в Scala. Некоторые предложения лучше, другие требуют доработки, но хорошо, что они поступают, и о них идут дискуссии; благодаря ним язык живет и, в конечном счете, в нем закрепляется наилучшее решение.
Scala 3 выйдет через два года. В нем появится ряд интересных возможностей, в частности, непрозрачные типы, параметры типажей, новый подход, связанный с метапрограммированием, типы объединения и & пересечения, неявные типы функций – вот всего несколько примеров. Конечно, здесь возникает (обоснованная) обеспокоенность по поводу миграции.
Уже известно, что будет представлен специальный инструмент для автоматической миграции кода со Scala 2 на Scala 3 при помощи scalafix. Поскольку Scala – статически типизированный язык, такая задача решаема в больших масштабах и гораздо проще, чем, например, на Python. Но, разумеется, никакой магии тут нет: даже если этот инструмент на 99% обеспечит правильное покрытие кода, все равно останется 1% наиболее проблемных случаев. Поскольку на магию рассчитывать не приходится, миграцию этих фрагментов нужно будет выполнить вручную.
Таковы издержки работы с активно развивающимся языком: вы получаете новейшие возможности, но некоторые из них на поверку оказываются не столь хороши и нуждаются в доработке. Даже с учетом этого, предлагаемые изменения не являются революционными. Язык Scala 3 очень похож на Scala 2, никаких серьезных изменений парадигмы не предвидится.
Обнадеживает тот факт, что команда Scala всерьез подходит к миграции. Тогда как ранее миграция между старшими версиями Scala (напр. с 2.8 на 2.9) была довольно обременительна, последние миграции прошли гораздо лучше. В них участвуют три основных стороны: EPFL, ScalaCenter и Lightbend все они (зачастую вместе) работают на облегчение миграции. Например, существует двоично-совместимый инструмент MIMA, а также в сообществе постоянно создаются многочисленные новые библиотеки, призванные обеспечить удобную работу с новыми версиями Scala.
Наконец, пока не законченный инструмент TASTY (который, соответственно, пока нельзя оценить) должен обеспечить использование двоичных файлов из Scala 2 в Scala 3.
Итак, зачем же использовать Scala?
Итак, каковы же причины остановиться на Scala, если рассматривать этот язык с точки зрения бизнеса? Все вышеперечисленные технические преимущества напрямую полезны и для бизнеса. Когда у вас есть язык, на котором можно писать сложный код с меньшим количеством багов – то вам обеспечены и минимальные задержки сроков, и довольные пользователи. Если вы станете писать на Scala мощные, практически не пробуксовывающие конкурентные приложения, для которых в Scala предусмотрены специальные инструментарии, то это обернется серьезной выгодой для вашей компании.
Кроме того, не забываем и о Spark, ведущей платформе для распределенного анализа данных. Scala используется не только для реализации Spark как такового, но и для определения самих вычислений. Вот вам еще одна data science-ориентированная абстракция, скрывающая сложную вычислительную модель.
Разумеется, в Scala есть и проблемы, но где их нет? Повод для оптимизма заключается в том, что множество людей, использующих Scala ежедневно, активно работают над улучшением инструментария, библиотек и самого языка. Могу предположить, что они продолжают работать со Scala именно потому, что, при всех имеющихся недоработках, ни один язык так хорошо не подходит для их предметной области.
Scala позволяет вам развивать свой стиль программирования, каким бы языком вы раньше ни занимались: Java, Ruby или только пробуете себя в программировании. Не существует однозначно выигрышного подхода к Scala; можно придерживаться или более императивного подхода Akka, или более функционального подхода Cats и Scalaz.
Вот где можно усмотреть проблему: в сообществе Scala есть фракции, придерживающиеся “реактивного”, “синтетического” OOП/ФП подхода и чистого ФП. Однако, на самом деле в этом заключается огромное преимущество. Благодаря такому разнообразию ведутся дискуссии, высказывается множество различных мнений с разных точек зрения. На этом, в свою очередь, отлично можно выучиться нестандартному решению задач и обогатить собственный инструментарий.
Какой бы путь в Scala вы ни выбрали, вас поддержит внушительное сообщество коллег, занимающихся разработкой библиотек и фреймворков; эти люди всегда готовы помочь и обсудить возникающие идеи.