stringtranslate.com

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

Scala ( / ˈ s k ɑː l ɑː / SKAH -lah ) [7] [8] — это сильный статически типизированный язык программирования высокого уровня общего назначения , поддерживающий как объектно-ориентированное, так и функциональное программирование . Разработанный с целью быть кратким, [9] многие из проектных решений Scala направлены на устранение критики Java . [6]

Исходный код Scala может быть скомпилирован в байт-код Java и запущен на виртуальной машине Java (JVM). Scala также может быть транспилирован в JavaScript для запуска в браузере или скомпилирован непосредственно в собственный исполняемый файл. При запуске на JVM Scala обеспечивает языковое взаимодействие с Java, так что библиотеки, написанные на любом языке, могут быть напрямую связаны в коде Scala или Java. [10] Как и Java, Scala является объектно-ориентированным и использует синтаксис, называемый фигурными скобками , который похож на язык C. Начиная с Scala 3, есть также возможность использовать правило off-side (отступ) для структурирования блоков , и его использование рекомендуется. Мартин Одерски сказал, что это оказалось самым продуктивным изменением, введенным в Scala 3. [11]

В отличие от Java, Scala имеет много особенностей функциональных языков программирования (таких как Scheme , Standard ML и Haskell ), включая карринг , неизменяемость , ленивые вычисления и сопоставление с образцом . Он также имеет расширенную систему типов, поддерживающую алгебраические типы данных , ковариацию и контравариантность , типы более высокого порядка (но не типы более высокого ранга ), анонимные типы , перегрузку операторов , необязательные параметры , именованные параметры , необработанные строки и экспериментальную версию алгебраических эффектов, которая может рассматриваться как более мощная версия проверяемых исключений Java . [12]

Название Scala представляет собой сочетание слов scalable (масштабируемый) и language (язык) , что означает, что он разработан с возможностью роста в соответствии с потребностями пользователей. [13]

История

Разработка Scala началась в 2001 году в Федеральной политехнической школе Лозанны (EPFL) (в Лозанне , Швейцария ) Мартином Одерски . Она стала продолжением работы над Funnel, языком программирования, объединяющим идеи функционального программирования и сетей Петри . [14] Ранее Одерски работал над Generic Java и javac , компилятором Java от Sun. [14]

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

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

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

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

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

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

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

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

Эталонный компилятор Scala, ориентированный на .NET Framework и его Common Language Runtime, был выпущен в июне 2004 года [14] , но был официально прекращен в 2012 году [28].

Примеры

Пример "Привет, мир"

Программа Hello World, написанная на Scala 3, имеет следующий вид:

@main def main () = println ( "Привет, мир!" )    

В отличие от автономного приложения Hello World для Java , здесь нет объявления классов и ничего не объявлено статическим.

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

$ scalac HelloWorld.scala

и запускает его с помощью

$ скала HelloWorld

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

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

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

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

$ scala HelloWorld2.scala

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

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

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

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

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

Следующий пример показывает различия между синтаксисом Java и Scala. Функция mathFunction принимает целое число, возводит его в квадрат, а затем добавляет кубический корень этого числа к натуральному логарифму этого числа, возвращая результат (т. е. ):

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

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

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

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

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

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

Возможности (применительно к Java)

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

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

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

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

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

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

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

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

Для-выражений

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

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

val s = for ( x <- 1 to 25 if x * x > 50 ) yield 2 * x              

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

Vector(16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50)

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

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

// Дана карта, указывающая пользователей Twitter, упомянутых в наборе твитов, // и количество раз, когда каждый пользователь был упомянут, найдите пользователей // на карте известных политиков и верните новую карту, содержащую только // политиков-демократов (как объекты, а не строки). val dem_mentions = for ( mention , times ) <- mentions account <- accounts . get ( mention ) if account . party == "Democratic" yield ( account , times )                  

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

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

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

Вот примеры:

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

В отличие от C или Java , но подобно таким языкам, как Lisp , Scala не делает различий между операторами и выражениями . Все операторы на самом деле являются выражениями, которые вычисляют некоторое значение. Функции, которые были бы объявлены как возвращающие voidв C или Java, и такие операторы whileлогически не возвращают значение, в Scala считаются возвращающими тип Unit, который является синглтонным типом , с единственным объектом этого типа. Функции и операторы, которые вообще никогда не возвращают (например, throwоператор или функция, которая всегда завершается нелокально с помощью исключения), логически имеют возвращаемый тип Nothing, специальный тип, не содержащий объектов; то есть нижний тип , то есть подкласс каждого возможного типа. (Это, в свою очередь, делает тип Nothingсовместимым с каждым типом, позволяя правильно функционировать выводу типа .) [33]

Аналогично, if-then-else"оператор" на самом деле является выражением, которое производит значение, т. е. результат оценки одной из двух ветвей. Это означает, что такой блок кода может быть вставлен везде, где требуется выражение, устраняя необходимость в тернарном операторе в Scala:

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

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

def printValue ( x : String ): Unit = println ( "Я съел %s" . format ( x ))      

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

