Scala (програмски језик)
Scala (изговор: Скала) је програмски језик за опште софтверске апликације. Скала има пуну подршку за функционално програмирање и веома јак систем статичких типова. Ово омогућава програмима написаним у Скали да буду веома концизни и тиме мањих димензија од осталих програмских језика опште намене . Многе одлуке при дизајну Скале биле су инспирисане критикама недостатака Јаве .[5]
Парадигма | Мулти-парадигма: функционална, објективно- оријентисана , императивна, конкурентна |
---|---|
Првобитни програмер(и) | Мартин Одерски |
Прва верзија | 20. јануар, 2004; пре 11 година |
Најновија верзија | 2.11.7 / 23. јун, 2015 пре 4 месеца[1] |
Дисциплина куцања | динамична,снажна, закључна, структурална |
Платформа | ЈВМ, ЛЛВМ, Јаваскрипт[2] |
Лиценца | 3-условна BSD лиценца[3] |
Екстензије | .scala |
Веб-сајт | www |
Под утицајем | |
Common Lisp, Erlang, Haskell, ML, Prolog, Scheme, Java, Ruby[4] | |
Утицао на | |
Elixir, Pixie, Rhine |
Предвиђено је да се изворни код Скале компајлира у Јава бајт код, тако да резултирајући извршни код ради на Јава виртуелној машини. Јава библиотеке могу да се користе директно у Скала коду и обрнуто (интероперабилност језика).[6] Као и Јава, Скала је објектно-оријентисана, и користи синтаксу која подсећа на C (програмски језик). За разлику од Јаве, Скала има много карактеристика функционалних програмских језика као што су Scheme, Стандард МЛ и Хаскел, укључујући кјуринг, подразумеване типове података, непроменљивости, лење евалуације, и патерн мечинг. Такође има напредни систем типова података који подржава алгебарски тип података, коваријансу и нековаријансу, типове вишег реда (али не и типове вишег ранга), и анонимне типове. Остале карактеристике Скале не постоје у Јави, укључујући преклапање оператора, факултативне параметре, назване параметре, сирове стрингове, и непроверене изузетке.
Име Скала је кованица од "скалабилности" и "језика", што значи да је дизајнирана да расте са захтевима својих корисника.[7]
Историја
уредиНацрт Скале је почео 2001. године на Екол Политекник Федерал де Лозан (ЕПФЛ) Мартин Одерски, који се надовезао на рад на Фунелу, програмском језику који комбинује идеје функционалног програмирања и Петри мрежа.[8] Одерски је раније радио на Џенерик Јави и јавцу, Сан Јави преводиоцу.[8]
Након интерног пуштања крајем 2003. године, Скала је јавно објављена почетком 2004. године на Јава платформи,[9] и на . НЕТ платформи јуна 2004. године.[5][8][10] Друга верзија (в2.0) испраћена је марта 2006. године.[5] Подршка за . НЕТ је званично напуштена 2012. године.[11]
Иако је Скала имала широку подршку за функционално програмирање од почетка, Јава остаје чисто објектно-оријентисани језик до увођења ламбда израза са Јавом 8 2014. године.
Дана 17. јануара 2011. године тим Скале је освојио донацију од преко 2,3 милиона € за петогодишње истраживање од Европског савета за истраживање.[12] 12. маја 2011. године, Одерски и сарадници су покренули Тајпсејф Инц., компанију за пружање комерцијалне подршке, обуке и услуга за Скалу. Тајпсејф је добио инвестицију вредну 3 милиона долара 2011. године од Грејлок Партнера.[13][14][15][16]
Платформе и лиценце
уредиСкала ради на Јава платформи (Јава виртуелној машини) и компатибилна је са постојећим Јава програмима.[9] Како се Андроид апликације углавном достављају као Јава бајт код, Скала је погодна за њихов развој.[17] Скала се може компилирати у ЈаваСкрипт, тако да је могуће написати Скала програме који могу да раде у претраживачу.[18]
Софтвер дистрибуције Скале, укључујући преводилац и библиотеке, је објављен под BSD лиценцом.[19]
Примери
уредиПример "Здраво, свете"
уреди object HelloWorld extends App {
println("Hello, World!")
}
За разлику од самосталне Здраво свете апликације за Јава, овде нема класе декларације и ништа се проглашава статичним; уникод креиран са објектом кључне речи се користи.
Са програмом сачуваним у фајл по имену ЗдравоСвете.scala
, могуће је саставити из командне линије:
$ scalac ЗдравоСвете.scala
Да би га стигао:
$ scala ЗдравоСвете
(Мора се користити "-cp" кључ комплета класнопутног као у Јави).
Ово је аналогно процесу прикупљање и рада Јава кода. Заиста, Скала је компилација и извршење модела идентичном оном из Јаве, што га чини компатибилним са Јава направом алат, као што је Ант.
Краћа верзија "Здраво свете" Скале програма је:
println("Hello, World!")
Скала укључује интерактивну шкољку и нацрт подршке.[20] Сачувано као фајл под називом ЗдравоСвете2.scala
, може да покрене као скрипту без претходне компилације користећи:
$ scala ЗдравоСвете2.scala
Команде могу бити унете директно у Скала интерпретатор, коришћењем опције -e:
$ scala -e 'println("Здраво, свете!")'
Најзад, команда може бити унета интерактивно са 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("Здраво, свете!")
Здраво, свете!
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
}
Неке синтаксне разлике у овом коду су:
- Скала не захтева запету на крају изјаве.
- Типови вредности су капитализовани:
Int, Double, Boolean
уместоint, double, boolean
. - Параметар и повратак врсте следе, као и у Паскалу, или претходе као у Ц.
- Методама мора претходити
def
. - Локалним или класама променљиве мора претходити
val
(указује непроменљиву променљиву) илиvar
(указује променљиву променљиву). - Оператор
return
је неопходан у функцији (иако дозвољено);вредност последњег извршеног кода или израза је нормално вредност ове функције. - Уместо Јава оператора
(Type) foo
, Скала користиfoo.asInstanceOf[Type]
, или специјалне функције као што суtoDouble или
toInt
. - Уместо у Јави
import foo.
*;
, Скала користиimport foo.
_
. - Функције или метода
foo()
може се назвати садfoo
; методаthread.send(signo)
може се назвати садthread send signo
; и методаfoo.toString()
може се назватиfoo toString
.
Неке друге основне синтаксичке разлике:
- Референце реда су написане као позиви функција, нпр
array(i)
док јеarray[i]
. (интерно у Скали, оба низа и функције концептуализоване су као врсте математичких мапирања из једног објекта на други.) - Опште врсте се пишу као нпр
List[String]
док у ЈавиList<String>
. - Уместо псеудо-типа
void
, Скала садржи актуелни уникодUnit
(види испод).
Примери са класама
уредиСледећи пример садржи дефиницију класа у Јави и Скали.
// 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)
}
}
Наведени код показује неке од концептуалних разлика између Јаве и Скале класе:
- Скала нема статичке променљиве или методе. Уместо тога, она има синглетон објекте, који су у суштини класе са само једним објектом у разреду. Синглетон објекти су проглашени коришћењем
object
уместоclass
. Уобичајно је да се ставе статичке променљиве и методе у синглтон објекту са истим именом као и именом класе, која је тада позната као пратилац објекта.[9] (Основна класа за синглетон објекат има$
у прилогу. Дакле, заclass Foo
са пратиоцем објектаobject Foo
, испод хаубе има класаFoo$
која садржи код пратилац објекта, и један објекат ове класе је креиран, користећи уникод.) - Уместо конструктора параметара, Скала има параметре класе, који се налазе на самим класама, сличним параметрима на функцији. Када је проглашена са
val
илиvar
модификатор, поља су такође дефинисани са истим именом, и аутоматски се иницијализују од параметара класе. (Под хаубом, спољашњи приступ јавним областима увек пролази кроз пријемник (гетер) и мутатор (сетер) методе, које је аутоматски креирао. Пријемник функције има исто име као на терену, због чега је непотребно у горњем примеру до експлицитно изјасни пријемник методе.) Пазити да алтернативни конструктори ће такође бити проглашени, као у Јави. Код који ће ићи у подразумевани конструктор (осим инитициализоване променљиве мембер) иде директно на ниво класе. - Уобичајна видљивост у Скали је
public
.
Карактеристике (са освртом на Јаву)
уредиСкала има исту компилацију модела као Јава и C#, односно посебне компилације и динамичне класе оптерећења, тако да код Скале може да позове Јава библиотеке, или .нет библиотеке у имплементацији . НЕТ.
Оперативни карактеристике Скале су исте као Јаве. Скала преводилац генерише бајт код који је готово идентичан ономе који генерише Јава преводилац.[9] У ствари, Скала код може бити неразумна за читање Јава кода, са изузетком неких конструктора операција. За ЈВМ, Скала код и Јава код се могу разликовати. Једина разлика је једноставан екстра рантајм образац, scala-library.jar
.[21]
Скала додаје велики број функција у поређењу са Јавом, и има неке фундаменталне разлике у свом основном моделу израза и врста, које чине теоретски језик чистијми и елиминишу велики број "корнер случаја" у Јави. Из перспективе Скале, ово је практично важно јер велики број додатних карактеристика у Скала је такође доступан у C#. Примери укључују:
Синтаксну флексибилност
уредиКао што је већ поменуто, Скала има доста синтаксних флексибилности, у поређењу са Јавом. Следе неки примери:
- Зарепете су непотребне; линије аутоматски почињу или се заврше знаком који не може нормално доћи у тај положај, или ако постоје незатворене заграде или заграде.
- Било који поступак се може користити као оператор поправке, нпр
"%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)
. Ово се користи за класе прикупљања и простире се на многим другим случајевима, као што су СТМ ћелије. - Скала прави разлику између не-паренс (
def foo = 42
) и празног паренс (def foo() = 42
) метода. Када се позива празна-паренс метода, заграде могу бити изостављене, што је корисно приликом позивања Јава библиотека које не знају ту разлику, на пример, користећиfoo.toString
уместоfoo.toString()
. По конвенцији, метод треба дефинисати са празним-паренсом када он обавља последице. - Метод имена завршава се двема тачака (
:
) очекивањем аргумента на левој страни и пријемника на десној страни. На пример,4 :: 2 :: Nil
је исто каоNil.::(2).::(4)
, први облик одговара визуелно резултату (листа са првог елемента 4 и другог елемента 2). - Класа тела променљивих се може транспарентно спроводити посебним гетер и сетер методама. За
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
. - Коришћење великих заграда уместо заграда је дозвољено у позиву метода. Ово омогућава чисте имплементације библиотека нових контролних структура.[22] На пример,
breakable { ... if (...) break() ... }
изгледа исто акоbreakable
је кључна реч језика дефинисана, али на метода узимања мисли се на аргумент. Методе које узимају истину или функције и често их стављају листу другог параметра, дозвољавајући да се мешају заграде и заграде синтаксе:Vector.fill(4) { math.random }
је исто као иVector.fill(4)(math.random)
. Протезу коврџавих варијанти омогућава израз спана виших линија. - За изразе (објашњено доле) може да прими било какву врсту која дефинише методе као што су
map
,flatMap
иfilter
.
Сами по себи, они могу изгледати као спорни избори, али колективно служе као сврха дозвољавања домена специфичних језика дефинисаних у Скали без потребе да се продужи преводилац. На пример, Ерлангова специјална синтакса за слање, односно. actor ! message
може бити (и јесте) спровођење у Скали библиотеке без потребе језичких додатака.
Обједињени типови система
уредиЈава прави оштру разлику између примитивног типа (нпр int
и boolean
) и референтних врста (било класа). Само референтне врсте су део шеме наслеђивања, која произилази из java.lang.
Object
. У Скала, међутим, све врсте су наслеђене од класе на највишем нивоу Any
, чија су деца непосредно AnyVal
(вредносни типови, попут Int
и Boolean
) и AnyRef
(референтни типови, као у Јави). То значи да Јава разлика између примитивних типова и кутија врсте (нпр. int
против Integer
) није присутна у Скали; кутија и некутија је потпуно транспарентна за корисника. Скала 2.10 дозвољава нове врсте вредности које су дефинисане од стране корисника.
За-изрази
уредиУместо Јава петље "форич" преко итератора, Скала има много снажнији концепт for
-израза. Ово је слично листи схватања у језицима као што су Хаскел, или комбинацијом листе схватања и генератора израза у Пајтону. За-изразе, користећи при томе yield
кључна реч омогућава нову колекцију која се генерише итеративно преко постојећег, и враћа нову колекцију истог типа. Они су преведени од стране преводиоца у низу map
, flatMap
и filter
позива. Где yield
није коришћен, код приближних петљи, превођењем на foreach
.
Прости пример је:
val s = for (x <- 1 to 25 if x*x > 50) yield 2*x
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
је прилично дефинисано у стандарду библиотеке Скала као поступак екстензије на целе бројева, употребом технике познате као имплицитне конверзије[23] који омогућава нове методе додавањем постојећих типова.)
Сложенија пример итератинга преко мапе:
// 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)
Израз (mention, times) <- mentions
је пример патерн метинг (види доле). Итератинг преко мапе враћа скуп кључних вредности торки, и образац-подударања лако омогућава да торке буду у одвојеним варијаблама за кључ и вредност. Слично томе, резултат схватања и враћања кључа-вредности записа, који је аутоматски уграђен назад у мапи, јер извор објекта (из променљиве mentions
) је мапа. Пазити ако је mentions
уместо одржаног листа, комплет, низ или други збир торки, потпуно исти код изнад би дао нову колекцију истог типа.
Функционалне тенденције
уредиИако подржава све објектно-оријентисане расположиве могућности у Јави (и, у ствари, повећавајући их на разне начине), Сцала такође пружа велики број могућности које су на обично налазе само у функционалним програмским језицима. Заједно, ови особине омогућавају Скала програми који се уписују у готово потпуно функционалне стила, а такође омогућити функционалне и објектно оријентисани стилова да се мешају.
Примери су:
- Нема разлике између изјава и израза
- Тип закључак
- Анонимне фунције са снимањем сематике (тј. затварачи)
- Непроменљиве варијабле и објекти
- Лења евалуација
- Раздвојени наставци (од 2.8)
- Функције високог реда
- Нестед функције
- Кјуринг
- Патерн мечинг
- Алгебра типова података (кроз "случај класа")
- Торке
Све је у изразу
уредиЗа разлику од C или Јава, или слична језицима као што су Lisp, Скала не прави разлику између изјава и израза . Све изјаве су у ствари изрази који оцењују неке вредности. Функције које би се изјасниле као повратак void
у C или Јави, изрази су попут while
да логички не врати вредност, у Скали се сматра врати тип
Unit
, што је уникод, са само једним објектом тог типа. Функције и оператори које никада не врати (нпр throw
оператер или функција која увек излази не-локално користећи изузетак) , логично има повратни тип Nothing
, посебна врста не садржи никакве предмете;то јес, дно типа, односно сваку подкласу могућег типа. (Ово заузврат чини тип Nothing
компатибилан са свим типовима , омогућавајући тип закључак да функционише исправно . )
Слично, if-then-else
"изјава" је заправо израз, који производи вредност, односно резултат процене једног од два крака. То значи да такав блок кода се може уметнути где год се жели израз, избегавајући потребу тернарног оператера у Скали :
// Java:
int hexDigit = x >= 10 ? x + 'A' - 10 : x + '0';
// Scala:
val hexDigit = if (x >= 10) x + 'A' - 10 else x + '0'
Из сличних разлога, return
изјаве нису потребне у Скали, а у ствари су обесхрабрене. Као и у Lisp-у, последњи израз у блоку кода је вредност тог блока кода, а ако је блок кода тело функције, она ће бити враћена функцијом.
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
(за променљиве чија вредност се касније може мењати).
def formatApples(x: Int) = "I ate %d apples".format(x)
или (са повратним типом за рекурзивну функцију)
def factorial(x: Int): Int =
if (x == 0)
1
else
x*factorial(x - 1)
Анонимне фунције
уредиУ Скали, функције су објекти, а погодна синтакса постоји за одређивање анонимних функција. Пример је израз x => x < 2
, који одређује функцију са једним параметром, који пореди свој аргумент да види да ли је мање од 2. То је еквивалентно Lisp облику (lambda (x) (< x 2))
. Пазити да ни тип x
нити повратни ти изричит, а може генерално закључити по типу извођења, али се може експлицитно навести, нпр као (x: Int) => x < 2
или (x: Int) => (x < 2): Boolean
.
Чак краћи облик анонимне функције користи чуваре места променљиве: на пример, следеће :
list map { x => sqrt(x) }
може бити написана и
list map { sqrt(_) }
или
list map sqrt
Постојаност
уредиСкала спроводи разлику између непроменљивих варијабли, чија вредност не може бити промењена након доделе, и променљивих варијабли, које се могу мењати . Слична је разлика између непроменљивих и променљивих објеката. Разлика мора постојати када се прогласи променљива: непроменљиве променљиве су декларисане val
док променљиве варијабле користе var
. Слично томе, сви објекти за сакупљање (врсте контејнера) у Скали, нпр. повезане листе, низови, сетови и хеш табеле, доступни су променљивим и непроменљивим варијантама, са непроменљивом варијантом сматра се више основна и подразумевана имплементација. Непроменљиве варијанте су "упорни" типови података праве нови објекат који обухвата стари објекат и додаје нови члана (С); ово је сличан начин повезане листе изграђене у Lisp-у, где су елементи препендедени стварањем нове "против" ћелије са показивачем новог елемента ("глава ") и старе листе ("реп"). Ово омогућава веома лаку конкуренцију - нема потребне браве какоо нема ни заједничких објеката икада модификовани. Непроменљиве структуре су такође изграђене ефикасно, у смислу да модификованом случајева реусес већина старих података степена и неискоришћених делова / унреференцед се прикупљају од ГЦ .[24]
Лење (нестроге) евалуације
уредиЕвалуација је строга ("нестрпљиви"). Другим речима, Скала оцењује изразе чим су доступни, него по потреби. Међутим, можете прогласи променљиву нестрогом ( "лењом" ) са lazy
кључном речју, што значи да код произведи вредност променљиве и неће бити вреднована до првог пута када се помене променљива. Нестрога складиштења разних врста такође постоје (као што су врста Stream
, нестрога повезана листа), и свака колекција постаје нестрога view
методом. Нестроге колекције пружају добар семантички спрег ствари као што су сервер података, где је процена кода за генерисање касније елемената листе (која заузврат изазива захтев сервера, можда се налази негде другде на интернету) само се дешава када ствари потребе елементе.
Репна рекурзија
уредиФункционални програмски језици обично пружају оптимизацију реп позива како би се омогућило широко коришћење рекурзије без стек оверфлоу проблема. Ограничења у Јава бајт кодовима компликују оптимизацију реп позива на ЈВМ. У принципу, функција која себе позива реп позивом може бити оптимизована, али међусобно рекурзивне функције не могу. Трамполине су предложене као алтернативно решење .[25] Подршка трамполине је показана од Скала библиотеке са објектом scala.util.control.
TailCalls
од Скала 2.8.0 (обновљена 14. јула 2010. године).[26]
Случај класе и образац подударања
уредиСкала има уграђену подршку за образац подударања, који се може посматрати као софистициранија, проширена верзије изјаве свич, где се могу поклопити произвољне врсте података (а не само једноставне врсте, као што су целих бројева, логички и стрингови), укључујући и произвољна угнежђења. Посебна врста класе позната као случај класе је обезбеђена, чиме укључује аутоматску подршку за образац подударања и може се користити за моделирање алгебарских типова података који се користе у многим функционалним програмским језицима.(Из перспективе Скале, случај класа је једноставно нормална класа за које преводилац аутоматски додаје одређена понашања која би могла бити обезбеђена мануелно нпр дефиниције метода које пружају дубока поређења и хеширање, и деструктурирање је предмет класе на својим конструкторима параметара током обрасца подударања).
Пример дефиниције квиксорт алгоритма помоћу обрасца подударања гласи :
def qsort(list: List[Int]): List[Int] = list match {
case Nil => Nil
case pivot :: tail =>
val (smaller, rest) = tail.partition(_ < pivot)
qsort(smaller) ::: pivot :: qsort(rest)
}
Идеја је да поделимо у листи елемената мање од стожера и елементе не мање, рекурсивним сортирањем сваког дела, и налепимо резултате заједно са стожером између. Ово користи иста стратегија подели па владај, мергсорта и других алгоритама за брзо сортирање.
Оператор match
се користи да уради подударања узорака на објекту који се налази у list
. Сваки case
израз је покушао опет да види да ли ће се подударати, а први удар одређује резултат. У овом случају, Nil
одговара само дословно објекат Nil
, али pivot :: tail
одговара непразној листи, и истовремено опадајућој листу према датом обрасцу. У том случају, повезан код ће имати приступ локалној променљивој по имену pivot
државши главу на листи, и друге варијабле tail
држаћи реп на листи. Имајте на уму да су ове варијабле само за читање, и да су семантички веома сличне променљивим утврђеним низовима користећи let
оператор у Lisp-у и Шеми.
Образац подударање такође се дешава у локалним декларацијама променљивих. У том случају, повратак вредности позива се tail.partition
је торка - у овом случају, две листе. (Торке се разликују од других врста амбалажа, нпр листа, у који су увек фиксне величине и елементи могу бити различитих типова. - Иако овде су оба исти) узорак подударања је најлакши начин да налажење два дела торке.
Форма _ < pivot
је декларација анонимне функције са чуварем места променљиве; види део о анонимним функцијама.
Листа оператора ::
(што додаје елемент на почетку листе, слично cons
у Lisp-у и Шеми) и :::
(који додаје две листе заједно, слично је append
у Lisp-у и Шеми), обоје нестају. Упркос наступима, не постоји ништа "уграђено" у вези било којих од ових оператера. Као што је пре спецификовано, сваки низ симбола може послужити као име функције, а метод се примењује на објекат који може бити написан "инфикс" стилом без периода или заграда. Линија изнад како је написано:
qsort(smaller) ::: pivot :: qsort(rest)
може бити записана и :
qsort(rest).::(pivot).:::(qsort(smaller))
у више стандардних метода позива запис.(Методе које се завршавају са двотачком у праву асоцијативе и везују се за објекат са десне стране.)
Парцијалне функције
уреди
У обрасцу разбијања горе наведеног примера, тело match
оператора је парцијална функција, која се састоји од низа case
израза, са првим одговарајућим преовладавајућим низом, слично телу изјаве. Парцијалне функције су такође користе у делу руковања са изузецима try
изјава:
try {
...
} catch {
case nfe:NumberFormatException => { println(nfe); List(0) }
case _ => Nil
}
Коначно, парцијална функција се може користити само од себе, а резултат назвавши еквивалентан је раду match
. На пример, претходни код за брзо сортирање може се записати следећим:
val qsort: List[Int] => List[Int] = {
case Nil => Nil
case pivot :: tail =>
val (smaller, rest) = tail.partition(_ < pivot)
qsort(smaller) ::: pivot :: qsort(rest)
}
Само за читање променљивих је проглашен тип чија је функција листа целих бројева на листи целих бројева, и везују се парцијалном функцијом. (Имајте на уму да један параметар парцијалне функције се никада није изјавио.) Међутим, још увек можемо назвати ову променљиву баш као да је у питању нормална функција:
scala> qsort(List(6,2,5,9)) res32: List[Int] = List(2, 5, 6, 9)
Објективно-оријентисани изрази
уредиСкала је чисто објектно-оријентисани језик у смислу да је свака Објекат. Типови података и понашања објеката су описани по врстама и особинама. Апстракције класа се продужавају подкласама и флексибилним механизмом измешане композиције засноване да би се избегли проблеми вишеструког наслеђивања.
Особине замене Скале је Јава интерфејс. Интерфејс верзија Јаве до 8 су веома ограничени, могли су само да садрже апстрактне декларације функција. То је довело до критика да пружање олакшају методе интерфејса непријатно (исте методе морају бити исте у сваком спровођењу), а проширење је објављен интерфејс уназад компатибилан начин је немогућ. Особине су слични миксин класама у томе што имају скоро сву моћ редовне апстрактне класе, у недостатку само параметре класе (Скала је еквивалентно градитељ Јава параметара), јер особине су увек помешане са класама. Оператор super
се понаша посебно у особинама, омогућавајући особинама да се ланцима коришћењем композиција поред наследства. Следећи пример је једноставан прозорни систем:
abstract class Window {
// abstract
def draw()
}
class SimpleWindow extends Window {
def draw() {
println("in SimpleWindow")
// draw a basic window
}
}
trait WindowDecoration extends Window { }
trait HorizontalScrollbarDecoration extends WindowDecoration {
// "abstract override" is needed here in order for "super()" to work because the parent
// function is abstract. If it were concrete, regular "override" would be enough.
abstract override def draw() {
println("in HorizontalScrollbarDecoration")
super.draw()
// now draw a horizontal scrollbar
}
}
trait VerticalScrollbarDecoration extends WindowDecoration {
abstract override def draw() {
println("in VerticalScrollbarDecoration")
super.draw()
// now draw a vertical scrollbar
}
}
trait TitleDecoration extends WindowDecoration {
abstract override def draw() {
println("in TitleDecoration")
super.draw()
// now draw the title bar
}
}
Променљиве се могу декларисати на следећи начин:
val mywin = new SimpleWindow with VerticalScrollbarDecoration with HorizontalScrollbarDecoration with TitleDecoration
Резултат позивања mywin.draw()
је
in TitleDecoration in HorizontalScrollbarDecoration in VerticalScrollbarDecoration in SimpleWindow
Другим речима, позив draw
се први извршава у коду TitleDecoration
(последње особине се помешају), затим (преко super()
позива) с навојем назад кроз друге мешовите особине и на крају до кода Window
сам, иако ниједна особина није наследила ништа. Ово је слично обрасцу декоратора, али је више концизно и мање склон грешкама, јер не захтева експлицитни матични прозор , експлицитно прослеђивање функције чија реализација се не мења. У другим језицима, сличан ефекат се може постићи компилирањем са дугим линеарним ланцем наслеђивања имплементације , али на штету у односу да је Скала један линеарни ланац наследство ће бити проглашено за сваку могућу комбинацију микс-инс .
Изражајни тип система
уредиСкала је опремљена експресивног статичким типом система који намеће безбедно и кохерентно коришћење апстракција. Конкретно, тип система подржава :
- Класе и апстрактни типови као чланови објекта
- Структуралне типове
- Зависне врсте
- Сложене типове
- Изричито самооткуцане референца
- Генеричко програмирање
- Полиморфне методе
- Горњи и доњи тип границе
- Варијација
- Анотација
- Прегледе
Сцала може да закључи врсте од употребе. То ради већина статичких изјаве типа опција. Статички типови не морају бити изричито изјављени, осим ако преводилац указује грешку на потребу. У пракси, неке статичке изјаве типа су укључени због јасноће кода .
Тип обогаћивања
уредиЗаједнички техника у Скали, познат као "обогати своју библиотеку" ;[23] ова формулација се сада губи због своје конотације), омогућава да се користе нове методе као да су додати у постојећих типовима. Ово је слично C # концепту саветодавних метода, али моћније, јер техника се не ограничава на додавању поступака. У Скали, ова техника подразумева проглашење имплицитне конверзије из типа "прима" на нову врсту (обично класе), који обавија оригиналну врсту и обезбеђује додатну методу. Ако се метод не може наћи за дату врсту, преводилац аутоматски тражи било коју имплицитну конверзију врста које пружају метод у питању .
Ова техника омогућава нове методе да се додају у постојеће класе користећи додатак библиотеци само ако код који увози додатак библиотеци добија нову функционалност, а за све остало код је непроменљив .
Следећи пример показује обогаћивање типа
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
Убацивање чланова MyExtensions
доноси имплицитно претварање могућности продужења класе
IntPredicates
у оквиру
.[27]
Конкуренција
уредиСтандардна библиотека Скале укључује подршку за актор модела, поред стандардних Јава конкуренција АПИ. Безбедан тип пружа платформу [28] коју укључује Акка, посебан извор оквир који омогућава актор заснован на конкуренцији. Акка актери могу бити дистрибуирани или у комбинацији са софтверском трансакционим меморијом ("трансактори"). Алтернативна ЦСП имплементација има за канал на бази поруке преко које комуницирају Скала објекти,[29] или једноставно преко ЈЦСП.
Актор као тема примера за поштанско сандуче . Може бити створена system.actorOf
, укључујући receive
методу примљања порука и коришћењем !
(знак узвика ) метод да се пошаље порука
.[30]
Следећи пример показује ЕкоСервер који може да прима поруке и затим и и штампа.
val echoServer = actor(new Act {
become {
case msg => println("echo " + msg)
}
})
echoServer ! "hi"
Скала је такође подржана паралелним програмима у форми паралелног складиштења [31] интегрисаног у стандарној библиотеци од верзије 2.9.0. Следећи пример показује коришћење паралелних складиштења перформанса.[30]
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")
Поред актора подршке и паралелизма, Скала такође подржава асинхроно програмирање са будућношћу и обећањима, софтвере трансакцијске меморије, и догађаје потока
.[32]
Кластер рачунарство
уредиДва значајна извора кластер рачунарства су заснована на Скали: Апач Спарк и Апач Игнит (прилагођени комерцијалном ГридГејн производу) .[33] Осим тога, Апач Кафка је објавио претплатну поруку реда популарности са Спарком и другим стрим процесорима технологија, пише у Скали.
Тестирање
уредиПостоји неколико начина тестирања кода у Скали:
- СkалаТест подржава више стилова тестирања и може се интегрисати са оквирима за тестирање базираним на Јави[34]
- СкалаЧек, библиотека слична Хаскел КвикЧеку[35]
- спецс2, библиотека за писање извршних софтверских апликација помоћу спецификација[36]
- СкалаМок подржава тестирање функција високог реда и Кари функција[37]
- ЈУнит или ТестИНГ, два популарна оквира за тестирање писана у Јави
Верзије
уредиВерзија | Издата | Карактеристике | Стање | Notes |
---|---|---|---|---|
2.0[38] | 12-03-2006 | _ | _ | _ |
2.1.8[39] | 23-08-2006 | _ | _ | _ |
2.3.0[40] | 23-11-2006 | _ | _ | _ |
2.4.0[41] | 09-03-2007 | _ | _ | _ |
2.5.0[42] | 02-05-2007 | _ | _ | _ |
2.6.0[43] | 27-07-2007 | _ | _ | _ |
2.7.0[44] | 07-02-2008 | _ | _ | _ |
2.8.0[45] | 14-07-2010 | Заједничка ревизија, униформа, и свеобухватни оквир за прикупљање врста . | _ | _ |
2.9.0[46] | 12-05-2011 | _ | _ | _ |
2.10[47] | 04-01-2013 |
Експерименталне карактеристике |
_ | _ |
2.10.2[56] | 06-06-2013 | _ | _ | _ |
2.10.3[57] | 01-10-2013 | _ | _ | _ |
2.10.4[58] | 18-03-2014 | _ | _ | _ |
2.10.5[59] | 05-03-2015 | _ | _ | _ |
2.11.0[60] | 21-04-2014 | _ | _ | _ |
2.11.1[61] | 20-05-2014 | _ | _ | _ |
2.11.2[62] | 22-06-2014 | _ | _ | _ |
2.11.4[63] | 31-10-2014 | _ | _ | _ |
2.11.5[64] | 08-01-2015 | _ | _ | _ |
2.11.6[65] | 05-03-2015 | _ | _ | _ |
2.11.7[66] | 23-06-2015 | _ | Тренутно | _ |
Поређење са другим ЈВМ језицима
уредиСкала је често у поређењу са Груви и Цлојуре, два друга програмска језика који користе ЈВМ. Значајне разлике између тих језика налазе се у систему типа, у мери у којој сваки језик подржава објектно-оријентисано и функционално програмирање, а у сличности њихових синтакси у синтаксама Јаве.
Скала статички тип, а како Гроови и Цлојуре су динамички типови. То чини тип систем сложенијим и тешким за разумевање, али омогућава готово да све грешке типа буде ухваћене у компилирање и може се довести до знатно бржег извршења. Насупрот томе, динамично куцање захтева више тестирања како би се осигурала исправност програма и генерално спорије како би се омогућила већа флексибилност програмирања и једноставност. Што се тиче брзине разлике, тренутне верзије Груви и Цлојуре дозвољавају опционе типове напомена да помогну програмима како би избегли изнад главе динамичног куцања у случајевима у којима типови су практично статички. Ово изнад је додатно смањено када се користе најновије верзије ЈВМ, која је појачан са "динамичним изазивањима". Упутство за методе које су дефинисане са динамичким откуцаним аргументима. Ови аванси смањују јаз између брзине статичког и динамичког куцања, иако је статички откуцан језика, као Скала, и даље омиљени избор када је ефикасност извршења веома важна.
Што се тиче програмских парадигми, Скала наслеђује објектно-оријентисани модел Јаве и проширује га на разне начине. Груви, истовремено снажно објектно- оријентисан је више усмерен на смањење евидентирања. У Цлојуре, објектно-оријентисано програмирање је димпејсед са функционалним програмирање што је главна снага језика. Скала има многе функционалне програмске садржаје, укључујући и могућности наласка у напредним функционалних језика као што су Хаскел, и покушава да буде агностик између две парадигме, пуштајући програмеру да изабере између две парадигме или, чешће, неке њихове комбинације.
Што се тиче синтаксе сличности са Јавом, Скала наслеђује много Јаве синтаксе, као што је то случај са Груви. Цлојуре са друге стране следи Lisp синтаксу, која се разликује и у изгледу и филозофији. Међутим, учење Скале се сматра тешко због његових бројних напредних функција. То није случај са Груви, упркос чињеници да је такође богат функцијама језика, углавном зато што је дизајниран да буде пре свега скриптни језик.
Прихватање
уредиРангирање језика
уредиСкала је проглашена за најпопуларнији ЈВМ писаћи језик 2012. године на ЈаваУан конференције.[9]
Од 2013. године, сви деривати базирани на ЈВМ (Скала / Груви / Цлојуре) су значајно мање популарни од оригиналног Јава језика који се обично рангира као први или други,[67][68][69] а који се такође истовремено развија.
Од децембра 2013. године,индекс ТИОБЕ[68] програмског језика популарности показује Скалу на 31. месту са 0,342% програмера (мерено Интернет претраживачима и сличним публикацијама бројања), док је испод горње границе од 50 година раније. Скала је сада испред функционалних језика Хаскел (50.) и Ерланг (> 50), као и ЈВМ конкуренти Груви (47.) и Clojure (> 50).
Друга мера, РедМонк програмски језик ранг листе, од јуна 2013. године поставља Скалу 12., заснована на 15. позицији у смислу броја ГитХуб пројеката и 16. у погледу броја питања означених на Стак Оверфлоу.[67] (Груби је био на 18. месту; Clojure на 22,.)[67] Ево, Скала је јасно иза прве класе групе од 11 језика (укључујући Јава, C, Пајтон, PHP, Руби, итд), али водећих у другој приказаној групи.
ТоутВоркс технологија радар, што је мишљење засновано на полу-годишњем извештају о групи виших технолога,[70] препоручује усвајање Скале у својим језицима и оквири категорију.[71]
Према Индид.цом Џоб Трендс, потражња Скале нагло расте од 2010. године, испред Цлојуре али иза Груви.
Компаније
уредиУ априлу 2009. године, Твитер је објаво да је укључен велики делови његовог бекхенд Руби Скале и намеру да претворити остатак.[72]
Глит користи Скалу и Плеј Фрејмворк.[28]
Форсквер користи Скалу и Лифт..[73]
СпринГоу користи Скалу и Акка.[74]
Коросера користи Скалу и Плеј Фрејмворк.[75]
Гардијан (новине)[76] најављују у априлу 2011. године да је прелазак са Јава да Сцала,[77][78]
Њујорк тајмс открива 2014. године да је интерни систем за управљање садржаја Црнобради изграђен коришћењем Скале, Акке и Пеја.[79]
Хафингтон пост новине су почеле да запошљавају Скалу као део свог система испоруке садржаја Атена 2013. године.[80]
Швајцарска банка УБС узима Скалу као главни продукциони систем.[81]
БитГолд платформа је у потпуности изграђена на Скали и Плеј Фрејмворку.[82]
ЛинкедИн користи Скалатра микрофрејмворк за напајање свој сигнал АПИ.[83]
Митап користи дефилтер алат за реално врме АПИ.[84]
Ремембер д Милк користи анфилтред алат, Скалу и Акку јавно за АПИ и ажурирања реалног времена.[85]
Веризон тражи да "следеће генерације раде" помоћу Скале.[86]
Замерка
уредиУ новембру 2011. године, Јамер је напустио Скалу због стрме криве учења нових чланова тима и некомпатибилности претходних са следећим верзијама Скала преводиоца.[87] Други критикују Скалу због нечитљивости везаних за имплицитне параметре, и због тога што није могуће избећи Скалине више арканске карактеристике када се повуче библиотека која их користи, те да све у свему, "Тежина Скале превазилази њену вредност."[88][89]
Референце
уреди- ^ „Scala 2.11.7 is now available!”. 23. 6. 2015. Приступљено 3. 7. 2015.
- ^ „Scala.js”. Приступљено 27. 7. 2015.
- ^ „Scala 2.11.1 is now available!”.
- ^ „Clojure Programming” (PDF). Приступљено 2013-04-30.
- ^ а б в Martin Odersky et al., An Overview of the Scala Programming Language, 2nd Edition
- ^ "Frequently Asked Questions - Java Interoperability". scala-lang.org
- ^ Loverdo 2010
- ^ а б в Martin Odersky, "A Brief History of Scala", Artima.com weblogs, June 9, 2006
- ^ а б в г д Odersky, M.; Rompf, T. (2014).
- ^ Martin Odersky, "The Scala Language Specification Version 2.7"
- ^ Expunged the .net backend. by paulp · Pull Request #1718 · scala/scala · GitHub.
- ^ "Scala Team Wins ERC Grant"
- ^ "Commercial Support for Scala". 2011-05-12
- ^ "Why We Invested in Typesafe: Modern Applications Demand Modern Tools" Архивирано на сајту Wayback Machine (8. децембар 2012). 2011-05-12
- ^ "Open-source Scala gains commercial backing". 2011-05-12
- ^ "Cloud computing pioneer Martin Odersky takes wraps off his new company Typesafe". 2011-05-12
- ^ "Developing for Android"
- ^ "Scala Js Is No Longer Experimental | The Scala Programming Language" Архивирано на сајту Wayback Machine (2. октобар 2015).
- ^ "Scala License | The Scala Programming Language".
- ^ "Getting Started with Scala". scala-lang.org. 15. 7. 2008
- ^ "Home" Архивирано на сајту Wayback Machine (31. август 2010).
- ^ Scala's built-in control structures such as
if
orwhile
cannot be re-implemented. - ^ а б "Pimp my Library".
- ^ "Collections - Concrete Immutable Collection Classes - Scala Documentation"
- ^ Rich Dougherty.
- ^ "TailCalls - Scala Standard Library API (Scaladoc) 2.10.2 - scala.util.control.
- ^ Implicit classes were introduced in Scala 2.10 to make method extensions more concise.
- ^ а б Typesafe Inc.
- ^ Communicating Scala Objects, Bernard Sufrin, Communicating Process Architectures 2008
- ^ а б Kay Yan.
- ^ "Parallelcollections - Overview - Scala Documentation".
- ^ Frank, Felix (28. 11. 2014). Learning Concurrent Programming in Scala. Packt Publishing. ISBN 978-1783281411.
- ^ Murphy, Ian (2014-11-04).
- ^ Kops, Micha (2013-01-13).
- ^ Nilsson, Rickard (2008-11-17).
- ^ "Build web applications using Scala and the Play Framework". workwithplay.com. 2013-05-22
- ^ Butcher, Paul (2012-06-04).
- ^ "Changes in Version 2.0 (12-Mar-2006)". scala-lang.org. 2006-03-12
- ^ "Changes in Version 2.1.8 (23-Aug-2006)". scala-lang.org. 2006-08-23
- ^ "Changes in Version 2.3.0 (23-Nov-2006)". scala-lang.org. 2006-11-23
- ^ "Changes in Version 2.4.0 (09-Mar-2007)". scala-lang.org. 2007-03-09
- ^ "Changes in Version 2.5 (02-May-2007)". scala-lang.org. 2007-05-02
- ^ "Changes in Version 2.6 (27-Jul-2007)". scala-lang.org. 2007-06-27
- ^ "Changes in Version 2.7.0 (07-Feb-2008)". scala-lang.org. 2008-02-07
- ^ "Changes in Version 2.8.0 (14-Jul-2010)". scala-lang.org. 2010-07-10
- ^ "Changes in Version 2.9.0 (12-May-2011)". scala-lang.org. 2011-05-12
- ^ "Changes in Version 2.10.0". scala-lang.org. 2013-01-04
- ^ Harrah, Mark.
- ^ а б Suereth, Josh.
- ^ Haller, Philipp; Prokopec, Aleksandar.
- ^ "SIP-17 - Type Dynamic". scala-lang.org
- ^ "SIP-18 - Modularizing Language Features". scala-lang.org
- ^ Prokopec, Aleksandar; Miller, Heather.
- ^ Miller, Heather; Burmako, Eugene.
- ^ Burmako, Eugene.
- ^ "Scala 2.10.2 is now available!". scala-lang.org. 2013-06-06
- ^ "Scala 2.10.3 is now available!". scala-lang.org. 2013-10-01
- ^ "Scala 2.10.4 is now available!". scala-lang.org. 2014-03-18
- ^ "Scala 2.10.5 is now available!". scala-lang.org. 2015-03-04
- ^ "Scala 2.11.0 is now available!". scala-lang.org. 2014-04-21
- ^ "Scala 2.11.1 is now available!". scala-lang.org. 2014-05-20
- ^ "Scala 2.11.2 is now available!". scala-lang.org. 2014-07-22
- ^ "Scala 2.11.4 is now available!". scala-lang.org. 2014-10-31
- ^ "Scala 2.11.5 is now available!". scala-lang.org. 2015-01-08
- ^ "Scala 2.11.6 is now available!". scala-lang.org. 2015-03-05
- ^ "Scala 2.11.7 is now available!". scala-lang.org. 2015-06-23
- ^ а б в "The RedMonk Programming Language Rankings: June 2013".
- ^ а б "TIOBE Index for December 2013" Архивирано на сајту Wayback Machine (2. јул 2013).
- ^ "The Transparent Language Popularity Index, July 2013".
- ^ "ThoughtWorks Technology Radar FAQ".
- ^ "ThoughtWorks Technology Radar MAY 2013" (PDF).
- ^ Greene, Kate (April 1, 2009).
- ^ "Scala, Lift, and the Future" Архивирано на сајту Wayback Machine (13. јануар 2016)
- ^ "SpinGo - SpinGo + Scala"
- ^ Coursera Engineering.
- ^ David Reid and Tania Teixeira (26 February 2010).
- ^ "Guardian switching from Java to Scala".
- ^ "Guardian.co.uk Switching from Java to Scala".
- ^ Roy, Suman and Sundaresan, Krishna (2014-05-13).
- ^ Pavley, John (2013-08-11).
- ^ Binstock, Andrew (2011-07-14).
- ^ http://www.bitgold.com | BitGold built on Scala and Play Framework
- ^ Synodinos, Dionysios G. (2010-10-11).
- ^ "Real-life Meetups Deserve Real-time APIs".
- ^ "Real time updating comes to the Remember The Milk web app".
- ^ "Senior Scala Engineer"
- ^ Hale, Coda (29 November 2011).
- ^ Allan, Graham (23 June 2013).
- ^ Pollack, David (14 September 2011).
Литература
уреди- Suereth, Joshua D. (2011). Scala in Depth. Manning Publications. стр. 225. ISBN 978-1-935182-70-2.
- Meredith, Gregory (2011). Monadic Design Patterns for the Web (PDF) (1st изд.). стр. 300.
- Raychaudhuri, Nilanjan (2011). Scala in Action (1st изд.). Manning. стр. 525. ISBN 978-1-935182-75-7.
- Wampler, Dean; Payne, Alex (15. 9. 2009). Programming Scala: Scalability = Functional Programming + Objects (1st изд.). O'Reilly Media. стр. 448. ISBN 978-0-596-15595-7.
- Odersky, Martin; Spoon, Lex; Venners, Bill (13. 12. 2010). Programming in Scala: A Comprehensive Step-by-step Guide (2nd изд.). Artima Inc. стр. 883/852. ISBN 978-0-9815316-4-9.
- Pollak, David (25. 5. 2009). Beginning Scala (1st изд.). Apress. стр. 776. ISBN 978-1-4302-1989-7. Архивирано из оригинала 5. 12. 2010. г. Приступљено 15. 11. 2015.
- Perrett, Tim (2011). Lift in Action (1st изд.). Manning. стр. 450. ISBN 978-1-935182-80-1.
- Loverdos, Christos; Syropoulos, Apostolos (2010). Steps in Scala: An Introduction to Object-Functional Programming (1st изд.). Cambridge University Press. стр. xviii + 485. ISBN 978-0-521-74758-5. Непознати параметар
|isbn/item2713441/?site_locale=
игнорисан (помоћ) - Subramaniam, Venkat (28. 7. 2009). Programming Scala: Tackle Multi-Core Complexity on the Java Virtual Machine (1st изд.). Pragmatic Bookshelf. стр. 250. ISBN 978-1-934356-31-9. Архивирано из оригинала 19. 12. 2010. г. Приступљено 15. 11. 2015.
- Horstmann, Cay (2012). Scala for the Impatient (1st изд.). Addison-Wesley Professional. стр. 360. ISBN 978-0-321-77409-5.