Scala

от Уикипедия, свободната енциклопедия
Scala
ПарадигмаМултипарадигмен, обектно ориентиран, структуриран, императивен, използващ, обобщено програмиране, рефлексивен език
Реализиране през2004
АвторМартин Одерски
Софтуерен разработчикЛаборатория за програмни методи of École Polytechnique Fédérale de Lausanne
Последна стабилна версия2.11.8 / 8 март, 2016
Типизация на даннитеСтатична, строга, заключваща, структурна
ИмплементацияScala
Повлиян отEiffel, Erlang, Haskell, Java, Lisp, Pizza, Standard ML, OCaml, Scheme, Smalltalk, Oz
ПовлияваCeylon, Chapel, Fantom, F#, Kotlin, Lasso,Red, Swift
Език на имплементацияScala
ПлатформаJVM, LLVM,JavaScript
Софтуерен лиценз3-clause BSD license
Файлово разширение.scala, .sc
Уебсайтwww.scala-lang.org
Лого на уикикниги Scala at Wikibooks в Уикикниги

Scala (английско произношение: /ˈskɑːlɑː/) е език за обобщено програмиране. Scala има пълен потенциал за функционално програмиране и много силна статичен тип система. Много от проекторешенията на Scala са вдъхновени от недостатъците на Java. Те са мотив да бъде проектиран по-рационален, кратък и ясен език като Scala. Изходният код на Scala е правен опит да може да се компилира с байткода на Java, за да може кодът да върви Java virtual machine (JVM). Java библиотеките могат да бъдат използвани директно в Scala кода и обратното (езикова приложимост). Като Java, Scala е обектно ориентиран език, и използва синтаксис с къдрави скоби напомнящ на програмния език C. За разлика от Java, Scala има много черти на езици за нефункционално програмиране като Scheme, Standard ML и Haskell, включително обработване, тип подразбиране, непроменливост, lazy (нестриктна оценка), и съвпадение на моделите. Освен това има напреднал тип системна поддържайки алгебричен тип данни, променлив и непроменлив, висок ред тип (но не от висок ранг) и анонимен тип данни. Други характерни черти за Scala са, че не присъства в Java include operator overloading, изборни параметри, именувани параметри, необработени низове и проверени изключения. Името Scala is идва от Scalable (по който може да се катери човек) и language (език), означавайки, че е създаден с идеята да расте заедно с изискванията на своите потребители.

История[редактиране | редактиране на кода]