def printValue ( x : String ) = println ( "Я съел %s" format x )      

Вывод типа

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

def formatApples ( x : Int ) = "Я съел %d яблок" . format ( x )    

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

def factorial ( x : Int ): Int = если x == 0 , то 1 , иначе x * factorial ( x - 1 )                

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

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

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

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

list map { x => sqrt(x) }

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

list map { sqrt(_) }

или даже

list map sqrt

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

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

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

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

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

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

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


Примером такой оптимизации может служить определение факториала . Например, рекурсивная версия факториала:

def factorial ( n : Int ): Int = если n == 0 , то 1 , иначе n * factorial ( n - 1 )                

Можно оптимизировать версию с хвостовой рекурсией следующим образом:

@tailrec def факториал ( n : Int , accum : Int ): Int = если n == 0, то накапливается иначе факториал ( n - 1 , n * accum )                    

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

def факториал ( n : Int ): Int =      @tailrec цикл def ( текущий : Int , накопленный : Int ): Int =         если n == 0, то аккумулировать      цикл else ( текущий - 1 , n * накопление )        loop ( n , 1 ) // Вызов замыкания с использованием базового случая   конечный факториал 

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

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

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

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

def qsort ( list : List [ Int ]): List [ Int ] = list match case Nil => Nil case pivot :: tail => val ( lesser , rest ) = tail . partition ( _ < pivot ) qsort ( lesser ) ::: pivot :: qsort ( rest )                            

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

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

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

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

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

qsort(smaller) ::: pivot :: qsort(rest)

можно также записать так:

qsort(rest).::(pivot).:::(qsort(smaller))

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

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

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

попробуйте ... поймать случай nfe : NumberFormatException => { println ( nfe ); Список ( 0 ) } случай _ => Ноль               

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

val qsort : List [ Int ] => List [ Int ] = case Nil => Nil case pivot :: tail => val ( lesser , rest ) = tail . partition ( _ < pivot ) qsort ( lesser ) ::: pivot :: qsort ( rest )                           

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

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

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

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

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

абстрактный класс Window : // абстрактный def draw ()     class SimpleWindow extends Window : def draw () println ( "in SimpleWindow" ) // рисуем простое окно         черта WindowDecoration расширяет Window   trait HorizontalScrollbarDecoration extends WindowDecoration : // "abstract override" здесь необходим для работы "super()", потому что родительская // функция абстрактна. Если бы она была конкретной, обычного " override" было бы достаточно. abstract override def draw () println ( "in HorizontalScrollbarDecoration" ) super.draw () // теперь рисуем горизонтальную полосу прокрутки              черта VerticalScrollbarDecoration расширяет WindowDecoration : abstract override def draw () println ( "in VerticalScrollbarDecoration" ) super.draw () // теперь рисуем вертикальную полосу прокрутки            черта TitleDecoration расширяет WindowDecoration : abstract override def draw () println ( "in TitleDecoration" ) super.draw ( ) // теперь рисуем заголовок           

Переменная может быть объявлена ​​следующим образом:

val mywin = new SimpleWindow с VerticalScrollbarDecoration с HorizontalScrollbarDecoration с TitleDecoration          

Результат вызова mywin.draw():

в TitleDecoration в HorizontalScrollbarDecoration в VerticalScrollbarDecoration в SimpleWindow    

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

Система экспрессивных шрифтов

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

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

Тип обогащения

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

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

Следующий пример демонстрирует обогащение типа Intметодами isEvenи isOdd:

объект MyExtensions : расширение ( i : Int ) def isEven = i % 2 == 0 def isOdd = ! я . isEven                 import MyExtensions . * // внести неявное обогащение в область действия 4 . isEven // -> true   

Импорт членов MyExtensionsприводит к неявному преобразованию в класс расширения IntPredicatesв область действия. [42]

Параллелизм

Стандартная библиотека Scala включает поддержку futures и promises , в дополнение к стандартным API Java concurrency. Первоначально она также включала поддержку модели акторов , которая теперь доступна как отдельная исходная платформа Akka [43] лицензированная Lightbend Inc. Акторы Akka могут быть распределены или объединены с программной транзакционной памятью ( транзакторами ). Альтернативные реализации коммуникационных последовательных процессов (CSP) для передачи сообщений на основе каналов — это Communicating Scala Objects, [44] или просто через JCSP .

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

val echoServer = actor ( new Act : become : case msg => println ( "echo " + msg ) )           echoServer ! "привет"  

Scala также поставляется со встроенной поддержкой программирования параллельных данных в форме параллельных коллекций [46], интегрированных в его стандартную библиотеку, начиная с версии 2.9.0.

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

val urls = Список ( "https://scala-lang.org" , "https://github.com/scala/scala" )    def fromURL ( url : String ) = scala.io.Source.fromURL ( url ) .getLines ( ) . mkString ( " \ n " )     val t = System . currentTimeMillis () urls . par . map ( fromURL ( _ )) // par возвращает параллельную реализацию коллекции println ( "time: " + ( System . currentTimeMillis - t ) + "ms" )          

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

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

