Scala (язык программирования) - Scala (programming language)

Scala
Scala-полноцветный.svg
ПарадигмаМультипарадигма: одновременный, функциональный, императив, объектно-ориентированный
РазработаноМартин Одерский
РазработчикЛаборатория методов программирования Федеральная политехническая школа Лозанны
Впервые появился20 января 2004 г.; 16 лет назад (2004-01-20)
Стабильный выпуск
2.13.4 / 19 ноября 2020; 17 дней назад (2020-11-19)[1]
Печатная дисциплинаПредполагаемый, статический, сильный, структурный
Язык реализацииScala
Платформа
ЛицензияЛицензия Apache 2.0[2]
Расширения имени файла.scala, .sc
Интернет сайтwww.scala-lang.org
Под влиянием
Common Lisp,[3] Эйфель, Erlang, Haskell,[4] Ява,[5] OCaml,[5] Унция, Пицца,[6] Схема,[5] Болтовня, Стандартный ML[5]
Под влиянием
Цейлон, Фантом, F #, Котлин, Лассо, Красный
  • Scala в Викиучебнике

Scala (/ˈskɑːлɑː/ СКАХ-ла )[7] это язык программирования общего назначения обеспечение поддержки как объектно-ориентированного программирования и функциональное программирование. В языке есть сильный статический система типов. Создан лаконичным,[8] многие дизайнерские решения Scala направлены на критика Java.[6]

Исходный код Scala предназначен для компиляции в Байт-код Java, так что полученный исполняемый код запускается на Виртуальная машина Java. Scala предоставляет языковая совместимость с участием Ява, так что на библиотеки, написанные на любом языке, можно ссылаться непосредственно в коде Scala или Java.[9] Как и Java, Scala объектно-ориентированный, и использует синтаксис фигурных скобок напоминает Язык программирования C. В отличие от Java, Scala имеет множество функций: функциональное программирование языки как Схема, Стандартный ML и Haskell, в том числе карри, неизменность, ленивая оценка, и сопоставление с образцом. Он также имеет расширенную систему типов, поддерживающую алгебраические типы данных, ковариация и контравариантность, типы высшего порядка (но нет высшие типы ), и анонимные типы. Другие функции Scala, отсутствующие в Java, включают перегрузка оператора, необязательные параметры, именованные параметры, и сырые струны. И наоборот, функция Java не в Scala проверенные исключения, что оказалось спорным.[10]

Название Scala - это воплощение масштабируемый и язык, что означает, что он разработан, чтобы расти вместе с требованиями пользователей.[11]

История

Разработка Scala началась в 2001 г. École Polytechnique Fédérale de Lausanne (EPFL) (в Лозанна, Швейцария ) от Мартин Одерский. Он стал продолжением работы над Funnel, языком программирования, сочетающим идеи функционального программирования и Сети Петри.[12] Одерский раньше работал над Общая Java, и javac, Компилятор Java от Sun.[12]

После внутреннего выпуска в конце 2003 г. Scala была публично выпущена в начале 2004 г. на Платформа Java,[13][6][12][14] Вторая версия (v2.0) вышла в марте 2006 года.[6]

17 января 2011 года команда Scala выиграла пятилетний исследовательский грант на сумму более 2,3 миллиона евро от Европейский исследовательский совет.[15] 12 мая 2011 года Одерский и его сотрудники основали компанию Typesafe Inc. (позже переименованную в Lightbend Inc. ), компания, предоставляющая коммерческую поддержку, обучение и услуги для Scala. В 2011 году компания Typesafe получила инвестиции в размере 3 млн долларов США от Greylock Partners.[16][17][18][19]

Платформы и лицензия

Scala работает на Платформа Java (Виртуальная машина Java ) и совместим с существующими Ява программы.[13] Так как Android приложения обычно написаны на Java и переведены из байт-кода Java в Дальвик байт-код (который в дальнейшем может быть переведен в машинный код во время установки) в пакете, совместимость Scala с Java делает его хорошо подходящим для разработки под Android, тем более когда предпочтителен функциональный подход.[20]

Эталонный дистрибутив программного обеспечения Scala, включая компилятор и библиотеки, выпущен под Лицензия Apache.[21]

Другие компиляторы и цели

Scala.js - это компилятор Scala, который компилируется в JavaScript, что позволяет писать программы Scala, которые можно запускать в веб-браузерах или Node.js.[22] Компилятор находился в разработке с 2013 года, а в 2015 году он был объявлен не экспериментальным (v0.6). Версия v1.0.0-M1 была выпущена в июне 2018 года. В сентябре 2020 года это версия 1.1.1.[23]

Scala Native - это Scala компилятор который нацелен на LLVM инфраструктура компилятора для создания исполняемого кода, который использует облегченную управляемую среду выполнения, которая использует Сборщик мусора Boehm. Проект возглавляет Денис Шабалин, его первая версия, 0.1, была выпущена 14 марта 2017 года. Разработка Scala Native началась в 2015 году с целью быть быстрее, чем своевременная компиляция для JVM, исключив начальную компиляцию кода во время выполнения, а также предоставив возможность напрямую вызывать собственные процедуры.[24][25]

Эталонный компилятор Scala, ориентированный на .NET Framework и это общеязыковая среда выполнения был выпущен в июне 2004 г.,[12] но был официально прекращен в 2012 году.[26]

Примеры

Пример "Hello World"

В Программа Hello World написанный на Scala, имеет такую ​​форму:

 объект Привет мир расширяет Приложение {   println("Привет мир!") }

в отличие от автономное приложение Hello World для Java, нет объявления класса и ничего не объявляется статическим; а одиночный объект создан с объект вместо этого используется ключевое слово.

Когда программа хранится в файле HelloWorld.scala, пользователь компилирует его с помощью команды:

$ scalac HelloWorld.scala

и запускает его с

$ scala HelloWorld

Это аналогично процессу компиляции и выполнения кода Java. Действительно, модель компиляции и выполнения Scala идентична модели Java, что делает ее совместимой с инструментами сборки Java, такими как Apache Ant.

Более короткая версия программы "Hello World" на Scala:

println("Привет мир!")

Scala включает интерактивную оболочку и поддержку сценариев.[27] Сохранено в файле с именем HelloWorld2.scala, это можно запустить как сценарий без предварительной компиляции, используя:

$ scala HelloWorld2.scala

Команды также можно вводить непосредственно в интерпретаторе Scala, используя параметр -e:

$ scala -e 'println ("Привет, мир!")'

Выражения можно вводить интерактивно в REPL:

$ ScalaДобро пожаловать в Scala 2.12.2 (64-разрядная серверная виртуальная машина Java HotSpot ™, Java 1.8.0_131).Введите выражения для оценки. Или попробуйте: помогите.scala> Список (1, 2, 3) .map (x => x * x)res0: List [Int] = List (1, 4, 9)scala>

Базовый пример

В следующем примере показаны различия между синтаксисом Java и Scala:

// Ява:int mathFunction(int число) {    int numSquare = число*число;    вернуть (int) (Математика.cbrt(numSquare) +      Математика.журнал(numSquare));}
// Scala: прямое преобразование из Java// импорт не требуется; scala.math// уже импортировано как `math`def mathFunction(число: Int): Int = {  вар numSquare: Int = число*число  вернуть (математика.cbrt(numSquare) + математика.журнал(numSquare)).    asInstanceOf[Int]}
// Scala: более идиоматический// Использует вывод типа, опускает оператор return,// использует метод `toInt`, объявляет неизменяемым numSquareимпорт math._def mathFunction(число: Int) = {  вал numSquare = число*число  (cbrt(numSquare) + журнал(numSquare)).toInt}

Некоторые синтаксические различия в этом коде:

  • Scala не требует точки с запятой в конце операторов.
  • Типы значений пишутся с заглавной буквы: Int, Double, Boolean вместо того интервал, двойной, логический.
  • Типы параметров и возвращаемых значений следующие, как в Паскаль, а не предшествовать, как в C.
  • Методы должны предшествовать def.
  • Перед локальными переменными или переменными класса должен стоять вал (указывает на неизменный переменная) или вар (указывает на изменчивый переменная).
  • В вернуть оператор не нужен в функции (хотя и разрешен); значение последнего выполненного оператора или выражения обычно является значением функции.
  • Вместо оператора приведения Java (Тип) foo, Scala использует foo.asInstanceOf [Тип], или специализированная функция, такая как удвоить или toInt.
  • Вместо Java import foo. *;, Scala использует import foo._.
  • Функция или метод foo () можно также назвать просто фу; метод thread.send (знак) можно также назвать просто поток отправить знак; и метод foo.toString () можно также назвать просто foo toString.