Проектът Scala е започнал през 2001 в института École Polytechnique Fédérale de Lausanne (EPFL) от Мартин Одерски. Последван е от труда върху Фунел (програмен език, който комбинира идеи от функционалното програмиране и Petri nets. Одерски преди това работил върху Generic Java и javac, компилаторът на Sun. След вътрешното издание в края на 2003 г., Scala излиза в началото на 2004 на Java платформата и на .NET платформа през юни 2004. Последвана от втора версия през 2006 г., .NET платформата официално спира да поддържа езика. Също така Scala е имала широка поддръжка за функционално програмиране от самото и начало. Java е останал чисто обектно ориентиран език до въвеждането на ламбда изразите с Java 8 през 2014. На 17 януари 2011 the Scala екипът е спечелил финансиране за 5-годишно проучване на стойност над 2,3 милиона евро от Европейското изследователско консулство. На 12 май 2011, Одерски и сътрудниците му създали Typesafe Inc., компания, която предоставя масова поддръжка, обучение и услуги, свързани със Scala. Typesafe Inc. получили 3 милиона щ.д. инвестиции през 2011 от Greylock Partners.

Платформи и лицензи[редактиране | редактиране на кода]

Scala върви на Java платформата (Java Virtual Machine) и е съвместим със съществуващите Java програми. Както Android приложенията са типично предоставени като Java байткод, който да бъде преведен върху инсталацията, това прави Scala добре съвместим с Android разработването. Scala също може да се компилира с JavaScript, правейки го възможно да пише Scala програми, които могат да тръгнат на браузъра.

Софтуерното разпределение на Scala, включително компилатор и библиотеки са издадени под BSD лиценз.

Примери[редактиране | редактиране на кода]

„Hello World“ пример[редактиране | редактиране на кода]

object HelloWorld extends App {
  println("Hello, World!")
}

За разлика от Java, тук не се декларира клас и не е декларирано нищо статично; единствено е използван обект, създаден с ключовата дума “object“. Със запазването на програмата в името HelloWorld.scala, вече може да се компилира:

$ scalac HelloWorld.scala

За да тръгне:

$ scala HelloWorld

(Може да се наложи да използвате „-cp“ опцията за да поставите classpath като в Java).

Този процес е аналогичен с компилирането и пускането на Java code. Наистина, компилацията и използването на модела на Scala е идентичен на Java, правейки го съвместим с Java инструментите като as Ant.

По-кратка версия на „Hello World“ Scala програма е:

println("Hello, World!")

Scala включва интерактивна защита и скриптова поддръжка. Запазен с името HelloWorld2.scala, може да тръгне като скрипт без използването на предварителна компилация.

$ scala HelloWorld2.Scala

Командите също могат да бъдат въвеждани директно в Scala интерпретатора, чрез използването на опцията -e:

$ scala -e 'println("Hello, World!")'

Вече могат да се въвеждат команди интерактивно в REPL:

$ scala

Welcome to Scala version 2.10.3 (OpenJDK 64-Bit Server VM, Java 1.7.0_51).

Type in expressions to have them evaluated.

Type :help for more information.

 scala> println("Hello, World!")

Hello, World!

 scala>

Основен пример[редактиране | редактиране на кода]

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

// Java:
int mathFunction(int num) {
  int numSquare = num*num;
  return (int) (Math.cbrt(numSquare) +
                Math.log(numSquare));
}
// Scala: Direct conversion from Java
// no import needed; scala.math
// already imported as `math`
def mathFunction(num: Int): Int = {
  var numSquare: Int = num*num
  return (math.cbrt(numSquare) + math.log(numSquare)).
    asInstanceOf[Int]
}
// Scala: More idiomatic
// Uses type inference, omits `return` statement,
// uses `toInt` method, declares numSquare immutable
import math._
def intRoot23(num: Int) = {
  val numSquare = num*num
  (cbrt(numSquare) + log(numSquare)).toInt
}

Някои съществени разлики:

  • Scala не изисква точка и запетая накрая на стейтмънта. Стойностните типове: Int, Double, Boolean започват с главна буква, вместо: int, double, boolean.
  • Параметричните и връщащите типове са по-скоро както в Pascal, отколкото в C.
  • Методите трябва да бъдат предвождани от def.
  • Пред локалните или класовите променливи трябва да се пише val (декларира неизменима променлива) or var (декларира изменима променлива).
  • return операторът е излишен във функция (както и забранен); стойността на последното изпълнено условие или израз е обикновено стойността на функцията.
  • Вместо Java cast оператора (Type) foo, Scala използва foo.asInstanceOf[Type], или специалната функция toDouble или toInt.
  • Вместо функцията в Java import foo.*;, Scala използва import foo._.
  • Функцията или метода foo() може да бъде наречена просто foo; метод thread.send(signo) може да бъде наречена thread send signo; и метод foo.toString() може да бъде наречен foo toString.

Синтактичните облекчения са създадени да позволяват да поддържа специфични езици. Масивните референции се пишат както функциите. Например: array(i) вместо array[i]. (Вътре в Scala, двата масива са функции са концептуализирани като вид математическо картографиране от един обект към друг) Общите типове са написани като например List[String] вместо List<String> както е в Java.

  • Вместо псевдотипа void, Scala има собствен обособен клас Unit (погледнете отдолу примера).

Пример с класове[редактиране | редактиране на кода]

Този пример показва контраста в определението за клас в Java и Scala.

// Java:
public class Point {
  private final double x, y;
  public Point(final double x, final double y) {
    this.x = x;
    this.y = y;
  }
  public Point(
    final double x, final double y,
    final boolean addToGrid
  ) {
    this(x, y);
    if (addToGrid)
      grid.add(this);
  }
  public Point() {
    this(0.0, 0.0);
  }
  public double getX() {
    return x;
  }
  public double getY() {
    return y;
  }
  double distanceToPoint(final Point other) {
    return distanceBetweenPoints(x, y,
      other.x, other.y);
  }
  private static Grid grid = new Grid();
  static double distanceBetweenPoints(
      final double x1, final double y1,
      final double x2, final double y2
  ) {
    return Math.hypot(x1  x2, y1  y2);
  }
}
// Scala
class Point(
    val x: Double, val y: Double,
    addToGrid: Boolean = false
) {
  import Point._
  if (addToGrid)
    grid.add(this)
  def this() = this(0.0, 0.0)
  def distanceToPoint(other: Point) =
    distanceBetweenPoints(x, y, other.x, other.y)
}
object Point {
  private val grid = new Grid()
  def distanceBetweenPoints(x1: Double, y1: Double,
      x2: Double, y2: Double) = {
    math.hypot(x1  x2, y1  y2)
  }
}

Горепосоченият код показва някои основни разлики в боравенето на класове между Java и Scala

• Scala статични променливи или методи. Вместо това, има уникални по рода си обекти в класа. Обектите са декларирани, чрез използване наobject вместо class. Нормално е да се слагат статични променливи и методи в обект със същото име като на класа, което е познато като придружаващ обект (Подчертаващият клас за обекта има $ appended. Оттук, за class Foo с придружаващ обект object Foo, в себе си има Foo$ съдържащ кода на придружаващия обект, и самостоятелен обект от този клас е създаден чрез уникален по рода си

• На мястото на параметрите на параметрите на конструктора, Scala има класови параметри, поставени в самия клас, подобно на параметри на функция. Когато са декларирани с val или var, полетата също са със същото име и автоматично инициализирани от класовите параметри. (Под обвивката, външен достъп до публичните полета винаги преминава през accessor (getter) и mutator (setter) методи, които са автоматично създадени. Accessor функцията има същото име като полето, което обяснява защо не е необходимо в горния пример изрично да се декларират accessor методи.) Забележете, че алтернативните конструктори могат също да бъдат декларирани, както в Java. Кода, който може да премине в отсъстващ конструктор (друг, който да инициализира променливите) отива директно на нивото на класа Отсъстваща видимост в Scala е public.

Характеристики (в сравнение с Java)[редактиране | редактиране на кода]

Scala има същия начин на компилиране като Java и C#, поименно отделен компилатор и динамичен клас зареждане, за да може Scala кода да използва Java библиотеките, или .NET библиотеките в .NET платформата.

Оперативните характеристики на Scala са същите като на Java. Scala компилатора генерира байткод, което е много подобно с този на Java. Всъщност, Scala кодът може да бъде декомпилиран в Java код, с изключение на някои конструкторни операции. За JVM, Scala Java кодовете нямат разлика. Единствената разлика е във времето необходимо на библиотеките да заредят, Scala-library.jar.

Scala добавя голям брой отличителни разлики, в сравнение с Java, и има някои основни разминавания в съществения модел на изразите и типовете, което прави езика теоретично по-чист и елиминира много пречки в Java. От гледна точка на Scala, това е на практика много важно, защото големия брой разлики са възможни и в C#.

Синтактична гъвкавост[редактиране | редактиране на кода]

Както споменахме по-горе, Scala има добра синтактична гъвкавост, в сравнение с Java. Ето и следните примери:

  • Точката и запетаята не са необходими; редовете автоматично се свързват, ако започват или завършват със символ, който не може да дойде на тази позицията, или ако има незатворени скоби или кавички.
  • Всеки метод може да бъде използван като вмъкнат оператор, например "%d apples".format(num) и "%d apples" format num са еднакви. Всъщност, аритметичните оператори като + и <<са третирани като всички останали методи, откакто имената на функциите могат да съдържат последователности от произволни символи (с малки изключения като обикновените, къдравите и квадратни скоби, които трябва да бъдат въведени по специфичен начин).
  • Методите apply и update имат синтактични кратки форми. foo()—където foo е стойност (обект или отделен клас)—е кратък вариант за foo.apply(), и foo() = 42 е кратък вариант за foo.update(42). Подобно, foo(42) е кратък вариант за foo.apply(42), и foo(4) = 2 е кратък вариант за foo.update(4, 2). Това се използва за колекции класове и се среща в много други случаи.
  • Scala се различава по методите с отсъстващи скоби (def foo = 42) и празни скоби (def foo() = 42). Когато декларираме метод с празни скоби, скобите могат да бъдат пропуснати, което е практично, когато използваме Java библиотеките, които не разпознават тази разлика. Като например използването на foo.toString вместо foo.toString(). На практика метода трябва да бъде дефиниран с празни скоби в случай, че дава странични ефекти
  • Имената на методите, завършващи с две точки (:) изискват аргумент в лявата страна и приемник от дясната.. Като например 4 :: 2 :: Nil е същото като Nil.::(2).::(4), първата форма отговаря визуално на резултата (списък с първи елемент 4 и втори елемент 2).
  • Променливите на тялото на класа могат да бъдат ясно въведени като getter и setter методи. За trait FooLike { var bar: Int }, въвеждането може да бъде object Foo extends FooLike { private var x = 0; def bar = x; def bar_=(value: Int) { x = value }} } }. Може да бъде по-кратко написано: foo.bar = 42.
  • Използването на къдрави скоби вместо обикновени е позволено при извикване на методи. Това позволява чисто въвеждане на библиотеки от нови контролни структури. Като например breakable { ... if (...) break() ... } изглежда като breakable е била дефинираната ключова дума, но е просто метод, взел аргумент, който не може да се вземе. Методите, които могат да взимат такива аргументи или функции често поставят тях във втори списък от параметри, позволявайки да се смесват обикновени и къдрави скоби: Vector.fill(4) { math.random } е същото като asVector.fill(4)(math.random). Варианта с къдравите скоби позволява на израза да обхване няколко реда.
  • For-цикли (обяснени са по-долу) могат да се поставят всякакъв тип, който определя едновалентни методи като map, flatMap и filter.