Наиболее известным решением кластерных вычислений с открытым исходным кодом, написанным на Scala, является Apache Spark . Кроме того, Apache Kafka , очередь сообщений «публикация-подписка», популярная в Spark и других технологиях потоковой обработки, написана на Scala.

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

Существует несколько способов тестирования кода в Scala. ScalaTest поддерживает несколько стилей тестирования и может интегрироваться с фреймворками тестирования на основе Java. [49] ScalaCheck — это библиотека, похожая на QuickCheck в Haskell . [50] specs2 — это библиотека для написания спецификаций исполняемого программного обеспечения. [51] ScalaMock обеспечивает поддержку тестирования функций высокого порядка и каррированных функций. [52] JUnit и TestNG — популярные фреймворки тестирования, написанные на Java.

Версии

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

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

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

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

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

Принятие

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

Еще в 2013 году, когда Scala была в версии 2.10, ThoughtWorks Technology Radar, который представляет собой основанный на мнении двухгодичный отчет группы старших технических специалистов, [139] рекомендовал внедрение Scala в своей категории языков и фреймворков. [140]

В июле 2014 года эта оценка была конкретизирована и теперь относится к «Scala, хорошим частям», что описывается как «Чтобы успешно использовать Scala, вам необходимо исследовать язык и иметь очень твердое мнение о том, какие части подходят именно вам, создавая свое собственное определение Scala, хороших частей». [141]

В выпуске опроса State of Java 2018 года [142] , в котором были собраны данные 5160 разработчиков по различным темам, связанным с Java, Scala занимает третье место по использованию альтернативных языков на JVM . По сравнению с выпуском опроса предыдущего года использование Scala среди альтернативных языков JVM упало с 28,4% до 21,5%, уступив место Kotlin , который вырос с 11,4% в 2017 году до 28,8% в 2018 году. Индекс популярности языков программирования [143] , который отслеживает поиски руководств по языкам, поставил Scala на 15-е место в апреле 2018 года с небольшой тенденцией к снижению и на 17-е место в январе 2021 года. Это делает Scala третьим по популярности языком на основе JVM после Java и Kotlin , занявших 12-е место.

Рейтинг языков программирования RedMonk, который составляет рейтинги на основе количества проектов GitHub и вопросов, заданных на Stack Overflow , в январе 2021 года поставил Scala на 14-е место. [ 144] Здесь Scala был помещен в группу языков второго уровня — впереди Go , PowerShell и Haskell и позади Swift , Objective-C , Typescript и R.

Индекс популярности языков программирования TIOBE [145] использует рейтинги поисковых систем в Интернете и аналогичный подсчет публикаций для определения популярности языка. В сентябре 2021 года он показал Scala на 31-м месте. В этом рейтинге Scala опередил Haskell (38-е место) и Erlang , но уступил Go (14-е место), Swift (15-е место) и Perl (19-е место).

По состоянию на 2022 год языки на основе JVM, такие как Clojure, Groovy и Scala, занимают высокие позиции, но все еще значительно менее популярны, чем исходный язык Java , который обычно занимает первые три места. [144] [145]

Компании

Критика

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

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

