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 (по който може да се катери човек) and 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“ пример[редактиране | редактиране на кода]

Hello World програмата написана в Scala изглежда по този начин:

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

За разлика от stand-alone 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 е по-същество локално, за разлика от по-глобален Hindley-Milner алгоритъм използван в HaskellML и други чисто функционални езици. Това се прави, за да се улесни обектно-ориентираното програмиране. Резултатът е, че някои видове все още трябва се декларират (най-вече, функционални параметри, както и видовете връщане на рекурсивни функции), например:

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

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

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

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

В Scala, функции са обекти, и съществува удобен синтаксис за уточняване анонимни функции. Един пример е изразa 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" клетка с указател към новия елемент ("главата") и старата списъка ("опашката"). Това дава възможност за много лесна едновременност - без да са необходими заключвания, тъй като не споделените обекти са все по модифицирани. Неизменните структури също са изградени ефективно, в смисъл, че модифицираните инстанции се използват най-старите данни и неизползваните / се събират от GC.

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

Общоприета техника в 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.

Източници[редактиране | редактиране на кода]

  1. www.scala-lang.org/
  2. https://en.wikipedia.org/wiki/Scala_(programming_language)
  3. www.tutorialspoint.com/scala/
  4. https://www.lightbend.com/blog/how-scala-compares-20-programming-languages-reddit-analysis
  5. scala.epfl.ch/
  6. https://www.toptal.com/scala/why-should-i-learn-scala
  7. https://en.wikibooks.org/wiki/Scala
  8. http://www.infoworld.com/article/2609013/java/scala-founder--language-due-for--fundamental-rethink-.html
  9. http://scala-language.1934581.n4.nabble.com/
  10. https://www.quora.com/Is-Scala-suitable-as-a-first-programming-language
  11. http://www.journaldev.com/7444/introduction-to-scala-programming-language
  12. https://www.dezyre.com/article/why-learn-scala-programming-for-apache-spark/198
  13. http://searchsoa.techtarget.com/definition/Java-virtual-machine
  14. https://www.oracle.com/java/index.html
  15. http://scalamock.org/
  16. https://www.scalacheck.org/
  17. https://clojure.org/
Криейтив Комънс - Признание - Споделяне на споделеното Лиценз за свободна документация на ГНУ Тази страница частично или изцяло представлява превод на страницата „Scala_(programming_language)“ в Уикипедия на английски. Оригиналният текст, както и този превод, са защитени от Лиценза „Криейтив Комънс - Признание - Споделяне на споделеното“, а за съдържание, създадено преди юни 2009 година — от Лиценза за свободна документация на ГНУ. Прегледайте историята на редакциите на оригиналната страница, както и на преводната страница. Вижте източниците на оригиналната статия, състоянието ѝ при превода, и списъка на съавторите.