{{위키데이터 속성 추적}}
{{프로그래밍 언어 정보
|이름 = 스칼라<br />Scala
|로고 = Scala-full-color.svg
|패러다임 = [[프로그래밍 패러다임]]: [[함수형 프로그래밍]], [[객체 지향 프로그래밍]], [[명령형 프로그래밍]], [[병행 컴퓨팅]]
| year = {{시작 날짜와 나이|2004|01|20|df=yes}}
|설계자 = [[마틴 오더스키]]
|개발자 = École Polytechnique Fédérale de Lausanne
|형 체계 = [[자료형 체계|정적 타입]], [[자료형 체계|강한 타입]], 추론적 타입, 구조적 타입
|구현체 = 
|파일 확장자 = .scala, .sc
|방언 =
|영향을 받은 언어 = [[에펠 (프로그래밍 언어)|에펠]], [[얼랭]], [[하스켈]], [[자바 (프로그래밍 언어)|자바]], [[리스프]], [[:en:Pizza (programming language)|피자]], [[:en:Standard ML|스텔데드 ML]], [[OCaml]], [[스킴 (프로그래밍 언어)|스킴]], [[스몰토크]], [[오즈 (프로그래밍 언어)|오즈]]
|영향을 준 언어 = [[:en:Ceylon (programming language)|실론]], [[:en:Fantom (programming language)|팬텀]], [[F 샤프|F#]], [[코틀린 (프로그래밍 언어)|코틀린]], [[:en:Lasso (programming language)|랩소]], [[:en:Red (programming language)|레드]]
|라이선스 = [[BSD 라이선스]]
| latest release version = {{wikidata|property|edit|reference|P548=Q2804309|P348}}
| latest release date = {{시작 날짜와 나이|{{wikidata|qualifier|single|P548=Q2804309|P348|P577}}}}
| latest preview version = {{wikidata|property|edit|reference|P548=Q51930650|P348}}
| latest preview date = {{시작 날짜와 나이|{{wikidata|qualifier|single|P548=Q51930650|P348|P577}}}}
|웹사이트 = {{URL|https://www.scala-lang.org/}}
}}

'''스칼라'''({{llang|en|Scala}})는 [[객체 지향 프로그래밍|객체 지향]] [[프로그래밍 언어]]와 [[함수형 프로그래밍]]의 요소가 결합된 [[다중패러다임 프로그래밍 언어]]이다. ''스칼라''라는 이름은 "'''Sca'''lable '''La'''nguage (확장 가능한 언어)"에서 유래되었다.

Java와 다르게, 스칼라는 [[커링]], [[불변객체|불변성]], [[느긋한 계산법]], [[패턴 매칭]] 등 여러 [[함수형 프로그래밍|함수형 프로그래밍 언어]]의 기능을 가지고 있다. 스칼라의 [[자료형 체계]]는 [[대수적 자료형]], [[공변성과 반공변성 (컴퓨터 과학)|공변성]], 고차 자료형, 익명 자료형을 지원해 Java에서는 이룰 수 없는 높은 수준의 [[추상화 (컴퓨터 과학)|추상화]]를 달성할 수 있다.

스칼라는 2004년 [[마틴 오더스키]]가 처음 개발하여 배포했다. 간결한 소스 코드를 사용하여 Java에서 구현할 수 있는 대부분의 기능을 구현할 수 있다.<ref name="pis">Programming in Scala, Martin Odersky, Lex Spoon, Bill Venners. Artima Press</ref> Scala는 자바 [[바이트코드]]를 사용하기 때문에 [[자바 가상 머신]](JVM)에서 실행할 수 있고, Java 언어와 호환되어 대부분의 자바 API를 그대로 사용할 수 있다.

== 자바와의 연관성 ==
=== 공통점 ===
대부분의 스칼라 관련 문서들에서 스칼라와 자바의 연관성을 '너무 바빠서 다른 언어를 따로 배울 시간이 없는 자바 프로그래머를 위한'<ref>http://www.ibm.com/developerworks/java/library/j-scala01228.html - The busy Java developer's guide to Scala</ref>이라는 표현을 사용하여 나타낼 정도로 비슷한 부분이 많이 나타난다.
==== 패키지 ====
import 키워드를 통해 사용할 패키지의 선언을 한다. 이 때 _(밑줄, underscore)을 사용함을 통해 패키지나 객체의 멤버에 대해 접근성을 향상시킬 수 있다.
<syntaxhighlight lang="scala">
import java.util.Scanner
import scala.collection.mutable._
</syntaxhighlight>
==== [[자바 API]]의 사용 ====
스칼라에서는 [[자바 API]]도 사용할 수 있다. 다음은 java.util.Scanner를 통해 문자열 입력을 받아 출력하는 예제이다.
<syntaxhighlight lang="scala">
import java.util._

object Example1 {
  val s = new Scanner(System.in)
  def main(args: Array[String]): Unit = {
    println("Your input: " + s.nextLine)
  }
}
</syntaxhighlight>

==== 실행 환경 ====
스칼라 고유의 라이브러리 파일을 추가로 가지고 있으면 기존의 [[자바 가상 머신]]에서 그대로 실행할 수 있다. 다음은 리눅스에서 자바 실행기(CUI환경)를 통해 스칼라로 컴파일한 프로그램을 실행하는 예이다.(bin에 클래스 파일들이, lib에 스칼라 라이브러리 파일들이 있다고 가정한다.)
<syntaxhighlight lang="bash">
java -cp .:./bin:./lib/* Example1
</syntaxhighlight>

=== 차이점 ===
==== 타입 추론 ====
컴파일러에 의해 [[타입 추론]]이 가능한 경우, 변수의 타입, 함수의 리턴 타입 등을 생략할 수 있다.

예: <code>val x = "foo"</code> , <code>var x = 1.5</code>
==== 자료형 ====
[[자바 (프로그래밍 언어)|자바]]에서의 자료형은 기본 자료형(int, short, long, float, double, byte, char, boolean)과 참조 자료형(기본 자료형의 조합으로 생성한 클래스)으로 나뉜다. 이는 성능에는 도움이 될 지 몰라도 기본 자료형과 참조 자료형 간의 변환 문제로 언어의 표현이 복잡해지는 경향이 있다. 이에 반해 스칼라에서는 [[스몰토크]]나 [[루비]]와 같이 모든 자료형을 객체로 취급하고 있다.<ref name="ref">서광열의 프로그래밍 언어 이야기, 마이크로소프트웨어 2008년 5월호</ref> 그 예로 3 + 4 와 같은 수식은 정수 3의 메소드 +를 4라는 정수 인자값으로 호출한다고 표현하여 (3).+(4) 와 같이 표현할 수 있다. 스칼라의 모든 객체는 scala 패키지의 Any를 최상위 클래스로 값(AnyVal)과 레퍼런스(AnyRef)를 모두 아우르고 있다.<ref name="ref"/><ref>Programming in Scala, Martin Odersky, Lex Spoon, Bill Venners. Artima Press</ref>
==== 싱글턴 객체 ====
{{참고|싱글턴 패턴}}
[[자바 (프로그래밍 언어)|자바]]에서는 생성자를 private를 통해 선언함과 메소드를 static으로 선언함을 통해 싱글턴 객체를 생성한다. 이렇게 생성된 객체는 생성자가 private으로 선언되어있기 때문에 새로 객체를 생성할 수 없고 static 메소드를 통해 어디서나 접근하는 것이 가능하다. 하지만 static은 객체지향이 지향하는 바에 부합하지도 않을 뿐 더러 객체를 프로그램 실행 초기에 미리 생성해두어야 하기 때문에 자원의 낭비 가능성이 존재하게 된다.<ref name="singleton">http://kyungseo.pe.kr/blog/111 {{웨이백|url=http://kyungseo.pe.kr/blog/111 |date=20100429135928 }} - 결론>정적 클래스 변수(메서드) vs. 싱글턴 패턴</ref> 이를 스칼라에서는 object라는 키워드를 통해 선언한다. 내부동작에는 크게 차이가 없으나 코드 표현에 있어서 간결성을 보인다.
==== 다중 상속 ====
{{참고|믹스인}}
[[자바 (프로그래밍 언어)|자바]]와 다르게, 스칼라는 트레잇(Trait)을 이용해 [[다중상속]]을 구현할 수 있다. 스칼라의 트레잇은 자바의 인터페이스와 비슷하지만, 구체적인 구현을 담을 수 있다는 점에서 큰 차이점을 가진다. with 키워드를 이용해 트레잇을 여러개 상속한다면 트레잇은 상속한 순서에 따라 [[믹스인]]되어 상속의 모호성 문제("[[다중상속|다이아몬드 문제]]")를 피할 수 있다.

== 스칼라 API ==
* 각 버전별 Scala API 문서
** [http://www.scala-lang.org/docu/files/api/index.html scaladoc]<br />
** [https://web.archive.org/web/20100428083510/http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/index.html scaladoc nightly]<br />

== 자바 API ==
{{참고|자바 API}}

== 예제 ==
=== Hello, world 프로그램 ===
<syntaxhighlight lang="scala">
object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello, world!")
  }
}
</syntaxhighlight>

=== Hello, world 프로그램 2 ===
<syntaxhighlight lang="scala">
object HelloWorld extends App {
  println "Hello, world!"
}
</syntaxhighlight>

=== 퀵 정렬 프로그램 ===
{{참고|퀵 정렬}}
[[명령형 프로그래밍]] 방식으로 구현한 경우 ▼
<syntaxhighlight lang="scala">
def qsort(arr: Array[Int]): Array[Int] = {
  def swap(i: Int, j: Int): Unit = {
    val tmp = arr(i)
    arr(i) = arr(j)
    arr(j) = tmp
  }

  def partition(left: Int, right: Int): Unit =
    if (right <= left ) ()
    else {
      val pivot = arr((left + right) / 2)
      var i = left
      var j = right

      while (i <= j) {
        while (arr(i) < pivot) i += 1
        while (arr(j) > pivot) j -= 1

        if (i <= j) {
          swap(i, j)

          i += 1
          j -= 1
        }
      }

    if (left < j) partition(left, j)
    if (j < right) partition(i, right)
  }

  partition(0, arr.length - 1)
  arr
}
</syntaxhighlight>
if-else문을 사용한 경우 ▼
<syntaxhighlight lang="scala">
def qsort(seq: Seq[Int]): Seq[Int] =
  if (seq.isEmpty) seq
  else {
    val (pivot, rest) = (seq.head, seq.tail)
    val (lt, ge) = rest partition { _ < pivot }
    qsort(lt) ++ (pivot +: qsort(ge))
  }
</syntaxhighlight>
패턴 매칭을 활용한 경우 ▼
<syntaxhighlight lang="scala">
def qsort(seq: Seq[Int]): Seq[Int] = seq match {
  case pivot +: rest =>
    val (lt, ge) = rest partition { _ < pivot }
    qsort(lt) ++ (pivot +: qsort(ge))
  case _             =>
    seq
}
</syntaxhighlight>
[[제네릭 프로그래밍|제네릭]]을 활용한 경우 ▼
<syntaxhighlight lang="scala">
def qsort[T](seq: Seq[T], lessThan: (T, T) => Boolean): Seq[T] = seq match {
  case pivot +: rest =>
    val (lt, ge) = rest partition { lessThan(_, pivot) }
    qsort(lt, lessThan) ++ (pivot +: qsort(ge, lessThan))
  case _             =>
    seq
}
</syntaxhighlight>
뷰 바운드(View Bounds)을 활용한 경우 ▼
<syntaxhighlight lang="scala">
def qsort[T <% Ordered[T]](seq: Seq[T]): Seq[T] = seq match {
  case pivot +: rest =>
    val (lt, ge) = rest partition { _ < pivot }
    qsort(lt) ++ (pivot +: qsort(ge))
  case _             =>
    seq
}
</syntaxhighlight>
컨텍스트 바운드(Context Bounds)을 활용한 경우 ▼
<syntaxhighlight lang="scala">
def qsort[T: Ordering](seq: Seq[T]): Seq[T] = seq match {
  case pivot +: rest =>
    val (lt, ge) =
      rest partition { implicitly[Ordering[T]].lt(_, pivot) }
    qsort(lt) ++ (pivot +: qsort(ge))
  case _             =>
    seq
}
</syntaxhighlight>
== 같이 보기 ==
* [[아파치 스파크]]
* [[Neo4j]]
* [[플레이 프레임워크]]
* [[Akka]]
== 각주 ==
{{각주}}

== 외부 링크 ==
* {{공식 웹사이트}}

{{자바 (소프트웨어 플랫폼)}}
{{주요 프로그래밍 언어}}

{{전거 통제}}

[[분류:객체 지향 프로그래밍 언어]]
[[분류:함수형 프로그래밍 언어]]
[[분류:명령형 프로그래밍 언어]]
[[분류:JVM 프로그래밍 언어]]
[[분류:2003년 개발된 프로그래밍 언어]]
[[분류:자바 프로그래밍 언어 계열]]
[[분류:스크립트 언어]]
[[분류:스칼라로 작성된 자유 소프트웨어]]
[[분류:BSD 라이선스 소프트웨어]]
[[분류:자유 컴파일러와 인터프리터]]
[[분류:패턴 매칭 프로그래밍 언어]]
[[분류:소스 대 소스 컴파일러]]
[[분류:병행 프로그래밍 언어]]
[[분류:정적 타입 프로그래밍 언어]]