Обединен тип система[редактиране | редактиране на кода]

Java прави сериозни разлики между примитивни типове (например int and boolean) и референтните типове (всички класове). Само референтните типове са част от производния метод, произхождащ от java.lang.Object. В Scala, обаче, всички производни от най-висок клас Any, чиито непосредствени наследници са AnyVal (стойностни типове като Int andBoolean) и AnyRef (референтни типове, като в Java). Това означава, че различието в Java между примитивните типове и окомплектованите типове (например int vs. Integer) не присъства в Scala; опаковането и разопаковането е напълно ясно за потребителя. Scala 2.10 позволява новите типове да бъдат определяни от потребителя.

For – цикли[редактиране | редактиране на кода]

Вместо както в Java „foreach“ циклите, for циклите чрез итератор, Scala има много по-силно понятие за for-expressions. Те са подобни на list comprehensions в езиците като Haskell, или комбинацията от list comprehensions и производните изрази в Python. For-циклите използващи yield ключови думи позволяват създаването на нови колекции чрез итерация, връщайки нова колекция от същия тип. Те са преведени от компилатора в серии от map, flatMap и filtercalls. Където 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 библиотека разширен метод от интегери, използвайки познатата техника имплицитно преобразуване, която позволява да бъдат въведени нови методи към съществуващите типове.)