Эти синтаксические ослабления предназначены для поддержки предметно-ориентированные языки.

Некоторые другие основные синтаксические отличия:

  • Ссылки на массивы записываются как вызовы функций, например. массив (я) скорее, чем массив [я]. (Внутри Scala первый расширяется до array.apply (i), который возвращает ссылку)
  • Универсальные типы записываются как, например, Список [Строка] а не Java Список .
  • Вместо псевдотипа пустота, Scala имеет актуальную одноэлементный класс Единица измерения (см. ниже).

Пример с классами

В следующем примере сравнивается определение классов в Java и Scala.

// Ява:общественный класс Точка {  частный окончательный двойной Икс, у;  общественный Точка(окончательный двойной Икс, окончательный двойной у) {    этот.Икс = Икс;    этот.у = у;  }  общественный Точка(    окончательный двойной Икс, окончательный двойной у,    окончательный логический addToGrid  ) {    этот(Икс, у);    если (addToGrid)      сетка.Добавить(этот);  }  общественный Точка() {    этот(0.0, 0.0);  }  общественный двойной getX() {    вернуть Икс;  }  общественный двойной GetY() {    вернуть у;  }  двойной distanceToPoint(окончательный Точка Другой) {    вернуть distanceBetweenPoints(Икс, у,      Другой.Икс, Другой.у);  }  частный статический Сетка сетка = новый Сетка();  статический двойной distanceBetweenPoints(      окончательный двойной x1, окончательный двойной y1,      окончательный двойной x2, окончательный двойной y2  ) {    вернуть Математика.гипотеза(x1 - x2, y1 - y2);  }}
// Scalaкласс Точка(    вал Икс: Двойной, вал у: Двойной,    addToGrid: Булево = ложный) {  импорт Point._  если (addToGrid)    сетка.Добавить(этот)  def этот() = этот(0.0, 0.0)  def distanceToPoint(Другой: Точка) =    distanceBetweenPoints(Икс, у, Другой.Икс, Другой.у)}объект Точка {  частный вал сетка = новый Сетка()  def distanceBetweenPoints(x1: Двойной, y1: Двойной,      x2: Двойной, y2: Двойной) = {    математика.гипотеза(x1 - x2, y1 - y2)  }}

В приведенном выше коде показаны некоторые концептуальные различия между обработкой классов Java и Scala:

  • В Scala нет статических переменных или методов. Вместо этого он одиночные объекты, которые по сути являются классами только с одним экземпляром. Объекты-одиночки объявляются с использованием объект вместо того класс. Обычно статические переменные и методы помещаются в одноэлементный объект с тем же именем, что и имя класса, который затем известен как сопутствующий объект.[13] (Базовый класс для одноэлементного объекта имеет $ добавлено. Следовательно, для класс Foo с сопутствующим объектом объект Foo, под капотом есть класс Foo $ содержащий код сопутствующего объекта, и один объект этого класса создается с использованием одноэлементный образец.)
  • Вместо параметров конструктора в Scala есть параметры класса, которые размещаются в классе подобно параметрам функции. При объявлении с вал или вар модификатор, поля также определяются с тем же именем и автоматически инициализируются из параметров класса. (Под капотом внешний доступ к общедоступным полям всегда осуществляется через методы доступа (получатель) и мутатор (установщик), которые создаются автоматически. Функция доступа имеет то же имя, что и поле, поэтому в приведенном выше примере нет необходимости явно объявлять методы доступа.) Обратите внимание, что альтернативные конструкторы также могут быть объявлены, как в Java. Код, который войдет в конструктор по умолчанию (кроме инициализации переменных-членов) происходит непосредственно на уровне класса.
  • Видимость по умолчанию в Scala общественный.

Особенности (применительно к Java)

Scala имеет ту же модель компиляции, что и Ява и C #, а именно раздельная компиляция и загрузка динамического класса, чтобы код Scala мог вызывать библиотеки Java.

Рабочие характеристики Scala такие же, как у Java. Компилятор Scala генерирует байт-код, почти идентичный тому, который генерируется компилятором Java.[13] Фактически, код Scala может быть декомпилированный в читаемый код Java, за исключением некоторых операций конструктора. К Виртуальная машина Java (JVM), код Scala и код Java неотличимы. Единственное отличие - одна дополнительная библиотека времени выполнения, scala-library.jar.[28]

Scala добавляет большое количество функций по сравнению с Java и имеет некоторые фундаментальные отличия в своей базовой модели выражений и типов, которые делают язык теоретически более чистым и устраняют несколько угловые случаи в Java. С точки зрения Scala это практически важно, потому что несколько дополнительных функций Scala доступны также и в C #. Примеры включают:

Синтаксическая гибкость

Как упоминалось выше, Scala обладает значительной синтаксической гибкостью по сравнению с Java. Ниже приведены некоторые примеры:

  • Точки с запятой не нужны; строки автоматически соединяются, если они начинаются или заканчиваются маркером, который обычно не может стоять в этой позиции, или если есть незакрытые круглые скобки или скобки.
  • В качестве инфиксного оператора можно использовать любой метод, например "% d яблоки" .format (число) и Формат числа "% d яблок" эквивалентны. Фактически, такие арифметические операторы, как + и << обрабатываются так же, как и любые другие методы, поскольку имена функций могут состоять из последовательностей произвольных символов (за некоторыми исключениями, сделанными для таких вещей, как скобки, скобки и скобки, которые должны обрабатываться особым образом); единственная особая обработка, которой подвергаются такие методы с именами символов, касается обработки приоритета.
  • Методы применять и Обновить имеют синтаксические краткие формы. foo ()-где фу является значением (одноэлементный объект или экземпляр класса) - сокращение от foo.apply (), и foo () = 42 это сокращение от foo.update (42). Так же, фу (42) это сокращение от foo.apply (42), и foo (4) = 2 это сокращение от foo.update (4, 2). Это используется для классов коллекций и распространяется на многие другие случаи, такие как СТМ клетки.
  • Scala различает no-parens (def foo = 42) и пустые скобки (def foo () = 42) методы. При вызове метода с пустыми скобками скобки можно опустить, что полезно при вызове библиотек Java, которые не знают этого различия, например, используя foo.toString вместо того foo.toString (). По соглашению метод должен быть определен с пустыми скобками, когда он выполняет побочные эффекты.
  • Имена методов заканчиваются двоеточием (:) ожидайте аргумента слева и получателя справа. Например, 4 :: 2 :: ноль такой же как Нет .::(2).::(4), первая форма визуально соответствующая результату (список с первым элементом 4 и вторым элементом 2).
  • Переменные тела класса могут быть прозрачно реализованы как отдельные методы получения и установки. Для trait FooLike {var bar: Int}, реализация может быть объект Фу расширяет FooLike { частный вар Икс = 0; def бар = Икс; def bar_ =(ценность: Int) { Икс = ценность }} } }. Сайт для звонков по-прежнему сможет использовать краткий foo.bar = 42.
  • В вызовах методов разрешено использование фигурных скобок вместо круглых. Это позволяет реализовать новые управляющие структуры в чистом виде.[29] Например, breakable {... if (...) break () ...} выглядит как будто хрупкий было ключевым словом, определенным языком, но на самом деле это просто метод, thunk аргумент. Методы, которые принимают преобразователи или функции, часто помещают их во второй список параметров, позволяя смешивать круглые скобки и синтаксис фигурных скобок: Vector.fill (4) {math.random} такой же как Vector.fill (4) (math.random). Вариант фигурных скобок позволяет выражению занимать несколько строк.
  • For-выражения (объясненные ниже) могут содержать любой тип, который определяет монадические методы, такие как карта, flatMap и фильтр.

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

Единая система типов

В Java проводится четкое различие между примитивными типами (например, int и логический) и ссылочные типы (любые класс ). Только ссылочные типы являются частью схемы наследования, производной от java.lang.Object. В Scala все типы наследуются от класса верхнего уровня Любые, чьи ближайшие дети AnyVal (типы значений, такие как Int и Булево) и AnyRef (ссылочные типы, как в Java). Это означает, что различие Java между примитивными типами и упакованными типами (например, int vs. Целое число) отсутствует в Scala; упаковка и распаковка полностью прозрачны для пользователя. Scala 2.10 позволяет пользователю определять новые типы значений.

Фор-выражения

Вместо Java »для каждого "циклы для прохождения итератора, в Scala есть для-выражения, похожие на составить список в таких языках, как Haskell, или сочетание понимания списков и генератор выражений в Python. For-выражения, использующие Уступать ключевое слово разрешить новый коллекция будет сгенерирован путем перебора существующей коллекции с возвратом новой коллекции того же типа. Они переводятся компилятором в серию карта, flatMap и фильтр звонки. куда Уступать не используется, код приближается к циклу императивного стиля, переводя в для каждого.