Ссылки

  1. ^ https://www.scala-lang.org/download/3.5.0.html. {{cite web}}: Отсутствует или пусто |title=( помощь )
  2. ^ "Файл уведомления". GitHub . 2019-01-24 . Получено 2019-12-04 .
  3. ^ «Макросы Scala».
  4. ^ Фогус, Майкл (6 августа 2010 г.). "MartinOdersky take(5) toList". Отправить еще парамедиков . Получено 2012-02-09 .
  5. ^ abcd Одерски, Мартин (11 января 2006 г.). «Эксперимент Scala — можем ли мы обеспечить лучшую языковую поддержку для компонентных систем?» (PDF) . Получено 22.06.2016 .
  6. ^ abcd Одерский, Мартин; и др. (2006). «Обзор языка программирования Scala» (PDF) (2-е изд.). Федеральная политехническая школа Лозанны (EPFL). Архивировано (PDF) из оригинала 9 июля 2020 г.
  7. ^ Одерски, Мартин (2008). Программирование на Scala. Маунтин-Вью, Калифорния: Artima. стр. 3. ISBN 9780981531601. Получено 12 июня 2014 г.
  8. ^ Уомплер, Дин; Пейн, Алекс (15 сентября 2009 г.). Программирование Scala: Масштабируемость = Функциональное программирование + Объекты. O'Reilly Media, Inc. стр. 7. ISBN 978-1-4493-7926-1. Получено 13 мая 2024 г. Создатели Scala на самом деле произносят его как scah-lah , как итальянское слово «лестница». Две «a» произносятся одинаково.
  9. ^ Потвин, Паскаль; Бонья, Марио (24 сентября 2015 г.). SDL 2013: Model-Driven Dependability Engineering . Lecture Notes in Computer Science. Vol. 7916. arXiv : 1509.07326 . doi :10.1007/978-3-642-38911-5. ISBN 978-3-642-38910-8. S2CID  1214469.
  10. ^ "Часто задаваемые вопросы: совместимость с Java". Scala-lang.org . Получено 2015-02-06 .
  11. ^ Мартин Одерски (17 июня 2020 г.). Мартин Одерски: Обновление Scala 3 (видео). YouTube. Событие происходит в 36:35–45:08. Архивировано из оригинала 21.12.2021 . Получено 24.04.2021 .
  12. ^ "Effect expt". scala . Получено 2022-07-31 .
  13. ^ Ловердо, Христос (2010). Шаги в Scala: Введение в объектно-функциональное программирование. Cambridge University Press . стр. xiii. ISBN 9781139490948. Получено 31 июля 2014 г.
  14. ^ abcd Одерски, Мартин (9 июня 2006 г.). «Краткая история Scala». Artima.com .
  15. ^ abcd Одерски, М.; Ромпф, Т. (2014). «Унификация функционального и объектно-ориентированного программирования с помощью Scala». Сообщения ACM . 57 (4): 76. doi : 10.1145/2591013 .
  16. ^ Мартин Одерски, «Спецификация языка Scala версии 2.7»
  17. ^ "Scala Team Wins ERC Grant" . Получено 4 июля 2015 г. .
  18. ^ "Коммерческая поддержка Scala". 2011-05-12 . Получено 2011-08-18 .
  19. ^ «Почему мы инвестировали в Typesafe: современные приложения требуют современных инструментов». 2011-05-12 . Получено 2018-05-08 .
  20. ^ "Открытый исходный код Scala получает коммерческую поддержку". 2011-05-12 . Получено 2011-10-09 .
  21. ^ "Пионер облачных вычислений Мартин Одерски представляет свою новую компанию Typesafe". 2011-05-12 . Получено 2011-08-24 .
  22. ^ "Scala на Android". Архивировано из оригинала 20 июня 2016 года . Получено 8 июня 2016 года .
  23. ^ "Scala 2.12.8 уже доступна!". 2018-12-04 . Получено 2018-12-09 .
  24. ^ "Scala Js больше не экспериментальный | Язык программирования Scala". Scala-lang.org . Получено 28 октября 2015 г. .
  25. ^ "Релизы · scala-js/Scala-js". GitHub .
  26. ^ Крилл, Пол (15 марта 2017 г.). «Уменьшенный вариант Scala сокращает связи с JVM». InfoWorld . Получено 21 марта 2017 г. .
  27. ^ Крилл, Пол (2016-05-11). «Язык Scala приближается к голому железу». InfoWorld .
  28. ^ Удален бэкэнд .net. paulp · Запрос на извлечение #1718 · scala/scala · GitHub. Github.com (2012-12-05). Получено 2013-11-02.
  29. ^ "Начало работы со Scala". Scala-lang.org . 15 июля 2008 г. Получено 31 июля 2014 г.
  30. ^ "Home". Blog.lostlake.org. Архивировано из оригинала 31 августа 2010 года . Получено 25 июня 2013 года .
  31. ^ Встроенные структуры управления Scala, такие как ifили whileне могут быть повторно реализованы. Существует исследовательский проект Scala-Virtualized, направленный на устранение этих ограничений: Adriaan Moors, Tiark Rompf, Philipp Haller и Martin Odersky. Scala-Virtualized. Труды семинара ACM SIGPLAN 2012 по частичной оценке и манипулированию программами , 117–120. Июль 2012 г.
  32. ^ ab "Pimp my Library". Artima.com. 2006-10-09 . Получено 2013-06-25 .
  33. ^ "Выражения | Scala 2.13". scala-lang.org . Получено 2021-05-24 .
  34. ^ "Mutable and Immutable Collections - Scala Documentation" . Получено 30 апреля 2020 г. .
  35. ^ "Коллекции - Конкретные неизменяемые классы коллекций - Документация Scala" . Получено 4 июля 2015 г. .
  36. ^ Доэрти, Рич. "Блог Рича Доэрти" . Получено 4 июля 2015 г.
  37. ^ "TailCalls - API стандартной библиотеки Scala (Scaladoc) 2.10.2 - scala.util.control.TailCalls". Scala-lang.org . Получено 25.06.2013 .
  38. ^ ab «Системы типов Java и Scala ненадежны» (PDF) .
  39. ^ Giarrusso, Paolo G. (2013). "Reify your collection requests for moduleity and speed!". Труды 12-й ежегодной международной конференции по аспектно-ориентированной разработке программного обеспечения . ACM. arXiv : 1210.6284 . Bibcode :2012arXiv1210.6284G. Также известен как шаблон pimp-my-library
  40. ^ Гилберт, Клинт (15.11.2011). «Что является наивысшим приоритетом для успеха Scala в корпоративном мире (должно быть в scala-debate?)?». Scala-lang.org . Получено 08.05.2019 .
  41. ^ «Должны ли мы «обогащать» или «прокачивать» библиотеки Scala?». stackexchange.com . 17 июня 2013 г. Получено 15 апреля 2016 г.
  42. ^ Неявные классы были введены в Scala 2.10, чтобы сделать расширения методов более лаконичными. Это эквивалентно добавлению метода implicit def IntPredicate(i: Int) = new IntPredicate(i). Класс также может быть определен как implicit class IntPredicates(val i: Int) extends AnyVal { ... }, создавая так называемый класс значений , также введенный в Scala 2.10. Затем компилятор исключит фактические инстанциации и сгенерирует вместо них статические методы, что позволит методам расширения практически не иметь накладных расходов на производительность.
  43. ^ Что такое Akka?, Онлайн-документация Akka.
  44. ^ Sufrin, Bernard (2008). "Communicating Scala Objects". В Welch, PH; Stepney, S.; Polack, FAC; Barnes, FRM; McEwan, AA; Stiles, GS; Broenink, JF; Sampson, AT (ред.). Communicating Process Architectures 2008: WoTUG-31 (PDF) . IOS Press. ISBN 978-1586039073.
  45. ^ Ян, Кей. "Scala Tour" . Получено 4 июля 2015 г.
  46. ^ "Parallelcollections - Обзор - Документация Scala". Docs.scala-lang.org . Получено 25.06.2013 .
  47. ^ Ян, Кей. "Scala Tour" . Получено 4 июля 2015 г.
  48. ^ Изучение параллельного программирования в Scala, Александр Прокопец, Packt Publishing
  49. ^ Копс, Миха (13.01.2013). "Краткое введение в ScalaTest". hascode.com . Получено 07.11.2014 .
  50. ^ Нильссон, Рикард (17.11.2008). "ScalaCheck 1.5". Scala-lang.org . Получено 07.11.2014 .
  51. ^ "Создание веб-приложений с использованием Scala и Play Framework". workwithplay.com . 2013-05-22 . Получено 2014-11-07 .
  52. ^ Бутчер, Пол (2012-06-04). "ScalaMock 3.0 Preview Release". paulbutcher.com . Архивировано из оригинала 2014-11-08 . Получено 2014-11-07 .
  53. ^ abcdefg "История изменений Scala". Scala-lang.org . Архивировано из оригинала 2007-10-09.
  54. ^ "Удалено: XML-литералы". dotty.epfl.ch . Получено 2021-03-05 .
  55. ^ "Изменения в версии 2.0 (12 марта 2006 г.)". Scala-lang.org . 2006-03-12 . Получено 2014-11-07 .
  56. ^ "Изменения в версии 2.1.8 (23 августа 2006 г.)". Scala-lang.org . 2006-08-23 . Получено 2014-11-07 .
  57. ^ "Изменения в версии 2.3.0 (23 ноября 2006 г.)". Scala-lang.org . 2006-11-23 . Получено 2014-11-07 .
  58. ^ "Изменения в версии 2.4.0 (09-мар-2007)". Scala-lang.org . 2007-03-09 . Получено 2014-11-07 .
  59. ^ "Изменения в версии 2.5 (02-May-2007)". Scala-lang.org . 2007-05-02 . Получено 2014-11-07 .
  60. ^ "Изменения в версии 2.6 (27 июля 2007 г.)". Scala-lang.org . 2007-06-27 . Получено 2014-11-07 .
  61. ^ "Изменения в версии 2.7.0 (07-фев-2008)". Scala-lang.org . 2008-02-07 . Получено 2014-11-07 .
  62. ^ "Изменения в версии 2.8.0 (14 июля 2010 г.)". Scala-lang.org . 2010-07-10 . Получено 2014-11-07 .
  63. ^ "Изменения в версии 2.9.0 (12 мая 2011 г.)". Scala-lang.org . 2011-05-12 . Получено 2014-11-07 .
  64. ^ "Изменения в версии 2.10.0". Scala-lang.org . 2013-01-04 . Получено 2014-11-07 .
  65. ^ Харра, Марк. «Классы ценностей и универсальные черты». Scala-lang.org . Получено 2014-11-07 .
  66. ^ Suereth, Josh. "SIP-13 - Неявные классы". Scala-lang.org . Архивировано из оригинала 2014-11-08 . Получено 2014-11-07 .
  67. ^ Suereth, Josh. "String Interpolation". Scala-lang.org . Получено 2014-11-07 .
  68. ^ Халлер, Филипп; Прокопец, Александр. «Будущее и обещания». Scala-lang.org . Получено 2014-11-07 .
  69. ^ "SIP-17 - Тип Dynamic". Scala-lang.org . Архивировано из оригинала 2014-11-08 . Получено 2014-11-07 .
  70. ^ "SIP-18 - Modularizing Language Features". Scala-lang.org . Архивировано из оригинала 2014-11-08 . Получено 2014-11-07 .
  71. ^ Прокопец, Александр; Миллер, Хизер. «Параллельные коллекции». Scala-lang.org . Получено 2014-11-07 .
  72. ^ Миллер, Хизер; Бурмако, Юджин. «Обзор отражения». Scala-lang.org . Получено 2014-11-07 .
  73. ^ Бурмако, Юджин. "Def Macros". Scala-lang.org . Получено 2014-11-07 .
  74. ^ "Scala 2.10.2 уже доступна!". Scala-lang.org . 2013-06-06. Архивировано из оригинала 2014-11-08 . Получено 2014-11-07 .
  75. ^ "Scala 2.10.3 уже доступна!". Scala-lang.org . 2013-10-01. Архивировано из оригинала 2014-11-08 . Получено 2014-11-07 .
  76. ^ "Scala 2.10.4 уже доступна!". Scala-lang.org . 2014-03-18 . Получено 2015-01-07 .
  77. ^ "Scala 2.10.5 уже доступна!". Scala-lang.org . 2015-03-04 . Получено 2015-03-23 .
  78. ^ "Scala 2.11.0 уже доступна!". Scala-lang.org . 2014-04-21 . Получено 2014-11-07 .
  79. ^ "Scala 2.11.1 уже доступна!". Scala-lang.org . 2014-05-20 . Получено 07.11.2014 .
  80. ^ "Scala 2.11.2 уже доступна!". Scala-lang.org . 2014-07-22 . Получено 2014-11-07 .
  81. ^ "Scala 2.11.4 уже доступна!". Scala-lang.org . 2014-10-30 . Получено 2014-11-07 .
  82. ^ "Scala 2.11.5 уже доступна!". Scala-lang.org . 2015-01-08 . Получено 2015-01-22 .
  83. ^ "Scala 2.11.6 уже доступна!". Scala-lang.org . 2015-03-05 . Получено 2015-03-12 .
  84. ^ "Scala 2.11.7 уже доступна!". Scala-lang.org . 2015-06-23 . Получено 2015-07-03 .
  85. ^ "Scala 2.11.8 уже доступна!". Scala-lang.org . 2016-03-08 . Получено 2016-03-09 .
  86. ^ ab "Три новых релиза и еще больше GitHub-блага!". Scala-lang.org . 2017-04-18 . Получено 2017-04-19 .
  87. ^ "Обновление безопасности: 2.12.4, 2.11.12, 2.10.7 (CVE-2017-15288)". Scala-lang.org . 2017-11-13 . Получено 2018-05-04 .
  88. ^ "Scala 2.12.0 уже доступна!". Scala-lang.org . 2016-11-03 . Получено 2017-01-08 .
  89. ^ "Scala 2.12.1 уже доступна!". Scala-lang.org . 2016-12-05 . Получено 2017-01-08 .
  90. ^ "Scala 2.12.3 уже доступна!". Scala-lang.org . 2017-07-26 . Получено 2017-08-16 .
  91. ^ "Scala 2.12.4 уже доступна!". Scala-lang.org . 2017-10-18 . Получено 2017-10-26 .
  92. ^ "Scala 2.12.5 уже доступна!". Scala-lang.org . 2018-03-15 . Получено 2018-03-20 .
  93. ^ "Scala 2.12.6 уже доступна!". Scala-lang.org . 2018-04-27 . Получено 2018-05-04 .
  94. ^ "Scala 2.12.7 уже доступна!". Scala-lang.org . 2018-09-27 . Получено 2018-10-09 .
  95. ^ "Scala 2.12.8 уже доступна!". Scala-lang.org . 2018-12-04 . Получено 2018-12-09 .
  96. ^ "Scala 2.12.9 уже доступна!". Scala-lang.org . 2019-08-05 . Получено 2021-01-20 .
  97. ^ "Scala 2.12.10 уже доступна!". Scala-lang.org . 2019-09-10 . Получено 2021-01-20 .
  98. ^ "Scala 2.12.11 уже доступна!". Scala-lang.org . 2020-03-16 . Получено 2021-01-20 .
  99. ^ "Scala 2.12.12 уже доступна!". Scala-lang.org . 2020-07-13 . Получено 2021-01-20 .
  100. ^ "Scala 2.12.13 уже доступна!". Scala-lang.org . 2021-01-12 . Получено 2021-01-20 .
  101. ^ "Scala 2.12.14 уже доступна!". Scala-lang.org . 2021-05-28 . Получено 2022-04-15 .
  102. ^ "Scala 2.12.15 уже доступна!". Scala-lang.org . 2021-09-14 . Получено 2022-06-19 .
  103. ^ "Scala 2.12.16 уже доступна!". Scala-lang.org . 2022-06-10 . Получено 2022-06-19 .
  104. ^ "Scala 2.12.17 уже доступна!". Scala-lang.org . 2022-06-10 . Получено 2022-09-16 .
  105. ^ "Scala 2.12.18 уже доступна!". Scala-lang.org . 2022-06-10 . Получено 2023-06-07 .
  106. ^ "Scala 2.12.19 уже доступна!". Scala-lang.org . 2024-02-25 . Получено 2024-08-12 .
  107. ^ "Scala 2.13.0 уже доступна!". Scala-lang.org . 2019-06-11 . Получено 2018-06-17 .
  108. ^ "Scala 2.13.1 уже доступна!". Scala-lang.org . 2019-09-18 . Получено 2021-01-20 .
  109. ^ "Scala 2.13.2 уже доступна!". Scala-lang.org . 2020-04-22 . Получено 2021-01-20 .
  110. ^ "Scala 2.13.3 уже доступна!". Scala-lang.org . 2020-06-25 . Получено 2021-01-20 .
  111. ^ "Scala 2.13.4 уже доступна!". Scala-lang.org . 2020-11-19 . Получено 2021-01-20 .
  112. ^ "Scala 2.13.5 уже доступна!". Scala-lang.org . 2021-02-22 . Получено 2021-02-26 .
  113. ^ "Scala 2.13.6 уже доступна!". Scala-lang.org . 2021-05-17 . Получено 2022-04-15 .
  114. ^ "Scala 2.13.7 уже доступна!". Scala-lang.org . 2021-11-01 . Получено 2022-04-15 .
  115. ^ "Scala 2.13.8 уже доступна!". Scala-lang.org . 2022-01-12 . Получено 2022-04-15 .
  116. ^ "Scala 2.13.9 уже доступна!". Scala-lang.org . 2022-09-21 . Получено 2023-08-28 .
  117. ^ "Scala 2.13.10 уже доступна!". Scala-lang.org . 2022-10-13 . Получено 2023-08-28 .
  118. ^ "Scala 2.13.11 уже доступна!". Scala-lang.org . 2023-06-07 . Получено 2023-08-28 .
  119. ^ "Scala 2.13.12 уже доступна!". Scala-lang.org . 2023-09-11 . Получено 2024-08-12 .
  120. ^ "Scala 2.13.13 уже доступна!". Scala-lang.org . 2024-02-26 . Получено 2024-08-12 .
  121. ^ "Scala 2.13.14 уже доступна!". Scala-lang.org . 2024-05-01 . Получено 2024-08-12 .
  122. ^ "Scala 3 уже здесь!". Scala-lang.org . 2021-05-14 . Получено 2021-05-26 .
  123. ^ "Scala 3.0.1 и 3.0.2-RC1 уже здесь!". Scala-lang.org . 2021-07-31 . Получено 2024-08-12 .
  124. ^ "Scala 3.0.2 выпущен!". Scala-lang.org . 2021-09-07 . Получено 2024-08-12 .
  125. ^ "Scala 3.1.0 выпущен!". Scala-lang.org . 2021-10-21 . Получено 2024-08-12 .
  126. ^ "Scala 3.1.1 и новости о прямой совместимости". Scala-lang.org . 2022-02-01 . Получено 2024-08-12 .
  127. ^ "Scala 3.1.2 выпущена!". Scala-lang.org . 2022-04-12 . Получено 2024-08-12 .
  128. ^ "Scala 3.1.3 выпущен!". Scala-lang.org . 2022-06-21 . Получено 2024-08-12 .
  129. ^ "Scala 3.2.0 выпущен!". Scala-lang.org . 2022-09-05 . Получено 2024-08-12 .
  130. ^ "Scala 3.2.1 выпущен!". Scala-lang.org . 2022-11-07 . Получено 2024-08-12 .
  131. ^ "Scala 3.2.2 уже доступна!". Scala-lang.org . 2023-01-30 . Получено 2024-08-12 .
  132. ^ "Scala 3.3.0 выпущен!". Scala-lang.org . 2023-05-30 . Получено 2024-08-12 .
  133. ^ "Scala 3.3.1 LTS уже доступна!". Scala-lang.org . 2023-09-07 . Получено 2024-08-12 .
  134. ^ "Scala 3.3.2". github.com . 2024-02-29 . Получено 2024-08-12 .
  135. ^ "Scala 3.4.0 и 3.3.3 LTS выпущены!". Scala-lang.org . 2024-02-29 . Получено 2024-08-12 .
  136. ^ "Scala 3.4.0 и 3.3.3 LTS выпущены!". Scala-lang.org . 2024-02-29 . Получено 2024-08-12 .
  137. ^ "Scala 3.4.1 уже доступна!". Scala-lang.org . 2024-03-29 . Получено 2024-08-12 .
  138. ^ "Scala 3.4.2 уже доступна!". Scala-lang.org . 2024-05-16 . Получено 2024-08-12 .
  139. ^ «Часто задаваемые вопросы о радаре ThoughtWorks Technology».
  140. ^ "Технологический радар ThoughtWorks МАЙ 2013" (PDF) .
  141. ^ «Scala, хорошие стороны».
  142. ^ «Состояние Явы в 2018 году».
  143. ^ «Индекс популярности языков программирования».
  144. ^ ab O'Grady, Stephen (1 марта 2021 г.). «Рейтинг языков программирования RedMonk: январь 2021 г.». RedMonk .
  145. ^ ab "Индекс TIOBE за май 2021 года".
  146. ^ Грин, Кейт (1 апреля 2009 г.). «Секрет роста Twitter. Как новый язык веб-программирования помогает компании справиться с растущей популярностью». Technology Review . MIT . Получено 6 апреля 2009 г.
  147. ^ Брек, Колин; Линк, Перси (2020-03-23). ​​"Виртуальная электростанция Tesla (архитектура и дизайн)" . Получено 2023-03-28 .
  148. ^ "Исходный код Apache Kafka на GitHub". Apache Software Foundation . Получено 29 марта 2023 г.
  149. ^ "Play Framework, Akka и Scala в Gilt Groupe". Lightbend. 15 июля 2013 г. Получено 16 июля 2016 г.
  150. ^ "Scala, Lift, and the Future". Архивировано из оригинала 13 января 2016 года . Получено 4 июля 2015 года .
  151. ^ Saeta, Brennan (2014-02-17). "Почему мы любим Scala в Coursera". Coursera Engineering . Получено 2023-09-21 .
  152. ^ "Apple Engineering PM Джаррод Неттлз в Twitter". Джаррод Неттлз . Получено 2016-03-11 .
  153. ^ "30 вакансий Scala в Apple". Элвин Александр . Получено 2016-03-11 .
  154. ^ Дэвид Рид и Таня Тейшейра (26 февраля 2010 г.). «Готовы ли люди платить за онлайн-новости?». BBC . Получено 28.02.2010 .
  155. ^ "Guardian переключается с Java на Scala". Heise Online . 2011-04-05 . Получено 2011-04-05 .
  156. ^ "Guardian.co.uk Переход с Java на Scala". InfoQ.com. 2011-04-04 . Получено 2011-04-05 .
  157. ^ Рой, Суман; Сундаресан, Кришна (2014-05-13). «Создание Blackbeard: система синдикации на базе Play, Scala и Akka». The New York Times . Получено 20 июля 2014 г.
  158. ^ Pavley, John (2013-08-11). "Краткий обзор: HuffPost обеспечивает совместную работу в режиме реального времени в редакции". Huffington Post . Получено 20 июля 2014 г.
  159. ^ Бинсток, Эндрю (2011-07-14). "Интервью с Мартином Одерски из Scala". Журнал доктора Добба . Получено 2012-02-10 .
  160. ^ Синодинос, Дионисиос Г. (11 октября 2010 г.). «LinkedIn Signal: пример Scala, JRuby и Voldemort». InfoQ .
  161. ^ «Реальные встречи заслуживают API реального времени».
  162. ^ «В веб-приложении Remember The Milk появилась функция обновления в режиме реального времени».
  163. ^ "ЧТО ТАКОЕ SCALA". 8 марта 2023 г. Получено 17.03.2023 .
  164. ^ Новет, Джордан (2015-06-04). "Airbnb анонсирует Aerosolve, пакет программного обеспечения для машинного обучения с открытым исходным кодом" . Получено 2016-03-09 .
  165. ^ Копс, Александр (14.12.2015). "Zalando Tech: от Java до Scala менее чем за три месяца" . Получено 09.03.2016 .
  166. ^ Calçado, Phil (2014-06-13). "Создание продуктов в SoundCloud — Часть III: Микросервисы в Scala и Finagle" . Получено 2016-03-09 .
  167. ^ "Исследования случаев клиентов: SoundCloud". Concurrent Inc. 2014-11-18 . Получено 2016-03-09 .
  168. ^ Scala в Morgan Stanley (видео). Навыки имеют значение. 2015-12-03 . Получено 2016-03-11 .
  169. ^ Грег Солтис (2015-12-03). SF Scala, Грег Солтис: Высокопроизводительные сервисы в Scala (видео). Навыки имеют значение. Архивировано из оригинала 2021-12-21 . Получено 2016-03-11 .
  170. ^ Ли Майдолл. "Работа Scala в Nest" . Получено 11.03.2016 .
  171. ^ Нурун. «Нурун запускает переработанную транзакционную платформу с Walmart Canada» . Получено 11 декабря 2013 г.
  172. ^ Хори, Андре К. (2017-01-31). "Переписываем движок Duolingo на Scala" . Получено 2017-02-03 .
  173. ^ "Репозиторий HMRC GitHub". GitHub .
  174. ^ "Встречайте M1 Finance, золотого спонсора ScalaCon". ScalaCon . Получено 2023-09-02 .
  175. Хейл, Кода (29 ноября 2011 г.). «Остальная часть истории». codahale.com . Получено 7 ноября 2013 г. .
  176. ^ Крикориан, Раффи (17 марта 2015 г.). Полная видеоподборка конференции O'Reilly Software Architecture Conference 2015: Re-Architecting on the Fly - Raffi Krikorian - Часть 3 (видео). O'Reilly Media. Событие происходит в 4:57 . Получено 8 марта 2016 г. Что бы я сделал по-другому четыре года назад, так это использовал Java и не использовал Scala в рамках этой переделки. [...] инженеру потребовалось бы два месяца, прежде чем он стал бы полностью продуктивным и начал писать код Scala.[ постоянная мертвая ссылка ]
  177. ^ Скотт, Кевин (11 марта 2015 г.). «LinkedIn избавляется от Scala?». quora.com . Получено 25 января 2016 г.
  178. ^ "Chisel: Constructing Hardware in a Scala Embedded Language". UC Berkeley APSIRE . Получено 27 мая 2020 г.

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