По-сложен пример за итериране на карта е:

// Given a map specifying Twitter users mentioned in a set of tweets,
// and number of times each user was mentioned, look up the users''
// in a map of known politicians, and return a new map giving only the
// Democratic politicians (as objects, rather than strings).

val dem_mentions = for {
    (mention, times) <- mentions
    account          <- accounts.get(mention)
    if account.party == "Democratic"
} yield (account, times)

Функционални тенденции[редактиране | редактиране на кода]

Докато поддържа всички възможни обектно ориентирани особености в Java, Scala също предоставя голям брой възможности, които се срещат обикновено в езиците за функционално програмиране. Заедно тези особености Scala програмите да се пишат почти изцяло във функционален стил и също така позволява функционален и обектно ориентиран стил да бъдат смесвани.

Примери са:

Всичко е изрази[редактиране | редактиране на кода]

За разлика от C или Java, но подобно на езици като Lisp, Scala не прави разлика между твърдениея и изрази. Всички твърдения всъщност са изрази, които правят изчисления на някаква стойност. Функции, които се декларират с връщане на Void в C или Java,както и изрази като while,които логически не връщат стойност, в Scala се считат за връщащи от тип Unit, която е от singleton type, със само един обект от този тип. Функции и оператори, които никога не се връщат изобщо (например операторът throw е функция, която винаги съдържа non-locally използвайки изключение) логично връща тип Nothing, специален тип, който не съдържа обекти; това е bottom type, т.е. подклас на всеки възможен тип. (Това от своя страна прави типа Nothing съвместим с всеки тип, което позволява type inference да функционира правилно.)