Простой пример:

вал s = для (Икс <- 1 к 25 если Икс*Икс > 50) Уступать 2*Икс

Результатом его запуска будет следующий вектор:

Вектор (16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50)

(Обратите внимание, что выражение От 1 до 25 не является специальным синтаксисом. Метод к скорее определен в стандартной библиотеке Scala как метод расширения целых чисел с использованием техники, известной как неявные преобразования.[30] что позволяет добавлять новые методы к существующим типам.)

Более сложный пример перебора карты:

// Учитывая карту, определяющую пользователей Twitter, упомянутых в наборе твитов,// и сколько раз был упомянут каждый пользователь, найдите пользователей// в карте известных политиков и вернуть новую карту, содержащую только// Демократические политики (как объекты, а не строки).вал dem_mentions = для {    (упомянуть, раз) <- упоминает    учетная запись          <- учетные записи.получить(упомянуть)    если учетная запись.партия == "Демократический"  } Уступать (учетная запись, раз)

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

Функциональные тенденции

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

Примеры:

Все является выражением

В отличие от C или Java, но похож на такие языки, как Лисп, Scala не делает различий между операторами и выражениями. Фактически, все операторы являются выражениями, которые дают некоторое значение. Функции, которые будут объявлены как возвращающие пустота в C или Java и такие операторы, как в то время как которые логически не возвращают значение, в Scala считается, что они возвращают тип Единица измерения, что является одиночный тип, только с одним объектом этого типа. Функции и операторы, которые вообще никогда не возвращаются (например, бросить оператор или функция, которая всегда завершается нелокально с использованием исключения) логически имеют тип возврата Ничего, особый тип, не содержащий объектов; это нижний тип, т.е. подкласс всех возможных типов. (Это, в свою очередь, делает тип Ничего совместим со всеми типами, что позволяет вывод типа для правильного функционирования.)

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

// Ява:int hexDigit = Икс >= 10 ? Икс + 'А' - 10 : Икс + '0';
// Scala:вал hexDigit = если (Икс >= 10) Икс + 'А' - 10 еще Икс + '0'

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

Чтобы было ясно, что все функции являются выражениями, даже методы, возвращающие Единица измерения пишутся со знаком равенства

def printValue(Икс: Строка): Единица измерения = {  println("Я съел% s".формат(Икс))}

или эквивалентно (с выводом типа и опусканием ненужных фигурных скобок):

def printValue(Икс: Строка) = println("Я съел% s" формат Икс)

Вывод типа

Из-за вывод типа, тип переменных, возвращаемые значения функции и многие другие выражения обычно могут быть опущены, поскольку компилятор может это определить. Примеры val x = "foo" (для неизменного постоянный или неизменный объект ) или var x = 1.5 (для переменной, значение которой впоследствии может быть изменено). Вывод типов в Scala по сути является локальным, в отличие от более глобального Хиндли-Милнер алгоритм, используемый в Haskell, ML и другие более чисто функциональные языки. Это сделано для облегчения объектно-ориентированного программирования. В результате все еще необходимо объявить определенные типы (в первую очередь, параметры функций и возвращаемые типы рекурсивные функции ), например

def форматЯблоки(Икс: Int) = "Я съел% d яблок".формат(Икс)

или (с возвращаемым типом, объявленным для рекурсивной функции)

def факториал(Икс: Int): Int =  если (Икс == 0)    1  еще    Икс*факториал(Икс - 1)

Анонимные функции

