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

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 13:29, 29 декабря 2016.
Scala
fraimed
Спроектировано Мартин Одерски
Печать дисциплины Статическая, Строгая, Струтурная, С автовыведением типов
OS Кроссплатформенное
Лицензия Лицензия BSD
Портал: http://www.scala-lang.org/
Под влиянием
Java, Haskell, Erlang, Standard ML, Objective Caml, Smalltalk, Scheme, Lisp, Algol 68
Влияние
Kotlin

Scala — (произносится skaɪl) мультипарадигмальный язык программирования, сочетающий возможности функционального и объектно-ориентированного программирования[1].

История

Язык был создан в 2001—2004 годах в Лаборатории методов программирования EPFL. Он стал результатом исследований, направленных на разработку улучшенной языковой поддержки компонентного ПО. За основу при разработке языка были взяты 2 идеи:

  1. Язык программирования компонентного ПО должен быть масштабируемым в том смысле, что должна быть возможность с помощью одних и тех же концепций описать как маленькие, так и большие части. Поэтому внимание было сконцентрировано на механизмах абстракции, композиции и декомпозиции вместо введения большого количества примитивов, которые могут быть полезными только на каком-то одном уровне масштабирования.
  2. Масштабируемая поддержка компонентов может быть предоставлена языком программирования, унифицирующим и обобщающим объектно-ориентированное и функциональное программирование. Некоторые из основных технических новшеств Scala — это концепции, представляющие собой сплав этих парадигм программирования. В статически типизированных языках, к которым относится Scala, эти парадигмы до сих пор были почти полностью разделены.

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

Объектно-ориентированный язык

В Scala используется чистая объектно-ориентированная модель, похожая на применяемую в Smalltalk: каждое значение — это объект, и каждая операция — это отправка сообщения. Например, сложение интерпретируется как , то есть как вызов метода + с аргументом y и x в качестве объекта-приёмника. Рассмотрим другой пример: . Это выражение интерпретируется как .Обратите внимание, что скобки вокруг чисел обязательны, потому что лексический анализатор Scala разбивает выражение на лексемы по принципу самого длинного возможного сопоставления. Таким образом, выражение разобьется на лексемы , и , потому что лексема 1. длиннее лексемы 1 и первый аргумент сложения будет интерпретирован, как тип Double вместо Int.

Функциональный язык

Каждая функция — это значение. Язык предоставляет легковесный синтаксис для определения анонимных и карринговых функций. Каждая конструкция возвращает значение. Сопоставление с образцом естественно расширяется к обработке XML c помощью регулярных выражений.

Интеграция

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

Классы и объекты в Scala могут наследовать от Java-классов и реализовать Java-интерфейсы. Это позволяет использовать Scala-код во фреймворке Java. Например, Scala-класс мог бы реализовывать интерфейс java.util.EventListener. Экземпляры этого класса затем можно оповещать о событиях, поступающих от Java-кода.

Особенности языка

Пример № 1

В качестве первого пример мы возьмём стандартную программу Hello World.

object HelloWorld 
{
   def main(args: Array[String]) 
   {
      println("Hello, world!")
   }
}

Структура такой программы состоит из main-метода, который получает аргументы командной строки в виде массива строк в качестве параметров. Тело метода состоит из единственного метода println, в качестве аргумента которому передаётся «Hello, World!». Метод main ничего не возвращает, поэтому нет необходимости явно указывать тип возвращаемых данных. Слово object обозначает то, что обычно называют синглетоном (singleton) -- это класс, объект которого может существовать лишь в одном экземпляре. Такое обозначение определяет сразу и класс HelloWorld и объект этого класса, который тоже называется HelloWorld. Этот объект будет создаваться по первому требованию, в момент первого его использования. main не объявлен как static. Это потому, что в Scala нет статических членов (методов или полей класса). Вместо определения статических членов, Scala программист объявит их в синглтон объектах.

Всё является объектами

В Scala всё является объектами, включая числа или функции. Этим Scala отличается от Java, поскольку в Java разделены примитивные типа (например boolean или int) и ссылочные типы, а также нет возможности работать с функциями как со значением. Числа – это объекты Поскольку числа являются объектами, они также имеют методы. На самом деле, следующее арифметическое выражение:


состоит исключительно из вызовов методов и эквиваленто следующему выражению:


Это также означает, что символы +, * – валидные идентификаторы в Scala. Скобки вокруг чисел необходимы, поскольку лексический анализатор Scala использует наиболее длинное правило сопоставления для токенов. То есть разобьёт следующие выражение


на токены 1., +, и 2. Дело в том, что 1. (цифра один с точкой) более длинное совпадение, чем 1 (просто цифра один) . Токен 1. интерпретируются как литерал 1.0, в результате получается Double вместо Int. Другими словами, если мы запишем выражение как


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

Классы

Мы уже знаем , что Scala является объектно-ориентированным языком и поэтому в нем есть такая концепция как класс. Классы в Scala объявляются используя синтаксис похожий на тот, который используется в Java. Отличием от Java является то, что классы в Scala могут иметь параметры. Это может быть проиллюстрировано в следующем определении комплексного числа.

class Complex(real:Double, imaginary:Double) 
{
   def re() = real
   def im() = imaginary
}

Этот класс может принимать два аргумента, которые являются действительной и мнимой частью комплексного числа. Эти аргументы должны быть переданы при создании объектов класса Complex: new Complex(1.5, 2.3). Этот класс содержит два метода re и im для получения этих двух частей. Следует отметить, что тип возвращаемого значения этих двух методов задан неявно. Он будет автоматически определён компилятором, который рассмотрит правую часть этих методов и решит что в обоих случаях тип возвращаемого значения будет Double.

Методы без аргументов

Небольшая проблема методов re и im заключается в том, что для того, чтобы вызвать их необходимо указывать пару пустых скобок после имени метода, как например в следующем примере:

object ComplexNumbers 
{
   def main(args: Array[String]) 
   {
       val c = new Complex(1.2, 3.4)
       println("imaginary part: " + c.im())
   }
}

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

class Complex(real: Double, imaginary: Double) 
{
    def re = real
    def im = imaginary
}

Наследование и переопределение

Все классы в Scala наследуются от суперкласса. Когда суперкласс не указан, как например в предыдущей главе в примере Complex, то будет по-умолчанию использоваться класс scala.AnyRef. Также можно переопределить (override) метод наследованный в суперклассе. В Scala существует требование явно указывать модификатор override, для того чтобы избежать случайное переопределение. В нашем примере, класс Complex может быть дополнен методом toString переопределяющим его из Object[2].

class Complex(real: Double, imaginary: Double) 
{
    def re = real
    def im = imaginary
    override def toString() = "" + re + (if (im < 0) "" else "+") + im + "i"
}

Примечания

  1. Scala [Электронный ресурс] : Материал из Википедии — свободной энциклопедии: — Режим доступа: https://ru.wikipedia.org/wiki/Scala
  2. Учебное пособие по Scala. Вольный перевод. [Электронный ресурс]: Режим доступа: http://programador.ru/scala-tu/