По подобен начин if-then-else „твърдение“ всъщност е израз, който съдържа стойност, т.е. резултат от изчисленията на едно от двете разклонения. Това означава, че такъв блок от код може да бъде поставен там, където е желан, избягвайки нуждата от ternary operator в Scala:

// Java:
int hexDigit = x >= 10 ? x + 'A'  10 : x + '0';
// Scala:
val hexDigit = if (x >= 10) x + 'A'  10 else x + '0'

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

За да стане ясно, че всички изрази са функции, дори и методи, които връщат Unit са написани със знак за равенство:

def printValue(x: String): Unit = {
  println("I ate a %s".format(x))
}

или еквивалентно (с тип интерфейс и изрязване на ненужните скоби):

def printValue(x: String) = println("I ate a %s" format x)

Разпознаване на типа на параметрите[редактиране | редактиране на кода]

Поради способността на компилатора да разпознава типа на променливи, стойности върнати от функция и много други изрази обикновено могат да се пропуснат, като компилаторът може да разпознае типа на параметъра. Примерите са val x = "foo" (за неизменен, константна променлива или неизменни обект) или var x = 1.5 (за променлива която може по-късно да и се промени стойността). Разпознаване на типовете на параметрите в Scala е по-същество локален Local-type-inference, за разлика от по-глобален Global-type-inference Hindley-Milner(type system) и Hindley-Milner-Damas(алгоритъм) използван в HaskellML и други чисто функционални езици. Това се прави, първо поради ограничеността на JVM номиналната типова система и второ, ограничеността на обхвата на локалното разпознаване на типа Single statement. Резултатът е, че някои видове все още трябва се декларират (най-вече, функционални параметри, както и видовете връщане на рекурсивни функции), например:

def formatApples(x: Int) = "I ate %d apples".format(x)

или (с вид връщане деклариран за рекурсивна функция)

def factorial(x: Int): Int =
  if (x == 0)
    1
  else
    x*factorial(x  1)

Анонимни функции[редактиране | редактиране на кода]

В Scala функциите са обекти и съществува удобен синтаксис за уточняване анонимни функции. Един пример е израза x => x < 2 който определя функция с един параметър, който сравнява своя аргумент, за да се види дали е по-малко от 2. Това е еквивалентно на Lisp формата (lambda (x) (< x 2)). Имайте предвид, че нито видът на х, нито видът на връщане е необходим да бъде изрично посочен, и като цяло може да се заключи от тип извод; но те могат да бъдат изрично посочени, пример (x: Int) => x < 2 или дори x: Int) => (x < 2): Boolean. Анонимни функции се държат като истински затваряне (closure) в които те автоматично улавяне на всички променливи, които са лексикално на разположение в средата на функцията обхващащата. Тези променливи ще бъдат на разположение, дори и след като се връща затварящия функция, и за разлика от случая на Java „анонимни вътрешни класове“ не е нужно да се декларира като окончателно. (Възможно е дори да се променят тези променливи, ако те са непостоянни, и модифицираната стойност ще бъде на разположение следващия път, когато анонимен функция се извиква.)