В Scala функции являются объектами, и существует удобный синтаксис для указания анонимные функции. Примером может служить выражение х => х <2, который определяет функцию с одним параметром, который сравнивает свой аргумент, чтобы увидеть, меньше ли он 2. Он эквивалентен форме Лиспа (лямбда (x) (. Обратите внимание, что ни тип Икс ни тип возвращаемого значения не нужно указывать явно, и, как правило, он может быть выведен с помощью вывод типа; но они могут быть указаны явно, например так как (х: Инт) => х <2 или даже (x: Int) => (x <2): логическое.

Анонимные функции ведут себя как истинные закрытие в том, что они автоматически захватывают любые переменные, которые лексически доступны в среде включающей функции. Эти переменные будут доступны даже после возврата из включающей функции, и в отличие от Java анонимные внутренние классы не должны объявляться окончательными. (Можно даже изменять такие переменные, если они изменяемы, и измененное значение будет доступно при следующем вызове анонимной функции.)

Еще более короткая форма анонимной функции использует заполнитель переменные: например, следующие:

список map {x => sqrt (x)}

можно записать более кратко как

список карты {sqrt (_)}

или даже

список карта sqrt

Неизменность

В Scala проводится различие между неизменяемыми и изменяемыми переменными. Изменяемые переменные объявляются с использованием вар ключевое слово и неизменяемые значения объявляются с использованием вал ключевое слово. переменная, объявленная с использованием вал ключевое слово не может быть переназначено так же, как переменная, объявленная с использованием окончательный ключевое слово нельзя переназначить в Java. Однако следует отметить, что вал'только поверхностно неизменяемы, то есть объект, на который ссылается val, не гарантирует, что сам по себе является неизменяемым.

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

Ленивая (нестрогая) оценка

По умолчанию оценка является строгой («нетерпеливой»). Другими словами, Scala оценивает выражения, как только они становятся доступными, а не по мере необходимости. Однако можно объявить переменную нестрогой ("ленивой") с ленивый ключевое слово, означающее, что код для создания значения переменной не будет оцениваться до первого обращения к переменной. Также существуют нестрогие коллекции различных типов (например, тип Ручей, нестрогий связанный список), и любую коллекцию можно сделать нестрогой с помощью Посмотреть метод. Нестрогие коллекции обеспечивают хорошее семантическое соответствие таким вещам, как данные, создаваемые сервером, где оценка кода для генерации более поздних элементов списка (что, в свою очередь, запускает запрос к серверу, возможно, расположенному где-то еще в Интернете). происходит, когда элементы действительно нужны.

Хвостовая рекурсия

Функциональные языки программирования обычно предоставляют хвостовой зов оптимизация, позволяющая широко использовать рекурсия без переполнение стека проблемы. Ограничения байт-кода Java усложняют оптимизацию хвостового вызова на JVM. В общем, функция, которая вызывает себя с хвостовым вызовом, может быть оптимизирована, а взаимно рекурсивные функции - нет. Батуты были предложены в качестве обходного пути.[33] Поддержка батутов была предоставлена ​​библиотекой Scala с объектом scala.util.control.TailCalls начиная с Scala 2.8.0 (выпущена 14 июля 2010 г.). Функция может быть дополнительно аннотирована @tailrec, и в этом случае он не будет компилироваться, если он не является хвостовым рекурсивным.[34]

Классы регистра и сопоставление с образцом

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

Пример определения быстрая сортировка алгоритм с использованием сопоставления с образцом таков:

def qsort(список: Список[Int]): Список[Int] = список матч {  кейс Ноль => Ноль  кейс поворот :: хвостик =>    вал (меньше, остальные) = хвостик.раздел(_ < поворот)    qsort(меньше) ::: поворот :: qsort(остальные)}

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

В матч используется для сопоставления с образцом объекта, хранящегося в список. Каждый кейс выражение, по очереди, проверяется, будет ли оно совпадать, и первое совпадение определяет результат. В таком случае, Ноль соответствует только буквальному объекту Ноль, но pivot :: tail соответствует непустому списку и одновременно разрушает список по заданному образцу. В этом случае связанный код будет иметь доступ к локальной переменной с именем поворот держит заголовок списка и другую переменную хвостик удерживая конец списка. Обратите внимание, что эти переменные доступны только для чтения и семантически очень похожи на переменные. привязки создан с использованием позволять оператор в Lisp и Scheme.

Сопоставление с образцом также происходит в объявлениях локальных переменных. В этом случае возвращаемое значение вызова tail.partition это кортеж - в данном случае два списка. (Кортежи отличаются от других типов контейнеров, например списков, тем, что они всегда имеют фиксированный размер, а элементы могут быть разных типов - хотя здесь они оба одинаковы.) Сопоставление с образцом - самый простой способ получить две части кортеж.

Форма _ <точка поворота является декларацией анонимная функция с переменной-заполнителем; см. раздел выше об анонимных функциях.

Операторы списка :: (который добавляет элемент в начало списка, аналогично минусы в Lisp и Scheme) и ::: (который объединяет два списка, аналогично добавить в Lisp и Scheme) появляются оба. Несмотря на внешний вид, ни в одном из этих операторов нет ничего «встроенного». Как указано выше, любая строка символов может служить именем функции, а метод, применяемый к объекту, может быть записан "инфикс "-стиль без точки или скобок. Строка выше, как написано:

qsort (меньше) ::: pivot :: qsort (остальное)

также можно было бы написать так:

qsort (остаток) .: :( pivot). :: :( qsort (меньше))

в более стандартной нотации вызова метода. (Методы, заканчивающиеся двоеточием, являются правоассоциативными и привязаны к объекту справа.)

Частичные функции

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

пытаться {  ...} ловить {  кейс NFE:NumberFormatException => { println(NFE); Список(0) }  кейс _ => Ноль}

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

вал qsort: Список[Int] => Список[Int] = {  кейс Ноль => Ноль  кейс поворот :: хвостик =>    вал (меньше, остальные) = хвостик.раздел(_ < поворот)    qsort(меньше) ::: поворот :: qsort(остальные)}

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

Scala> qsort(Список(6,2,5,9))res32: Список[Int] = Список(2, 5, 6, 9)

Объектно-ориентированные расширения

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

Traits - это замена Scala для Java интерфейсы. Интерфейсы в версиях Java до 8 сильно ограничены и могут содержать только объявления абстрактных функций. Это привело к критике за то, что предоставление удобных методов в интерфейсах неудобно (одни и те же методы должны быть повторно реализованы в каждой реализации), а расширение опубликованного интерфейса обратно совместимым способом невозможно. Черты похожи на миксин классы в том смысле, что они обладают почти всей мощью обычного абстрактного класса, не имея только параметров класса (эквивалент Scala параметрам конструктора Java), поскольку черты всегда смешиваются с классом. В супер Оператор ведет себя особым образом в свойствах, позволяя объединять черты в цепочку с использованием композиции в дополнение к наследованию. Следующий пример представляет собой простую оконную систему:

Абстрактные класс Окно {  // Абстрактные  def привлечь()}класс SimpleWindow расширяет Окно {  def привлечь() {    println("в SimpleWindow")    // рисуем базовое окно  }}черта характера ОкноУкрашение расширяет Окно { }черта характера Горизонтальная полоса прокруткиУкрашение расширяет ОкноУкрашение {  // "абстрактное переопределение" необходимо здесь для того, чтобы "super ()" работала, потому что родительский  // функция абстрактная. Если бы он был конкретным, было бы достаточно обычного «переопределения».  Абстрактные отменять def привлечь() {    println("в HorizontalScrollbarDecoration")    супер.привлечь()    // теперь рисуем горизонтальную полосу прокрутки  }}черта характера Вертикальная полоса прокруткиУкрашение расширяет ОкноУкрашение {  Абстрактные отменять def привлечь() {    println("в VerticalScrollbarDecoration")    супер.привлечь()    // теперь рисуем вертикальную полосу прокрутки  }}черта характера НазваниеУкрашение расширяет ОкноУкрашение {  Абстрактные отменять def привлечь() {    println("в TitleDecoration")    супер.привлечь()    // теперь рисуем строку заголовка  }}

Переменная может быть объявлена ​​так:

вал мойвин = новый SimpleWindow с участием Вертикальная полоса прокруткиУкрашение с участием Горизонтальная полоса прокруткиУкрашение с участием НазваниеУкрашение

Результат звонка mywin.draw () является:

в НазваниеУкрашениев Горизонтальная полоса прокруткиУкрашениев Вертикальная полоса прокруткиУкрашениев SimpleWindow

Другими словами, призыв к привлечь сначала выполнил код в НазваниеУкрашение (вмешалась последняя черта), затем (через супер() вызовов), передаваемого обратно через другие смешанные черты и, в конечном итоге, в код в Окно, хотя ни одна из черт не унаследована друг от друга. Это похоже на декоратор шаблон, но он более краток и менее подвержен ошибкам, поскольку не требует явной инкапсуляции родительского окна, явной пересылки функций, реализация которых не изменяется, или использования инициализации взаимосвязей сущностей во время выполнения. В других языках подобный эффект может быть достигнут во время компиляции с длинной линейной цепочкой наследование реализации, но с недостатком по сравнению со Scala, что одна цепочка линейного наследования должна быть объявлена ​​для каждой возможной комбинации добавлений.

Система выразительных шрифтов

Scala оснащена выразительной системой статических типов, которая в основном обеспечивает безопасное и связное использование абстракций. Однако система типов не звук.[35] В частности, система типов поддерживает:

Scala умеет вывести типы по использованию. Это делает большинство объявлений статических типов необязательными. Статические типы не нужно объявлять явно, если ошибка компилятора не указывает на необходимость. На практике некоторые объявления статических типов включены для ясности кода.

Обогащение типов

Распространенный метод в Scala, известный как «обогатить мою библиотеку»[36] (первоначально названный Мартином Одерски «сутенером моей библиотеки» в 2006 году;[30] были высказаны опасения по поводу этой формулировки из-за ее отрицательной коннотации[37] и незрелость[38]), позволяет использовать новые методы, как если бы они были добавлены к существующим типам. Это похоже на концепцию C # методы расширения но более мощный, потому что метод не ограничивается добавлением методов и может, например, использоваться для реализации новых интерфейсов. В Scala этот метод включает объявление неявное преобразование от типа, «принимающего» метод, к новому типу (обычно классу), который является оболочкой исходного типа и предоставляет дополнительный метод. Если метод не может быть найден для данного типа, компилятор автоматически ищет любые применимые неявные преобразования к типам, которые предоставляют рассматриваемый метод.

Этот метод позволяет добавлять новые методы в существующий класс с помощью дополнительной библиотеки, так что только код, который импорт библиотека надстройки получает новые функции, а весь остальной код не изменяется.

В следующем примере показано обогащение типа Int с методами даже и isOdd:

объект MyExtensions {  неявный класс IntPredicates(я: Int) {    def даже = я % 2 == 0    def isOdd  = !даже  }}импорт MyExtensions._  // вводим неявное обогащение в область видимости4.даже  // -> истина

Импорт членов MyExtensions приносит неявное преобразование в класс расширения IntPredicates в объем.[39]

Параллелизм

Стандартная библиотека Scala включает поддержку актерская модель, в дополнение к стандартным API-интерфейсам параллелизма Java. Lightbend Inc. предоставляет платформу[40] это включает Акка,[41] отдельная платформа с открытым исходным кодом, которая обеспечивает параллелизм на основе акторов. Актеры Akka могут быть распределен или в сочетании с программная транзакционная память (участники сделки). Альтернатива связь последовательных процессов (CSP) реализации для передачи сообщений на основе канала - это коммуникативные объекты Scala,[42] или просто через JCSP.

Актер подобен экземпляру потока с почтовым ящиком. Это может быть создано system.actorOf, отменяя получить метод получения сообщений и использование ! (восклицательный знак) метод отправки сообщения.[43]В следующем примере показан EchoServer, который может получать сообщения и затем распечатывать их.

вал echoServer = актер(новый Действовать {  становиться {    кейс сообщение => println("эхо" + сообщение)  }})echoServer ! "Здравствуй"

Scala также имеет встроенную поддержку параллельного программирования данных в форме Parallel Collections.[44] интегрирован в стандартную библиотеку с версии 2.9.0.

В следующем примере показано, как использовать параллельные коллекции для повышения производительности.[45]

вал URL = Список("https://scala-lang.org", "https://github.com/scala/scala")def fromURL(url: Строка) = Scala.io.Источник.fromURL(url)  .getLines().mkString(" п")вал т = Система.currentTimeMillis()URL.номинал.карта(fromURL(_)) // par возвращает параллельную реализацию коллекцииprintln("время:" + (Система.currentTimeMillis - т) + "РС")

Помимо поддержки акторов и параллелизма данных, Scala также поддерживает асинхронное программирование с Futures и Promises, программной транзакционной памятью и потоками событий.[46]

Кластерные вычисления

Самым известным решением для кластерных вычислений с открытым исходным кодом, написанным на Scala, является Apache Spark. Дополнительно, Апач Кафка, то опубликовать – подписаться очередь сообщений популярный в Spark и других технологиях потоковой обработки, написан на Scala.

Тестирование

Есть несколько способов протестировать код в Scala. ScalaTest поддерживает несколько стилей тестирования и может интегрироваться со средами тестирования на основе Java.[47] ScalaCheck это библиотека, похожая на Haskell's Быстрая проверка.[48] спецификации2 это библиотека для написания спецификаций исполняемого программного обеспечения.[49] ScalaMock обеспечивает поддержку тестирования высокоуровневых и каррированных функций.[50] JUnit и TestNG - популярные среды тестирования, написанные на Java.

Версии

ВерсияВыпущенныйособенностиСтатус
1.0.0-b2[51]8 декабря 2003 г.__
1.1.0-b1[51]19 февраля 2004 г.
  • scala.Enumeration
  • Лицензия Scala была изменена на исправленную лицензию BSD
_
1.1.1[51]23 марта 2004 г.
  • Поддержка статических внутренних классов Java
  • Улучшения библиотечных классов для Iterable, Array, xml.Elem, Buffer
_
1.2.0[51]9 июня 2004 г.
  • Взгляды
  • XML-литералы
_
1.3.0[51]16 сентября 2004 г.
  • Поддержка Microsoft .NET
  • Закрытие методов
  • Синтаксис типов для методов без параметров изменен с [] Т к => Т
_
1.4.0[51]20 июня 2005 г.
  • Атрибуты
  • матч ключевое слово заменяет матч метод
  • Экспериментальная поддержка типов среды выполнения
_
2.0[52]12 марта 2006 г.
  • Компилятор полностью переписан на Scala
  • Экспериментальная поддержка дженериков Java
  • неявный и требует ключевые слова
  • матч ключевое слово только разрешенный инфикс
  • с участием связка допускается только после расширяет пункт
  • Новые строки могут использоваться как разделители операторов вместо точки с запятой.
  • Шаблоны соответствия регулярных выражений ограничены только шаблонами последовательностей
  • Формы понимания допускают определения значений и шаблонов
  • Параметры класса могут иметь префикс val или var
  • У приватной видимости есть квалификаторы
_
2.1.0[51]17 марта 2006 г.
  • инструмент sbaz, интегрированный в дистрибутив Scala
  • матч ключевое слово заменяет матч метод
  • Экспериментальная поддержка типов среды выполнения
_
2.1.8[53]23 августа 2006 г.
  • Защищенная видимость имеет квалификаторы
  • На частные члены класса можно ссылаться из сопутствующего модуля класса и наоборот.
  • Обобщенный неявный поиск
  • Соответствие типизированному образцу ужесточено для одиночных типов
_
2.3.0[54]23 ноября 2006 г.
  • Возвращение функций Единица измерения не нужно явно указывать возвращаемый тип
  • Переменные типа и типы различаются при сопоставлении с образцом
  • Все и AllRef переименован в Ничего и Значение NULL
_
2.4.0[55]09-мар-2007
  • частный и защищенный модификаторы принимают [этот] квалификатор
  • Кортежи можно записывать в круглые скобки
  • Первичный конструктор класса теперь может быть помечен как частный или защищенный
  • Атрибуты изменены на аннотации с новым синтаксисом
  • Собственные псевдонимы
  • Операторы можно комбинировать с назначением
_
2.5.0[56]02-мая-2007
  • Параметры типа и элементы абстрактного типа также могут абстрагироваться от конструкторов типов.
  • Поля объекта могут быть инициализированы до вызова родительских конструкторов
  • Изменение синтаксиса для-понимания
  • Неявные анонимные функции (с подчеркиванием для параметров)
  • Сопоставление с образцом анонимных функций расширено для поддержки любого искусства
_
2.6.0[57]27-июл-2007
  • Экзистенциальные типы
  • Ленивые ценности
  • Структурные типы
_
2.7.0[58]07 февраля 2008 г.
  • Универсальные типы Java, поддерживаемые по умолчанию
  • Расширены функциональные возможности классов кейсов
_
2.8.0[59]14-июл-2010
  • Пересмотр общей, единообразной и всеобъемлющей структуры для типов коллекций.
  • Типовая специализация
  • Именованный и аргументы по умолчанию
  • Объекты пакета
  • Улучшенные аннотации
_
2.9.0[60]12-мая-2011
  • Параллельные коллекции
  • Потокобезопасный Приложение черта заменяет заявка черта характера
  • DelayedInit черта характера
  • Улучшения Java Interop
_
2.10[61]04-янв-2013
  • Классы значений[62]
  • Неявные классы[63]
  • Строчная интерполяция[64]
  • Будущее и обещания[65]
  • Dynamic и applyDynamic[66]
  • Типы зависимых методов:
    • def идентичность(Икс: AnyRef): Икс.тип = Икс // возвращаемый тип говорит, что мы возвращаем именно то, что получили
  • Новый эмиттер ByteCode на основе ASM:
    • Может нацеливаться на JDK 1.5, 1.6 и 1.7
    • По умолчанию выдает байт-код 1.6
    • Бэкэнд старой версии 1.5 устарел
  • Новый Pattern Matcher: переписан с нуля для генерации более надежного кода (больше никаких экспоненциальных взрывов!)
    • генерация кода и анализ теперь независимы (последний можно отключить с помощью -Xno-patmat-analysis)
  • Улучшения Scaladoc
    • Implicits (флаг -implicits)
    • Диаграммы (флаг -diagrams, требуется graphviz)
    • Группы (-группы)
  • Модульные языковые функции[67]
  • Параллельные коллекции[68] теперь настраиваются с помощью настраиваемых пулов потоков
  • Akka Actors теперь в раздаче
    • scala.actors устарел, и реализация akka теперь включена в дистрибутив.
  • Улучшения производительности
    • Более быстрый вкладыш
    • Сумма диапазона # теперь равна O (1)
  • Обновление библиотеки ForkJoin
  • Исправления в неизменяемом TreeSet / TreeMap
  • Улучшения частичных функций
  • Добавление ??? и NotImplementedError
  • Добавление классов типов IsTraversableOnce + IsTraversableLike для методов расширения
  • Устаревание и очистка
  • Устарел синтаксис с плавающей точкой и восьмеричным литералом
  • Удален scala.dbc

Экспериментальные особенности

  • Отражение Скала[69]
  • Макросы[70]
_
2.10.2[71]06-июн-2013__
2.10.3[72]01 октября 2013 г.__
2.10.4[73]18-мар-2014__
2.10.5[74]05-мар-2015__
2.11.0[75]21 апреля 2014 г.
  • Улучшения производительности коллекции
  • Улучшения производительности компилятора
_
2.11.1[76]20-мая-2014__
2.11.2[77]22-июл-2014__
2.11.4[78]31 октября 2014 г.__
2.11.5[79]08-янв-2015__
2.11.6[80]05 марта 2015 г.__
2.11.7[81]23-июн-2015__
2.11.8[82]08-мар-2016__
2.11.11[83]18-апр-2017__
2.11.12[84]13-ноя-2017__
2.12.0[85]03-ноя-2016_
2.12.1[86]05-дек-2016__
2.12.2[87]18-апр-2017__
2.12.3[88]26-июл-2017__
2.12.4[89]17 октября 2017 г.__
2.12.5[90]15-мар-2018__
2.12.6[91]27-апр-2018__
2.12.7[92]27-сен-2018__
2.12.8[93]04-дек-2018Первый выпуск Scala 2.12 с измененной лицензией на Apache v2.0_
2.13.0[94]11-июн-2019_ток

Сравнение с другими языками JVM

Scala часто сравнивают с Groovy и Clojure, два других языка программирования также используют JVM. Существенные различия между этими языками обнаруживаются в системе типов, в степени, в которой каждый язык поддерживает объектно-ориентированное и функциональное программирование, и в сходстве их синтаксиса с синтаксисом Java.

Scala - это статически типизированный, а Groovy и Clojure динамически типизированный. Это делает систему типов более сложной и трудной для понимания, но позволяет почти всем[35] ошибки типа, которые должны быть обнаружены во время компиляции и могут привести к значительно более быстрому выполнению. Напротив, динамическая типизация требует большего количества тестов, чтобы гарантировать правильность программы, и обычно медленнее, чтобы обеспечить большую гибкость и простоту программирования. Что касается разницы в скорости, текущие версии Groovy и Clojure допускают необязательные аннотации типов, чтобы помочь программам избежать накладных расходов на динамическую типизацию в случаях, когда типы практически статичны. Эти накладные расходы еще больше уменьшаются при использовании последних версий JVM, которые были улучшены с помощью вызывать динамический инструкция для методов, которые определены с динамически типизированными аргументами. Эти достижения сокращают разрыв в скорости между статической и динамической типизацией, хотя язык со статической типизацией, такой как Scala, по-прежнему является предпочтительным выбором, когда эффективность выполнения очень важна.

Что касается парадигм программирования, Scala наследует объектно-ориентированную модель Java и расширяет ее различными способами. Groovy, хотя и сильно объектно-ориентирован, больше ориентирован на снижение многословности. В Clojure объектно-ориентированному программированию не уделяется должного внимания, поскольку функциональное программирование является основной сильной стороной языка. Scala также имеет множество средств функционального программирования, включая функции, имеющиеся в расширенных функциональных языках, таких как Haskell, и пытается быть агностиком между двумя парадигмами, позволяя разработчику выбирать между двумя парадигмами или, что более часто, их комбинацией.

Что касается синтаксического сходства с Java, Scala наследует большую часть синтаксиса Java, как и в случае с Groovy. Clojure же следует за Лисп синтаксис, который отличается как по внешнему виду, так и по философии. Однако изучение Scala также считается трудным из-за его множества дополнительных функций. Это не относится к Groovy, несмотря на то, что он также является многофункциональным языком, главным образом потому, что он был разработан в основном как язык сценариев.[нужна цитата ]

Принятие

Рейтинг языков

По состоянию на 2013 годвсе языки на основе JVM (Clojure, Groovy, Kotlin, Scala) значительно менее популярны, чем исходный язык Java, который обычно занимает первое или второе место,[95][96] и который также одновременно развивается с течением времени.

Индекс популярности языка программирования,[97] отслеживающий поиск учебных пособий по языку, Scala заняла 15-е место в апреле 2018 года с небольшой тенденцией к снижению. Это делает Scala самым популярным языком на основе JVM после Java, хотя сразу за ним следует Котлин, язык на базе JVM с сильной тенденцией к росту занял 16-е место.

В Индекс TIOBE[96] Для определения популярности языка программирования используются рейтинги в поисковых системах и аналогичный подсчет публикаций. По состоянию на апрель 2018 года Scala занимает 34-е место, опустившись на четыре позиции за последние два года, но, как упоминалось в разделе «Ошибки и запросы на изменение», TIOBE знает о проблемах с его методологией использования условий поиска, которые могут не соответствовать обычно используется в некоторых сообществах языков программирования. В этом рейтинге Scala опережает некоторые функциональные языки, такие как Haskell (42-й), Erlang, но ниже других языков, таких как Swift (15), Perl (16), Идти (19-е) и Clojure (30-е).

В ThoughtWorks Technology Radar, представляющий собой двухгодичный отчет группы старших технологов, основанный на мнениях.[98] рекомендовал принятие Scala в категории языков и фреймворков в 2013 году.[99] В июле 2014 года эта оценка была сделана более конкретной и теперь относится к «Scala, хорошие части», которая описывается как «Чтобы успешно использовать Scala, вам необходимо изучить язык и иметь очень твердое мнение о том, какие части являются правильными. для вас, создав ваше собственное определение Scala, хорошие части. ".[100]

Рейтинг языков программирования RedMonk, который устанавливает рейтинги на основе количества GitHub проекты и вопросы, заданные на Переполнение стека, занимает 14 место Scala.[95] Здесь Scala помещается в группу языков второго уровня, опережая Идти, PowerShell и Haskell, и позади Swift, Цель-C, Машинопись и р. Однако в своем отчете за 2018 год рейтинги отметили падение рейтинга Scala в третий раз подряд, задав вопрос, «сколько из доступного кислорода для Scala потребляется Kotlin, поскольку последний продолжает подниматься в этом рейтинге».[95]

В обзоре "Состояние Java" за 2018 г.[101] который собрал данные от 5160 разработчиков по различным темам, связанным с Java, Scala занимает третье место с точки зрения использования альтернативных языков на JVM. По сравнению с прошлогодним опросом, использование Scala среди альтернативных языков JVM упало почти на четверть (с 28,4% до 21,5%), обогнав Kotlin, который вырос с 11,4% в 2017 году до 28,8% в 2018 году.

Компании

  • В апреле 2009 г. Twitter объявил, что он переключил большую часть своей серверной части с Рубин на Scala и предназначен для преобразования остальных.[102]
  • Золоченый использует Scala и Play Framework.[103]
  • Foursquare использует Scala и Лифт.[104]
  • Coursera использует Scala и Play Framework.[105]
  • Apple Inc. использует Scala в определенных командах вместе с Java и платформой Play.[106][107]
  • Хранитель сайт газеты с высокой посещаемостью guardian.co.uk[108] объявил в апреле 2011 года о переходе с Java на Scala,[109][110]
  • В Газета "Нью-Йорк Таймс в 2014 г. обнаружил, что его внутренняя система управления контентом Черная борода построен с использованием Scala, Akka и Play.[111]
  • В Huffington Post газета начала использовать Scala как часть своей системы доставки контента Афина в 2013.[112]
  • Швейцарский банк UBS одобрил Scala для общего производственного использования.[113]
  • LinkedIn использует Скалатра микрофреймворк для работы своего Signal API.[114]
  • Встреча использует нефильтрованный инструментарий для API реального времени.[115]
  • Помни о молоке использует нефильтрованный инструментарий, Scala и Akka для общедоступного API и обновлений в реальном времени.[116]
  • Verizon стремясь создать «фреймворк следующего поколения» с использованием Scala.[117]
  • Airbnb разрабатывает программное обеспечение для машинного обучения с открытым исходным кодом "Aerosolve", написанное на Java и Scala.[118]
  • Zalando перенесла свой технологический стек с Java на Scala и Play.[119]
  • SoundCloud использует Scala для своей серверной части, используя такие технологии, как Finagle (микросервисы),[120] Scalding and Spark (обработка данных).[121]
  • Датабрики использует Scala для Apache Spark Платформа больших данных.
  • Морган Стенли широко использует Scala в своих финансовых проектах и ​​проектах, связанных с активами.[122]
  • Есть команды внутри Google /Alphabet Inc. которые используют Scala, в основном из-за таких приобретений, как Firebase[123] и гнездо.[124]
  • Walmart Canada Использует Scala для своей серверной платформы.[125]
  • Duolingo использует Scala в качестве внутреннего модуля, который генерирует уроки.[126]
  • HMRC использует Scala для многих налоговых приложений правительства Великобритании.[127]

Критика

В марте 2015 года бывший вице-президент группы разработки платформ в Twitter. Раффи Крикорян, заявил, что не выбрал бы Scala в 2011 году из-за ее кривая обучения.[128] В том же месяце старший вице-президент LinkedIn Кевин Скотт заявили о своем решении «минимизировать [свою] зависимость от Scala».[129] В ноябре 2011 г. Yammer отошел от Scala по причинам, в том числе из-за необходимости обучения новых членов команды и несовместимости от одной версии компилятора Scala к другой.[130]

Смотрите также

  • сбт, широко используемый инструмент сборки для проектов Scala
  • Играть в!, платформа веб-приложений с открытым исходным кодом, поддерживающая Scala
  • Акка, набор инструментов с открытым исходным кодом для создания параллельных и распределенных приложений.
  • Долото, язык с открытым исходным кодом, основанный на Scala, который используется для проектирования и создания оборудования.[131]

использованная литература

  1. ^ "Scala 2.13.4 уже доступна!". 2020-11-19. Получено 2020-11-19.
  2. ^ "Файл NOTICE". 2019-01-24. Получено 2019-12-04 - через GitHub.
  3. ^ «Макросы Scala».
  4. ^ Фогус, Майкл (6 августа 2010 г.). "МартинОдерский возьми (5) в список". Отправить больше медработников. Получено 2012-02-09.
  5. ^ а б c d Одерский, Мартин (11 января 2006 г.). «Эксперимент Scala - можем ли мы обеспечить лучшую языковую поддержку для компонентных систем?» (PDF). Получено 2016-06-22.
  6. ^ а б c d Одерский, Мартин; и другие. (2006). «Обзор языка программирования Scala» (PDF) (2-е изд.). Федеральная политехническая школа Лозанны (EPFL). В архиве (PDF) из оригинала от 09.07.2020.
  7. ^ Одерский, Мартин (2008). Программирование на Scala. Маунтин-Вью, Калифорния: Артима. п. 3. ISBN  9780981531601. Получено 12 июн 2014.
  8. ^ Потвин, Паскаль; Бонха, Марио (24 сентября 2015 г.). IMS DSL, разработанный в Эрикссон. Конспект лекций по информатике. 7916. arXiv:1509.07326. Дои:10.1007/978-3-642-38911-5. ISBN  978-3-642-38910-8. S2CID  1214469.
  9. ^ «Часто задаваемые вопросы - совместимость с Java». scala-lang.org. Получено 2015-02-06.
  10. ^ Фризен, Джефф (16 ноября 2016 г.). "Проверенные исключения хороши или плохи?". JavaWorld. Получено 28 августа 2018.
  11. ^ Ловердо, Христос (2010). Шаги в Scala: введение в объектно-функциональное программирование. Издательство Кембриджского университета. п. xiii. ISBN  9781139490948. Получено 31 июля 2014.
  12. ^ а б c d Мартин Одерский, «Краткая история Scala», Интернет-журналы Artima.com, 9 июня 2006 г.
  13. ^ а б c d Одерский, М .; Ромпф, Т. (2014). «Объединение функционального и объектно-ориентированного программирования с помощью Scala». Коммуникации ACM. 57 (4): 76. Дои:10.1145/2591013.
  14. ^ Мартин Одерский, "Спецификация языка Scala версии 2.7"
  15. ^ «Команда Scala выигрывает грант ERC». Получено 4 июля 2015.
  16. ^ «Коммерческая поддержка Scala». 2011-05-12. Получено 2011-08-18.
  17. ^ «Почему мы инвестировали в Typesafe: современные приложения требуют современных инструментов». 2011-05-12. Получено 2018-05-08.
  18. ^ «Scala с открытым исходным кодом получает коммерческую поддержку». 2011-05-12. Получено 2011-10-09.
  19. ^ «Пионер облачных вычислений Мартин Одерски закрывает глаза на свою новую компанию Typesafe». 2011-05-12. Получено 2011-08-24.
  20. ^ «Scala на Android». Получено 8 июн 2016.
  21. ^ «Scala 2.12.8 уже доступна!». 2018-12-04. Получено 2018-12-09.
  22. ^ "Scala Js больше не экспериментальный | Язык программирования Scala". Scala-lang.org. Получено 28 октября 2015.
  23. ^ https://github.com/scala-js/scala-js/releases
  24. ^ Криль, Пол (15 марта 2017 г.). «Уменьшенный вариант Scala устраняет связи с JVM». InfoWorld. Получено 21 марта 2017.
  25. ^ Криль, Пол (2016-05-11). «Язык Scala приближается к голому металлу». InfoWorld.
  26. ^ Удален сервер .net. автор: paulp · Запрос на слияние №1718 · scala / scala · GitHub. Github.com (05.12.2012). Проверено 2 ноября 2013.
  27. ^ «Начало работы со Scala». scala-lang.org. 15 июля 2008 г.. Получено 31 июля 2014.
  28. ^ "Главная". Blog.lostlake.org. Архивировано из оригинал 31 августа 2010 г.. Получено 2013-06-25.
  29. ^ Встроенные управляющие структуры Scala, такие как если или в то время как не может быть повторно реализован. Существует исследовательский проект Scala-Virtualized, направленный на снятие этих ограничений: Адриан Мурс, Тиарк Ромпф, Филипп Галлер и Мартин Одерски. Scala-виртуализированный. Материалы семинара ACM SIGPLAN 2012 по частичной оценке и манипулированию программой, 117–120. Июль 2012 г.
  30. ^ а б "Прокачай мою библиотеку". Artima.com. 2006-10-09. Получено 2013-06-25.
  31. ^ «Изменяемые и неизменяемые коллекции - документация Scala». Получено 30 апреля 2020.
  32. ^ "Коллекции - Конкретные неизменяемые классы коллекций - Документация Scala". Получено 4 июля 2015.
  33. ^ Догерти, Рич. "Блог Рича Догерти". Получено 4 июля 2015.
  34. ^ «TailCalls - API стандартной библиотеки Scala (Scaladoc) 2.10.2 - scala.util.control.TailCalls». Scala-lang.org. Получено 2013-06-25.
  35. ^ а б «Системы типов Java и Scala не верны» (PDF).
  36. ^ Джарруссо, Паоло Г. (2013). «Повторите запросы вашей коллекции для модульности и скорости!». Материалы 12-й ежегодной международной конференции по Аспектно-ориентированной разработке программного обеспечения. ACM. arXiv:1210.6284. Bibcode:2012arXiv1210.6284G. Также известен как шаблон pimp-my-library
  37. ^ Гилберт, Клинт (2011-11-15). «Что является наивысшим приоритетом для успеха Scala в корпоративном мире (должно ли быть в scala-дебатах?)?». scala-lang.org. Получено 2019-05-08.
  38. ^ «Следует ли нам« обогащать »или« расширять »библиотеки Scala?». stackexchange.com. 17 июня 2013 г.. Получено 15 апреля 2016.
  39. ^ Неявные классы были введены в Scala 2.10, чтобы сделать расширения методов более краткими. Это эквивалентно добавлению метода неявный def IntPredicate (i: Int) = новый IntPredicate (i). Класс также можно определить как неявный класс IntPredicates (val i: Int) расширяет AnyVal {...}, производя так называемый класс стоимости, также представленный в Scala 2.10. Затем компилятор исключит фактические экземпляры и вместо этого сгенерирует статические методы, позволяя методам расширения практически не иметь накладных расходов на производительность.
  40. ^ «Реактивная платформа Lightbend». Lightbend. Получено 2016-07-15.
  41. ^ Что такое Акка?, Онлайн-документация Akka
  42. ^ Взаимодействие с объектами Scala, Бернар Суфрин, Архитектуры коммуникационных процессов, 2008 г.
  43. ^ Ян, Кей. «Скала Тур». Получено 4 июля 2015.
  44. ^ «Параллельные коллекции - Обзор - Документация Scala». Docs.scala-lang.org. Получено 2013-06-25.
  45. ^ Ян, Кей. «Скала Тур». Получено 4 июля 2015.
  46. ^ Изучение параллельного программирования на Scala, Александр Прокопец, Packt Publishing
  47. ^ Копс, Миха (13 января 2013). «Краткое введение в ScalaTest». hascode.com. Получено 2014-11-07.
  48. ^ Нильссон, Рикард (17 ноября 2008 г.). «ScalaCheck 1.5». scala-lang.org. Получено 2014-11-07.
  49. ^ «Создавайте веб-приложения с использованием Scala и Play Framework». workwithplay.com. 2013-05-22. Получено 2014-11-07.
  50. ^ Мясник, Пол (2012-06-04). «Предварительный выпуск ScalaMock 3.0». paulbutcher.com. Получено 2014-11-07.
  51. ^ а б c d е ж г «История изменений Scala». scala-lang.org. Архивировано из оригинал на 2007-10-09.
  52. ^ «Изменения в версии 2.0 (12 марта 2006 г.)». scala-lang.org. 2006-03-12. Получено 2014-11-07.
  53. ^ «Изменения в версии 2.1.8 (23 августа 2006 г.)». scala-lang.org. 2006-08-23. Получено 2014-11-07.
  54. ^ «Изменения в версии 2.3.0 (23 ноября 2006 г.)». scala-lang.org. 2006-11-23. Получено 2014-11-07.
  55. ^ «Изменения в версии 2.4.0 (09 марта 2007 г.)». scala-lang.org. 2007-03-09. Получено 2014-11-07.
  56. ^ «Изменения в версии 2.5 (02 мая 2007 г.)». scala-lang.org. 2007-05-02. Получено 2014-11-07.
  57. ^ «Изменения в версии 2.6 (27 июля 2007 г.)». scala-lang.org. 2007-06-27. Получено 2014-11-07.
  58. ^ «Изменения в версии 2.7.0 (7 февраля 2008 г.)». scala-lang.org. 2008-02-07. Получено 2014-11-07.
  59. ^ «Изменения в версии 2.8.0 (14 июля 2010 г.)». scala-lang.org. 2010-07-10. Получено 2014-11-07.
  60. ^ «Изменения в версии 2.9.0 (12 мая 2011 г.)». scala-lang.org. 2011-05-12. Получено 2014-11-07.
  61. ^ «Изменения в версии 2.10.0». scala-lang.org. 2013-01-04. Получено 2014-11-07.
  62. ^ Харра, Марк. «Классы ценностей и универсальные черты». scala-lang.org. Получено 2014-11-07.
  63. ^ Суэрет, Джош. «SIP-13 - Неявные классы». scala-lang.org. Получено 2014-11-07.
  64. ^ Суэрет, Джош. «Строчная интерполяция». scala-lang.org. Получено 2014-11-07.
  65. ^ Галлер, Филипп; Прокопец, Александр. «Будущее и обещания». scala-lang.org. Получено 2014-11-07.
  66. ^ «СИП-17 - Тип Динамический». scala-lang.org. Получено 2014-11-07.
  67. ^ «SIP-18 - Модуляризация языковых функций». scala-lang.org. Получено 2014-11-07.
  68. ^ Прокопец, Александар; Миллер, Хизер. «Параллельные коллекции». scala-lang.org. Получено 2014-11-07.
  69. ^ Миллер, Хизер; Бурмако, Евгений. "Обзор отражения". scala-lang.org. Получено 2014-11-07.
  70. ^ Бурмако, Евгений. "Макросы защиты". scala-lang.org. Получено 2014-11-07.
  71. ^ «Scala 2.10.2 уже доступна!». scala-lang.org. 2013-06-06. Архивировано из оригинал на 2014-11-08. Получено 2014-11-07.
  72. ^ «Scala 2.10.3 уже доступна!». scala-lang.org. 2013-10-01. Архивировано из оригинал на 2014-11-08. Получено 2014-11-07.
  73. ^ «Scala 2.10.4 уже доступна!». scala-lang.org. 2014-03-18. Получено 2015-01-07.
  74. ^ «Scala 2.10.5 уже доступна!». scala-lang.org. 2015-03-04. Получено 2015-03-23.
  75. ^ «Scala 2.11.0 уже доступна!». scala-lang.org. 2014-04-21. Получено 2014-11-07.
  76. ^ «Scala 2.11.1 уже доступна!». scala-lang.org. 2014-05-20. Получено 2014-11-07.
  77. ^ «Scala 2.11.2 уже доступна!». scala-lang.org. 2014-07-22. Получено 2014-11-07.
  78. ^ «Scala 2.11.4 уже доступна!». scala-lang.org. 2014-10-30. Получено 2014-11-07.
  79. ^ «Scala 2.11.5 уже доступна!». scala-lang.org. 2015-01-08. Получено 2015-01-22.
  80. ^ «Scala 2.11.6 уже доступна!». scala-lang.org. 2015-03-05. Получено 2015-03-12.
  81. ^ «Scala 2.11.7 уже доступна!». scala-lang.org. 2015-06-23. Получено 2015-07-03.
  82. ^ «Scala 2.11.8 уже доступна!». scala-lang.org. 2016-03-08. Получено 2016-03-09.
  83. ^ «Три новых релиза и еще доброго GitHub!». scala-lang.org. 2017-04-18. Получено 2017-04-19.
  84. ^ «Обновление безопасности: 2.12.4, 2.11.12, 2.10.7 (CVE-2017-15288)». scala-lang.org. 2017-11-13. Получено 2018-05-04.
  85. ^ «Scala 2.12.0 уже доступна!». scala-lang.org. 2016-11-03. Получено 2017-01-08.
  86. ^ «Scala 2.12.1 уже доступна!». scala-lang.org. 2016-12-05. Получено 2017-01-08.
  87. ^ «Три новых релиза и еще доброго GitHub!». scala-lang.org. 2017-04-18. Получено 2017-04-19.
  88. ^ "SCALA 2.12.3 ТЕПЕРЬ ДОСТУПНА!". scala-lang.org. 2017-07-26. Получено 2017-08-16.
  89. ^ "SCALA 2.12.4 ТЕПЕРЬ ДОСТУПНА!". scala-lang.org. 2017-10-18. Получено 2017-10-26.
  90. ^ "SCALA 2.12.5 ТЕПЕРЬ ДОСТУПНА!". scala-lang.org. 2018-03-15. Получено 2018-03-20.
  91. ^ «Scala 2.12.6 уже доступна!». scala-lang.org. 2018-04-27. Получено 2018-05-04.
  92. ^ «Scala 2.12.7 уже доступна!». scala-lang.org. 2018-09-27. Получено 2018-10-09.
  93. ^ «Scala 2.12.8 уже доступна!». scala-lang.org. 2018-12-04. Получено 2018-12-09.
  94. ^ «Scala 2.13.0 уже доступна!». scala-lang.org. 2019-06-11. Получено 2018-06-17.
  95. ^ а б c «Рейтинг языков программирования RedMonk: январь 2018 г.».
  96. ^ а б «Индекс TIOBE за апрель 2018 года».
  97. ^ «Индекс популярности языка программирования».
  98. ^ «Часто задаваемые вопросы о ThoughtWorks Technology Radar».
  99. ^ «Технологический радар ThoughtWorks МАЙ 2013» (PDF).
  100. ^ «Рейтинг языков программирования RedMonk: январь 2018 г.».
  101. ^ «Состояние Java в 2018 году».
  102. ^ Грин, Кейт (1 апреля 2009 г.). «Секрет роста Twitter. Как новый язык веб-программирования помогает компании справляться с растущей популярностью». Обзор технологий. Массачусетский технологический институт. Получено 6 апреля 2009.
  103. ^ «Play Framework, Akka и Scala в Gilt Groupe». Lightbend. 15 июля 2013 г.. Получено 16 июля 2016.
  104. ^ «Scala, Lift и будущее». Архивировано из оригинал 13 января 2016 г.. Получено 4 июля 2015.
  105. ^ «Почему мы любим Scala на Coursera». Coursera Engineering. Получено 4 июля 2015.
  106. ^ "Технический директор Apple, Джаррод Неттлз в Twitter". Джаррод Крапива. Получено 2016-03-11.
  107. ^ «30 вакансий Scala в Apple». Элвин Александр. Получено 2016-03-11.
  108. ^ Дэвид Рид и Таня Тейшейра (26 февраля 2010 г.). «Готовы ли люди платить за новости в Интернете?». BBC. Получено 2010-02-28.
  109. ^ «Guardian, переходящий с Java на Scala». Heise Online. 2011-04-05. Получено 2011-04-05.
  110. ^ "Guardian.co.uk Переход с Java на Scala". InfoQ.com. 2011-04-04. Получено 2011-04-05.
  111. ^ Рой, Суман и Сундаресан, Кришна (13 мая 2014 г.). «Building Blackbeard: система синдикации на базе Play, Scala и Akka». Получено 2014-07-20.
  112. ^ Павли, Джон (2013-08-11). "Sneak Peek: HuffPost обеспечивает сотрудничество в режиме реального времени в отделе новостей". Получено 2014-07-20.
  113. ^ Бинсток, Эндрю (14.07.2011). "Интервью с Мартином Одерски из Scala". Журнал доктора Добба. Получено 2012-02-10.
  114. ^ Синодин, Дионисий Г. (11.10.2010). «LinkedIn Signal: пример использования Scala, JRuby и Voldemort». InfoQ.
  115. ^ «Встречи в реальной жизни заслуживают API в реальном времени».
  116. ^ «Веб-приложение Remember The Milk обновляется в реальном времени».
  117. ^ «Старший инженер по Scala». Получено 2014-08-18.
  118. ^ Новет, Иордания (4 июня 2015 г.). «Airbnb представляет Aerosolve, программный пакет для машинного обучения с открытым исходным кодом». Получено 2016-03-09.
  119. ^ Копс, Александр (14.12.2015). «Zalando Tech: от Java до Scala менее чем за три месяца». Получено 2016-03-09.
  120. ^ Кальсадо, Фил (13.06.2014). «Создание продуктов в SoundCloud - Часть III: Микросервисы в Scala и Finagle». Получено 2016-03-09.
  121. ^ Concurrent Inc. (18 ноября 2014 г.). «Примеры использования: SoundCloud». Получено 2016-03-09.
  122. ^ Навыки имеют значение (03.12.2015). "Scala в Morgan Stanley (видео)". Получено 2016-03-11.
  123. ^ Грег Солтис. "SF Scala, Грег Солтис: высокопроизводительные услуги в Scala (видео)". Получено 2016-03-11.
  124. ^ Ли Мигдолл. "Вакансии Scala в Nest". Получено 2016-03-11.
  125. ^ Нурун. «Нурун запускает обновленную транзакционную платформу с Walmart Canada». Получено 2013-12-11.
  126. ^ Андре К. Хори (31 января 2017 г.). «Переписывание движка Duolingo на Scala». Получено 2017-02-03.
  127. ^ "Репозиторий HMRC GitHub".
  128. ^ Крикориан, Раффи (17 марта 2015 г.). Конференция по архитектуре программного обеспечения O'Reilly 2015: Полный сборник видео: перестройка архитектуры на лету - Раффи Крикориан - Часть 3 (видео). O'Reilly Media. Событие происходит в 4:57. Получено 8 марта 2016. Четыре года назад я бы сделал иначе, так это использовал бы Java, а не Scala как часть этого переписывания. [...] инженеру потребуется два месяца, прежде чем он станет полностью продуктивным и напишет код Scala.
  129. ^ Скотт, Кевин (11 марта 2015 г.). «Избавится ли LinkedIn от Scala?». quora.com. Получено 25 января 2016.
  130. ^ Хейл, Кода (29 ноября 2011 г.). "Остальная часть истории". codahale.com. Получено 7 ноября 2013.
  131. ^ "Chisel: создание оборудования на встроенном языке Scala | ASPIRE". Калифорнийский университет в Беркли APSIRE. Получено 27 мая 2020.

дальнейшее чтение