Още по-кратка форма на анонимен функция използва заместващи променливи: Например, следното:

list map { x => sqrt(x) }

може да се запише по-стегнато като

list map { sqrt(_) }

или дори

list map sqrt

Неизменност[редактиране | редактиране на кода]

Scala налага разграничение между неизменни (само за четене) променливи, чиято стойност не може да се променя веднъж възложена и непостоянни променливи, които могат да бъдат променени. Прави се подобно разграничение между неизменни и непостоянен обекти. Трябва да се прави разграничение, когато една променлива е декларирана: неизменими променливи се декларират с val докато непостоянен променливи използват var. По същия начин, всички обекти за събиране (тип контейнер) в Scala, например свързани списъци, масиви, комплекти и хеш таблици, са на разположение в непостоянен и неизменни варианти, с неизменното вариант се счита за по-основно и изпълнение по подразбиране. Неизменни варианти са „устойчиви“ типове данни в които те създават нов обект, който обхваща старата обекта и добавя нов елементи; Това е подобно на начина по който, свързаните списъци са изградени в Lisp, където елементи се поставят преди чрез създаване на нова „cons“ клетка с указател към новия елемент („главата“) и старата списъка („опашката“). Това дава възможност за много лесна едновременност – без да са необходими заключвания, тъй като не споделените обекти са все по модифицирани. Неизменните структури също са изградени ефективно, в смисъл, че модифицираните инстанции се използват най-старите данни и неизползваните / се събират от Garbage collection.

Тип на обогатяване[редактиране | редактиране на кода]

Общоприета техника в Scala, известна като „обогати моята библиотека“, позволява на нови методи да се използват, като се прибавят към съществуващи типове. Това е подобно на концепта в C # за метод на удължаване, но по-мощен, защото техниката не се ограничава до метод на добавяне, но и може, например, да се използва за прилагане на нови интерфейси. В Scala, тази техника включва декларариране на имплицитно преобразуване от типа „получаване“ на метода в нов вид (обикновено, клас), който „опакова“ оригиналния тип и осигурява допълнителен метод. Ако един метод не може да се намери за даден вид, компилаторът автоматично търси за всички приложими имплицитни реализации на видове, които осигуряват въпросният метод.

Тази техника позволява на нови методи да бъдат добавени към съществуващия клас, използвайки добавена библиотека, така че само код, който засяга добавената библиотека получава новата функционалност, а целия друг код остава незасегнат.

Следващият пример показва обогатяването на тип Int с методите isEven и isOdd:

object MyExtensions {
  implicit class IntPredicates(i: Int) {
    def isEven = i % 2 == 0
    def isOdd  = !isEven
  }
}

import MyExtensions._ // bring implicit enrichment into scope
4.isEven // -> true

Едновременност[редактиране | редактиране на кода]

Стандартната библиотека в Scala включва поддръжка за „actor model“, в допълнение към стандартната Java едновременност APIs. Typesafe осигурява платформа, която включва Akka, отделна open source платформа, която осигурява actor-based едновременност. Akka операторите могат да бъдат разпределени или комбинирани със софтуер за контрол на паметта. Алтернативни CSP реализации за преминаване на съобщенията са Communicating Scala Object, или просто чрез JCSP.

Actor е като например тема с пощенска кутия. Може да бъде създадена от system.actorOf, незачита receive метода за получаване на съобщения и използва ! метода за изпращане на съобщение. Следващият пример показва EchoServer, който може да получава съобщения и след това да ги отпечата.

val echoServer = actor(new Act {
  become {
    case msg => println("echo " + msg)
  }
})
echoServer ! "hi"

Скала също така идва с вградена поддръжка за данни за паралелно програмиране под формата на Parallel Collections, интегрирани в своята стандартна библиотека от версия 2.9.0.

Следващият пример показва как да използвате Parallel Collections за подобряване на производителността.

val urls = List("http://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(_))
println("time: " + (System.currentTimeMillis  t) + "ms")

Клъстър компютри[редактиране | редактиране на кода]

Най-известното open source решение за клъстър компютри, написан на Scala e Apache Spark. Освен това, Apache Kafka, опашката за публикуване на абонирани съобщения известна в Spark и други технологии за обработка на потока, е написана на Scala.

Тестване[редактиране | редактиране на кода]

Има различни начини за тестване на код в Scala:

  • ScalaTest – поддържа много начини за тестване и може да се интегрира с Java базирани платформи.
  • ScalaCheck – библиотека подобна на Haskell's QuickCheck.
  • ScalaMock – осигурява поддръжка за тестване на висок ред и къри функции.
  • Junit или TestNG, две популярни платформи за тестване, написани на Java.

Сравнение с други JVM езици[редактиране | редактиране на кода]

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

Scala е статично типизиран, докато Groovy и Clojure са динамично типизирани. Това прави системата за типизиране по-сложна и трудна за разбиране, но позволява на почти всички типизирани грешки да бъдат уловени по време на компилиране и да доведе до значително по-бързо изпълнение на програмата. За разлика от това, динамичното типизиране изисква повече проверки, за да сме сигурни в коректността на програмата и като цяло е по-бавно, за да осигури по-голяма гъвкавост и простота. По отношение на различията в скоростта, сегашните версии на Groovy и Clojure имат допълнителни пояснения за типа, за да се избегне необходимостта от динамично типизиране в случаите в които типовете са статични. Това е допълнително намалено, когато използваме последните версии на JVM, която е подобрена с „invoke dynamic“ инструкция за методи, които са дефинирани с динамично типизирани аргументи. Тези подобрения намаляват разликата в скоростта между статичното и динамичното типизиране, въпреки че статично типизираните езици, като Scala са по-предпочитани, когато ефективността на изпълнение е по-важна.

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

По отношение на сходствата на синтаксиса с Java, Scala наследява много от синтаксиса на Java, какъвто е и случая с Groovy. Clojure от друга страна наследява синтаксиса на Lisp, който е различен както на вид така и като философия. Също така изучаването на Scala също се счита за трудно, поради разширените си функции. Случаят с Groovy е различен, въпреки факта, че е богат на функции, най-вече защото е проектиран да бъде скриптов език.

Класация на езиците[редактиране | редактиране на кода]

Skala е избран за най-популярен JVM скриптов език на JavaOne конференцията през 2012 г.

От 2013 г. всички JVM базирани производни (Scala, Groovy, Clojure) са значително по-малко популярни от оригиналния Java, който обикновено се класира първи или втори, и който същевременно се развива с течение на времето.

Popularity of Programming Language Index, която проследява търсенията за езикови уроци класира Scala на 16-о място през март 2016 с малък напредък, правейки го най-популярният JVM базиран език след Java.

Към януари 2016, индексът на TIOBE показва, че Scala e на 30-о място.

ThoughtWorks Technology Radar, което е становище за шестмесечен отчет на група от висши технолози, препоръчва приемана на Scala при своите езици и платформи.

Според Indeed.com Job Trends, търсенето на Scala рязко се увеличило от 2010 г. насам набиращ популярност пред Clojure и Groovy.

Външни препратки[редактиране | редактиране на кода]

  Тази страница частично или изцяло представлява превод на страницата Scala_(programming_language) в Уикипедия на английски. Оригиналният текст, както и този превод, са защитени от Лиценза „Криейтив Комънс – Признание – Споделяне на споделеното“, а за съдържание, създадено преди юни 2009 година – от Лиценза за свободна документация на ГНУ. Прегледайте историята на редакциите на оригиналната страница, както и на преводната страница, за да видите списъка на съавторите. ​

ВАЖНО: Този шаблон се отнася единствено до авторските права върху съдържанието на статията. Добавянето му не отменя изискването да се посочват конкретни източници на твърденията, които да бъдат благонадеждни.​