필사 모드: 모던 Scala 2026 — Scala 3.6 / 3.7 / ZIO 2 / Cats Effect 3 / Pekko / Tapir / Mill / Scala CLI 심층 가이드
한국어목차
1. 2026년 모던 Scala — Scala 3 정착의 시대
Scala는 한때 "이상한 언어"로 불렸습니다. 2020년대 초만 해도 "Scala는 어렵다", "Scala 2는 컴파일이 느리다", "팀에 도입하기엔 학습 곡선이 너무 가파르다"는 얘기가 흔했습니다. 2026년의 Scala는 다릅니다. **Scala 3가 정착**했고, 빌드 도구는 다양화됐으며, **ZIO/Cats Effect 같은 효과 시스템**이 성숙했고, **Pekko가 Akka의 BSL 라이선스 사태를 흡수**했습니다. 동시에 **Effect.ts**처럼 Scala의 아이디어가 TypeScript로 역수출되는 흥미로운 현상도 일어나고 있습니다.
이 글은 2026년 5월 기준 Scala 생태계를 한 번에 정리하는 심층 가이드입니다.
2026년 Scala를 둘러싼 큰 흐름
| 흐름 | 내용 |
|------|------|
| Scala 3 정착 | Scala 3.6 (2024.12) / 3.7 (2025.3) 안정화, Scala 4 preview 진행 중 |
| 빌드 도구 분화 | sbt 2.x (느린 전환), Mill (Li Haoyi), Scala CLI (스크립트·POC) |
| 효과 시스템 양분 | ZIO 2 vs Cats Effect 3 — 두 진영의 공존 |
| Akka 사태 후폭풍 | Akka가 BSL로 전환 (2022), Apache Pekko로 fork — 사실상 표준 |
| 웹 프레임워크 안정 | http4s, Tapir, Play Framework 3 — 함수형 웹 스택 |
| 다른 플랫폼 | Scala.js (JS), Scala Native 0.5 (네이티브 바이너리) |
| 데이터 엔지니어링 | Apache Spark의 핵심 언어 — 여전히 큰 시장 |
| 아이디어 역수출 | Effect.ts (TS), Iron (refined types), magnolify |
| 채택 현황 | Lichess, 토스 일부, 메가존, Septeni, Money Forward 등 |
Scala가 사라지지 않는 이유
여러 번 "Scala 끝났다"는 얘기가 있었지만, 2026년의 Scala는 분명한 자리를 차지하고 있습니다.
- **Spark이 사실상 Scala로 쓰여 있음** — 데이터 엔지니어링·ML 파이프라인의 핵심
- **JVM의 표현력 한계를 가장 잘 뚫는 언어** — Kotlin보다 더 깊은 함수형, Java보다 더 강한 타입
- **효과 시스템(ZIO/Cats Effect)이 정말로 작동** — 산업 검증된 FP 스택
- **Iron 같은 refined types로 타입 안전성의 최전선** — 다른 언어가 따라잡지 못함
- **Lichess처럼 단일 회사가 백만 명을 운영하는 사례** — Scala의 실전 능력 증명
이제 하나씩 살펴봅시다.
2. Scala 3.6 (2024.12) / 3.7 (2025.3) — 새 기능들
Scala 3는 2021년 5월 정식 출시 이후 꾸준히 발전해왔습니다. 2024년 말과 2025년 초에 나온 3.6과 3.7은 "Scala 3가 진짜로 안정됐다"는 신호를 보낸 릴리스입니다.
Scala 3.6의 주요 변경
Scala 3.6 (2024년 12월 8일)에서는 다음이 핵심입니다.
- **Quotes API 안정화** — 매크로 작성이 훨씬 쉬워짐
- **Named tuples (실험)** — 튜플에 이름 붙이기, `("Alice", 30)` 대신 `(name = "Alice", age = 30)`
- **Type ascription warnings** — 모호한 타입 표기에 경고
- **`-Wunused` 개선** — 사용하지 않는 import/var 경고 정교화
- **Capture checking 발전** — Scala 4의 핵심 기능 미리보기
// Named tuples (3.6 실험, 4.0 정식)
val person = (name = "Alice", age = 30)
val n: String = person.name // 필드명으로 접근
val a: Int = person.age
// 함수 인자도 named tuple로
def greet(p: (name: String, age: Int)): String =
s"Hello $p.name, $p.age years old"
Scala 3.7의 변경
Scala 3.7 (2025년 3월 27일)은 마이너 릴리스지만 실질적으로 중요한 개선이 많습니다.
- **`@experimental` 어노테이션 정리** — 어떤 기능이 stable이고 어떤 게 실험인지 더 명확
- **Best-effort compilation** — IDE에서 일부 에러가 있어도 자동완성 가능
- **컴파일 속도 개선** — Scala 2 시절의 악명이 점점 옅어짐
- **JDK 25 호환성** — 가장 최신 LTS와 호환
- **새 인라인 API** — `inline def`의 정교한 컨트롤
컴파일 속도 — 가장 큰 불만이 사라지는 중
Scala 2.x는 컴파일이 느리기로 악명 높았습니다. Scala 3.7은 다음 덕분에 빨라졌습니다.
| 기법 | 효과 |
|------|------|
| Incremental compilation (Zinc) 개선 | 변경된 파일만 다시 컴파일 |
| Pickle 캐시 | 타입 정보 재사용 |
| 병렬 컴파일 | 모듈 단위 병렬화 |
| `bloop` 사용 | 백그라운드 컴파일 서버 |
여전히 Java나 Kotlin보다는 느립니다. 하지만 "콜라 마시고 기다리는 컴파일"은 옛말입니다.
마이그레이션 도구
Scala 2 → 3 마이그레이션은 다음 도구로 자동화됩니다.
Scalafix - 자동 리팩토링
sbt "scalafixAll dependency:Scala3RewriteFromScala2Old@org.scalameta:scalafix-rules:0.13.0"
Scala 3 컴파일러의 자동 마이그레이션 모드
scalac -source:3.0-migration MyFile.scala
scala-migrate CLI
cs install scala-migrate
scala-migrate migrate-build
대부분의 Scala 2 코드는 **자동 마이그레이션**으로 80~90%가 해결됩니다.
3. Scala 4 preview — 앞으로
Scala 4는 아직 정식 출시가 아니지만, **2025년 후반부터 preview**가 활발하게 진행되고 있습니다. 핵심은 "Scala 3에서 실험으로 들어간 기능을 정식화"하는 것입니다.
Scala 4가 노리는 것
- **Capture checking 정식화** — 변경 가능 자원의 추적, 메모리 안전 보장
- **Named tuples 정식화** — 가벼운 레코드 타입
- **Match types 개선** — 타입 레벨 패턴 매칭
- **암시(implicit) 시스템 단순화** — `given`/`using`만 남기는 방향
- **컴파일러 내부 정리** — TASTy 포맷 안정화
Capture checking이란
Scala 3.x에서 실험으로 들어왔고 Scala 4에서 정식화될 가장 큰 변화입니다. 함수가 "어떤 자원을 캡처하는지"를 타입 시스템이 추적합니다.
// Scala 4 preview
// f가 io 자원을 캡처한다고 명시
def withFile[T](path: String)(f: File^ => T): T = ???
// ^ capability
// 캡처된 자원을 외부로 새지 않게 컴파일러가 보장
val data = withFile("a.txt") { file =>
file.readAll()
}
// 컴파일 에러: file을 반환하려고 하면 안 됨
val leaked = withFile("a.txt") { file => file } // ERROR
이건 **Rust의 borrow checker와 비슷한 아이디어**이지만 JVM 위에서 동작합니다. ZIO/Cats Effect의 `Resource`를 언어 수준에서 다루는 셈입니다.
Scala 4의 출시 시점
EPFL(Scala를 만든 곳)과 Scala Center가 공식적으로 "2026년 후반~2027년 초"를 목표로 발표했습니다. 단, Scala는 "메이저 버전이라고 호환성을 깨지 않는다"는 정책으로 가고 있어서, Scala 4가 나와도 Scala 3 코드는 대부분 그대로 빌드됩니다.
4. sbt 2.x / Mill / Scala CLI — 빌드 도구 진화
오랫동안 Scala 빌드 도구는 **sbt**였습니다. 강력하지만 학습 곡선이 가파르고, 한 번 망가지면 디버깅이 끔찍하다는 평이 많았죠. 2026년의 풍경은 달라졌습니다.
sbt 2.x — 느린 전환
sbt 2.x는 2024년부터 RC 단계에 있고, 2026년 5월 현재도 완전한 1.x 대체는 못 했습니다. 주요 변경점.
- **빌드 정의를 Scala 3로 작성 가능**
- **새 plugin model** — 의존성 충돌 감소
- **`Task` API 정리**
- **컴파일/실행 분리** — incremental 향상
// build.sbt (sbt 2.x 스타일)
ThisBuild / scalaVersion := "3.7.0"
ThisBuild / version := "0.1.0-SNAPSHOT"
lazy val root = (project in file("."))
.settings(
name := "my-app",
libraryDependencies ++= Seq(
"dev.zio" %% "zio" % "2.1.10",
"org.scalatest" %% "scalatest" % "3.2.19" % Test
)
)
Mill — Li Haoyi의 대안
[Mill](https://mill-build.com/)은 Li Haoyi가 만든 빌드 도구입니다. sbt의 "DSL 마법"에 지친 사람들을 위해 **순수 Scala 객체로 빌드를 정의**합니다.
// build.sc
object app extends ScalaModule {
def scalaVersion = "3.7.0"
def ivyDeps = Agg(
ivy"dev.zio::zio:2.1.10"
)
object test extends ScalaTests {
def ivyDeps = Agg(ivy"org.scalatest::scalatest:3.2.19")
def testFramework = "org.scalatest.tools.Framework"
}
}
Mill의 장점.
- **명시적** — 빌드 로직이 그냥 Scala 메서드. 마법 없음
- **빠름** — 변경 감지가 더 정확
- **이해 가능한 에러** — sbt보다 디버깅 쉬움
Twitter, Databricks 일부 팀이 Mill로 옮겼다는 보고가 있습니다.
Scala CLI — 스크립트의 정답
Scala CLI는 **Scala Center의 공식 도구**로, 작은 스크립트·POC·학습용으로 sbt를 완전히 대체합니다.
설치
brew install Virtuslab/scala-cli/scala-cli
한 파일짜리 스크립트
scala-cli run hello.scala
의존성을 코드 안에서 선언
cat > script.scala <<'EOF'
//> using scala 3.7.0
//> using dep dev.zio::zio:2.1.10
object Main extends ZIOAppDefault:
def run = Console.printLine("Hello from Scala CLI")
EOF
scala-cli run script.scala
단일 바이너리로 패키징 (Scala Native)
scala-cli package --native --output myapp script.scala
Scala CLI는 2024년 이후로 **`scala` 커맨드의 공식 백엔드**가 됐습니다. 즉 그냥 `scala myfile.scala`를 치면 내부적으로 Scala CLI가 돌아갑니다.
빌드 도구 비교
| 항목 | sbt 2.x | Mill | Scala CLI |
|------|---------|------|-----------|
| 대상 | 대형 프로젝트 | 중대형 프로젝트 | 스크립트·작은 앱 |
| 빌드 정의 | `build.sbt` (DSL) | `build.sc` (Scala 객체) | `using` 디렉티브 |
| 학습 곡선 | 가파름 | 중간 | 거의 없음 |
| 속도 | 보통 | 빠름 | 매우 빠름 |
| 플러그인 생태계 | 매우 풍부 | 보통 | 제한적 |
| 추천 사용 | 기존 sbt 프로젝트 | 새 프로젝트 | 학습·POC |
5. ZIO 2 — 함수형 효과 진영
[ZIO](https://zio.dev)는 Scala의 함수형 효과 시스템 중 가장 인기 있는 라이브러리입니다. 2026년 5월 기준 **ZIO 2.1.x**가 표준이며, ZIO 3 로드맵도 공개돼 있습니다.
ZIO의 핵심 아이디어 — `ZIO[R, E, A]`
ZIO 값은 **3가지 타입 파라미터**를 가집니다.
- `R` (Environment) — 이 효과가 실행되려면 필요한 의존성
- `E` (Error) — 실패할 수 있는 에러 타입
- `A` (Success) — 성공 시 반환되는 값 타입
// Int를 반환하지만 Throwable로 실패 가능
val task1: ZIO[Any, Throwable, Int] = ZIO.attempt(42)
// DB 환경이 필요하고, AppError로 실패하며, User를 반환
val task2: ZIO[Database, AppError, User] =
ZIO.serviceWithZIO[Database](_.getUser(123))
// 조합
val task3: ZIO[Database, AppError, String] =
for {
user <- task2
_ <- Console.printLine(s"Got user: $user.name").orDie
} yield user.name
ZIO Layer — 의존성 주입
ZIO의 가장 강력한 부분은 **Layer 시스템**입니다. Spring DI의 함수형 버전.
trait Database:
def getUser(id: Int): Task[User]
class LiveDatabase(config: DbConfig) extends Database:
def getUser(id: Int): Task[User] = ZIO.attempt(???)
object LiveDatabase:
val layer: ZLayer[DbConfig, Nothing, Database] =
ZLayer.fromFunction(LiveDatabase(_))
// 조합
val appLayer = DbConfig.layer >>> LiveDatabase.layer
ZIO 2의 새 기능
- **`Scope`로 자원 관리** — `ZManaged` 삭제, 더 단순한 API
- **`ZStream` 안정화** — 백프레셔가 있는 스트림 처리
- **`ZIO.attemptBlocking`** — 블로킹 작업 자동 격리
- **`ZIO.logSpan`** — 분산 추적 통합
ZIO 생태계
| 라이브러리 | 역할 |
|------------|------|
| zio-http | HTTP 서버·클라이언트 |
| zio-json | JSON 직렬화 |
| zio-config | 설정 관리 |
| zio-quill | 컴파일 타임 SQL 생성 |
| zio-kafka | Kafka 통합 |
| zio-prelude | 함수형 데이터 타입 |
| zio-schema | 스키마 기반 직렬화 |
6. Cats Effect 3 — 다른 함수형 진영
[Cats Effect](https://typelevel.org/cats-effect/)는 ZIO와 함께 Scala 함수형 효과의 양대 산맥입니다. Typelevel 진영(Cats, Cats Effect, http4s, doobie 등)이 만든 라이브러리로, **`IO[A]`라는 단순한 타입**을 중심으로 합니다.
`IO[A]` — 단순함의 미학
val program: IO[String] = for {
_ <- IO.println("Enter your name:")
name <- IO.readLine
_ <- IO.println(s"Hello, $name!")
} yield name
object Main extends IOApp.Simple:
def run: IO[Unit] = program.void
ZIO vs Cats Effect — 어디가 다른가
| 항목 | ZIO 2 | Cats Effect 3 |
|------|-------|---------------|
| 핵심 타입 | `ZIO[R, E, A]` | `IO[A]` |
| 에러 추적 | 타입으로 명시 (`E`) | 모두 `Throwable` |
| 의존성 주입 | `Layer` 시스템 | typeclass + `Resource` |
| 학습 곡선 | 가파름 (3개 타입 파라미터) | 완만 (1개 파라미터) |
| 생태계 | zio-* 시리즈 | Typelevel 진영 |
| 철학 | "다 같이 ZIO에서" | "작은 라이브러리 조합" |
Cats Effect의 강점
- **타입클래스 기반** — `MonadCancel`, `Concurrent`, `Async`로 분해됨
- **`Fiber`로 동시성** — 가벼운 그린 스레드
- **`Resource[F, A]`로 자원 관리** — try-with-resources의 함수형 버전
- **Loom 호환** — JDK 21+ 가상 스레드와 자연스럽게 어우러짐
// Resource로 자원 안전 관리
val dbResource: Resource[IO, Connection] =
Resource.make(IO(openConnection()))(c => IO(c.close()))
val program: IO[Unit] =
dbResource.use { conn =>
IO(conn.query("SELECT 1"))
}
// 예외가 나도 conn.close()는 보장됨
진영 선택의 실제
현장에서는 다음 패턴이 흔합니다.
- **신규 팀** → ZIO 2 (러닝 자료가 풍부, 의존성 주입이 자연스러움)
- **이미 Typelevel 스택을 쓰는 팀** → Cats Effect 3
- **둘 다 안 쓰는 팀** → 그냥 Future나 동기 코드로 시작 후 필요하면 도입
종교 전쟁 같은 면이 있어서, 팀이 합의한 쪽으로 가면 됩니다.
7. Pekko (Apache, Akka fork) — BSL 사태 이후
Scala 생태계에서 가장 정치적이고 충격적인 사건은 **2022년 9월 Akka의 라이선스 변경**이었습니다.
Akka가 BSL로 간 사건
Lightbend(Akka를 만든 회사)는 2022년 9월 7일 **Akka 2.7+를 BSL(Business Source License)로 전환**한다고 발표했습니다. 핵심 조건.
- 비상업적 사용은 무료
- 상업적 사용은 매년 일정 매출 이상부터 유료
- 3년 후 Apache 2.0으로 전환 (delayed open source)
이는 Scala 커뮤니티에 충격을 줬습니다. Akka는 Play Framework, Lagom, Spark Streaming, 그리고 수많은 회사의 백본이었기 때문입니다. **Lightbend의 입장은 "회사가 살아야 라이브러리도 산다"였지만**, 커뮤니티는 "신뢰가 깨졌다"고 반응했습니다.
Apache Pekko의 등장
2022년 말, Apache Software Foundation 산하에서 **Pekko**가 출범했습니다. Akka 2.6.x를 fork한 프로젝트로, 100% Apache 2.0 라이선스입니다.
// Akka (BSL)
// Pekko (Apache 2.0) - 거의 동일
object Greeter:
sealed trait Command
case class Greet(name: String) extends Command
def apply(): Behavior[Command] = Behaviors.receive { (ctx, msg) =>
msg match
case Greet(name) =>
ctx.log.info(s"Hello $name")
Behaviors.same
}
차이는 **패키지명 `akka.*` → `org.apache.pekko.*`** 뿐입니다. 마이그레이션은 sed 한 줄.
2026년의 현실
- **신규 프로젝트는 거의 100% Pekko** — 상업 라이선스 리스크 없음
- **기존 Akka 사용자는 Pekko로 이동 진행 중** — Lightbend의 매출은 BSL로 회복했지만, 신뢰 회복은 못 함
- **Pekko의 메이저 릴리스가 활발** — 커뮤니티가 자력으로 발전 중
- **Play Framework 3도 Pekko 기반**
Pekko의 사용처
- **분산 시스템** — 액터 모델로 큰 규모 처리
- **스트리밍** — Pekko Streams, Pekko Connectors (Kafka, Cassandra 등)
- **HTTP 서버** — Pekko HTTP
- **이벤트 소싱** — Pekko Persistence
이벤트 기반 시스템을 만든다면 2026년에는 Pekko가 사실상의 표준입니다.
8. Play Framework 3 / http4s / Tapir — 웹
Scala 웹 프레임워크는 **세 가지 진영**으로 정리됩니다.
Play Framework 3 — 풀스택 프레임워크
[Play 3](https://www.playframework.com/)는 Rails 같은 풀스택 MVC 프레임워크입니다. 2023년 말에 Pekko 기반으로 리빌드됐습니다.
// Play 3 컨트롤러
package controllers
@Singleton
class HomeController @Inject() (cc: ControllerComponents)
extends AbstractController(cc):
def index() = Action { implicit request =>
Ok("Hello from Play 3")
}
def user(id: Int) = Action.async { implicit request =>
userService.get(id).map(u => Ok(Json.toJson(u)))
}
장점 — 풀스택, 템플릿 엔진, 폼 검증, 자산 파이프라인 다 포함.
단점 — "함수형스럽지 않다", 학습 곡선.
http4s — 함수형 웹
[http4s](https://http4s.org)는 **Cats Effect 기반의 순수 함수형 웹 서버**입니다.
val helloService = HttpRoutes.of[IO] {
case GET -> Root / "hello" / name =>
Ok(s"Hello, $name")
}.orNotFound
object Main extends IOApp.Simple:
def run = EmberServerBuilder
.default[IO]
.withHost(ipv4"0.0.0.0")
.withPort(port"8080")
.withHttpApp(helloService)
.build
.useForever
장점 — 순수 함수형, 작동 명확, Cats Effect와 자연스럽게 통합.
단점 — 처음 보면 마법 같음, 미들웨어 작성이 까다로움.
Tapir — 타입 안전 API 정의
[Tapir](https://tapir.softwaremill.com)는 Scala 커뮤니티의 비밀 무기입니다. **엔드포인트를 타입 수준에서 정의**하면 코드, 클라이언트, OpenAPI 스펙이 자동 생성됩니다.
case class User(id: Int, name: String)
// 엔드포인트를 값으로 정의
val getUser =
endpoint
.get
.in("users" / path[Int]("id"))
.out(jsonBody[User])
.errorOut(stringBody)
// http4s로 서빙
val routes = Http4sServerInterpreter[IO]()
.toRoutes(getUser.serverLogic(id => IO.pure(Right(User(id, "Alice")))))
// 동일한 정의로 OpenAPI 생성
val docs = OpenAPIDocsInterpreter().toOpenAPI(getUser, "My API", "1.0")
println(docs.toYaml)
엔드포인트를 한 번 정의하면.
- HTTP 서버 라우트
- 타입 안전 클라이언트
- OpenAPI/Swagger 스펙
- 자동 문서
가 모두 나옵니다. 백엔드 인터페이스 정의의 최첨단이라고 봅니다.
어떤 걸 골라야 하나
| 상황 | 추천 |
|------|------|
| 풀스택 웹앱 (템플릿 포함) | Play 3 |
| 함수형 마이크로서비스 | http4s + Tapir |
| 큰 API + 스키마 우선 | Tapir + 아무 backend |
| 액터 기반 동시성 | Pekko HTTP |
| 신규 팀, 학습 부담 적게 | Tapir + http4s |
9. Scala.js / Scala Native 0.5 — 다른 플랫폼
Scala는 JVM만의 언어가 아닙니다. **Scala.js**로 JavaScript, **Scala Native**로 LLVM 기반 네이티브 바이너리를 만들 수 있습니다.
Scala.js — JavaScript로 컴파일
[Scala.js](https://www.scala-js.org)는 Scala 코드를 JavaScript로 컴파일합니다. 2026년에는 1.18.x가 표준이며, React, Vue 같은 JS 라이브러리와의 상호운용도 깔끔합니다.
// Scala.js + Laminar (반응형 UI)
val app = div(
h1("Hello Scala.js"),
button(
"Click me",
onClick --> { _ =>
println("Clicked!")
}
)
)
render(dom.document.getElementById("app"), app)
장점 — Scala 타입 시스템을 프론트엔드에 그대로 가져옴, dead code elimination이 강력해서 번들이 작음.
단점 — JS 생태계와의 상호운용은 가능하지만 type definition을 직접 써야 할 때가 있음.
Scala Native 0.5 — LLVM 네이티브
[Scala Native](https://scala-native.org)는 Scala를 LLVM IR로 컴파일해 네이티브 바이너리를 만듭니다. **0.5.x (2024년 출시) 이후로 정말 쓸 만**해졌습니다.
// Hello, Scala Native
object Main:
def main(args: Array[String]): Unit =
stdio.printf(c"Hello from Scala Native! PID: %d\n", unistd.getpid())
컴파일
scala-cli package --native --output myapp Main.scala
실행 — JVM 없이 즉시 시작
./myapp
장점.
- **JVM 부팅 시간 제거** — CLI 도구에 이상적
- **메모리 사용량 작음** — Lambda/Cloud Run 같은 서버리스에 좋음
- **GC 선택 가능** — Boehm, Immix, Commix
- **C 라이브러리 직접 호출 가능**
단점.
- JVM 라이브러리를 다 못 씀 (리플렉션 의존 라이브러리)
- 컴파일이 LLVM 통과해서 느림
Scala CLI + Scala Native 조합으로 **단일 바이너리 CLI 도구**를 만들기 좋습니다. coursier, sbt-pack 같은 도구도 이 조합으로 배포됩니다.
10. Spark Scala — 데이터 엔지니어링
Scala가 2026년에도 살아남은 가장 큰 이유 중 하나는 **Apache Spark**입니다. Spark의 코어는 Scala로 쓰여 있고, **Scala API가 가장 빠르고 표현력이 풍부**합니다.
Spark의 현황
- Spark 3.5.x (2024년) / Spark 4.0 (2025년 출시 예정)
- Python(PySpark)이 점유율은 높지만, **고성능·복잡한 변환은 여전히 Scala**
- Databricks, Palantir 등의 대형 데이터 회사는 Scala Spark가 메인
Scala로 Spark 쓰기
val spark = SparkSession.builder
.appName("Example")
.master("local[*]")
.getOrCreate()
case class Transaction(userId: Int, amount: Double, ts: String)
val df = Seq(
Transaction(1, 100.0, "2026-01-01"),
Transaction(1, 200.0, "2026-01-02"),
Transaction(2, 50.0, "2026-01-01")
).toDF()
val agg = df
.groupBy("userId")
.agg(
sum("amount").as("total"),
count("*").as("tx_count")
)
.orderBy(desc("total"))
agg.show()
Frameless — 타입 안전 Spark
[Frameless](https://typelevel.org/frameless/)는 Spark의 `DataFrame`을 타입 안전하게 감쌉니다. 컴파일 타임에 컬럼명 오타를 잡아줍니다.
val ts: TypedDataset[Transaction] = TypedDataset.create(transactions)
val totals: TypedDataset[(Int, Double)] = ts
.groupBy(ts('userId))
.agg(sum(ts('amount)))
.as[(Int, Double)]
// 컴파일 에러: 'amounnt'라는 컬럼은 없음
val bad = ts.select(ts('amounnt)) // 컴파일 안 됨
Scala 3로 마이그레이션된 Frameless 0.16+가 안정적입니다.
데이터 엔지니어가 Scala를 배워야 할까
- **PySpark가 60% 시장** — Python으로 시작해도 됨
- **하지만 인프라/플랫폼 팀은 거의 Scala** — Databricks 자체도 Scala
- **성능이 중요한 변환은 Scala가 명확히 빠름** — JVM 직접 호출이라 직렬화 오버헤드 없음
- **결론** — 데이터 분석가는 Python, 데이터 인프라/플랫폼 엔지니어는 Scala
11. Effect.ts — TS로 옮겨간 Scala 아이디어
흥미로운 2020년대 중반 현상은 **Scala의 아이디어가 TypeScript로 역수출**된 것입니다. 대표 사례가 [Effect.ts](https://effect.website)입니다.
Effect.ts란
Effect.ts는 ZIO와 Cats Effect의 핵심 아이디어를 TypeScript에 이식한 라이브러리입니다.
// Effect.ts (TypeScript)
const program = Effect.gen(function* () {
yield* Console.log("Enter your name:")
const name = "Alice" // 실제로는 입력 받음
yield* Console.log(`Hello, ${name}`)
return name
})
Effect.runPromise(program).then(console.log)
비교해보면 ZIO와 사실상 같은 구조입니다.
// ZIO (Scala)
val program = for {
_ <- Console.printLine("Enter your name:")
name <- ZIO.succeed("Alice")
_ <- Console.printLine(s"Hello, $name")
} yield name
Runtime.default.unsafeRun(program)
왜 이런 일이 일어났나
- **TypeScript의 타입 시스템이 충분히 발전** — 제네릭, 조건부 타입, infer로 효과 추적 가능
- **JS 생태계의 비동기 지옥** — Promise/async-await로는 한계
- **함수형 진영의 TS 사용자 증가** — Haskell, Scala 출신들이 TS로 옴
- **에러 처리 표준화 욕구** — `Either`, `Option` 같은 패턴이 TS에서도 인기
이게 Scala에 주는 의미
- Scala가 만들어낸 패턴이 **언어를 초월해 살아남는다**는 증명
- Scala 사용자가 TS 풀스택을 할 때 **자연스럽게 Effect.ts를 쓸 수 있음**
- 반대로 TS에서 함수형을 깊게 한 사람이 **Scala로 자연스럽게 옮길 수 있음**
Scala 커뮤니티에서는 "우리 아이디어가 mainstream이 됐다"며 자랑스러워하는 분위기가 있습니다.
12. Iron — refined types
[Iron](https://github.com/Iltotore/iron)은 Scala 3 전용 라이브러리로 **refined types**를 구현합니다. 컴파일 타임에 타입에 제약을 거는 도구입니다.
Refined Type이란
"`Int`이지만 0보다 큰", "`String`이지만 이메일 형식인" 같은 제약을 타입 시스템에 인코딩합니다.
// 양의 정수
type PositiveInt = Int :| Positive
val age: PositiveInt = 30 // OK
val bad: PositiveInt = -5 // 컴파일 에러
// 이메일
type Email = String :| Match["""[\w.+]+@[\w.]+"""]
val email: Email = "a@b.com" // OK
val notEmail: Email = "hello" // 컴파일 에러
// 함수에서도
def sendEmail(to: Email, body: String :| MinLength[1]): Unit = ???
Iron의 강점
- **런타임 검증 없이 타입 안전** — 일반 `Int`/`String`과 메모리 호환
- **Scala 3 매크로로 컴파일 타임 검사** — 리터럴은 컴파일러가 검증
- **임의 조건 정의 가능** — 도메인 규칙을 타입으로
// 사용자 도메인 타입
type UserId = Int :| Positive
type UserName = String :| (MinLength[2] & MaxLength[50])
case class User(id: UserId, name: UserName)
// 컴파일 타임에 막힘
val u = User(0, "X")
// ERROR: 0은 Positive가 아님, "X"는 MinLength[2]가 아님
다른 언어와 비교
- TypeScript의 [Brand types](https://medium.com/@KevinBGreene/typescript-branded-types-and-the-pattern-for-domain-modeling-d016eb71affd) — Iron의 약한 버전
- Rust의 newtype pattern — 비슷한 의도, 약한 검증
- Haskell의 refined types — 가장 가까운 패턴
- F#의 units of measure — 일부 겹침
Iron은 **2026년 Scala가 가진 가장 강력한 타입 안전 도구** 중 하나입니다.
13. doobie / Slick — DB 라이브러리
Scala의 DB 라이브러리는 크게 **doobie**(함수형)와 **Slick**(SQL DSL)로 나뉩니다.
doobie — 순수 함수형 JDBC
[doobie](https://typelevel.org/doobie/)는 Cats Effect 위에서 JDBC를 함수형으로 감쌉니다.
val xa = Transactor.fromDriverManager[IO](
driver = "org.postgresql.Driver",
url = "jdbc:postgresql:test",
user = "u",
password = "p",
logHandler = None
)
case class User(id: Int, name: String)
// SQL 인터폴레이션 — 컴파일 타임에 타입 체크
def findUser(id: Int): ConnectionIO[Option[User]] =
sql"SELECT id, name FROM users WHERE id = $id".query[User].option
val program: IO[Option[User]] = findUser(1).transact(xa)
장점 — SQL을 그대로 씀, 타입 안전, Cats Effect 통합 완벽.
단점 — SQL을 잘 알아야 함, ORM의 자동 매핑 없음.
Slick — 타입 안전 SQL DSL
[Slick](https://scala-slick.org)은 SQL을 Scala DSL로 표현합니다. ORM은 아니고 query builder에 가깝습니다.
class Users(tag: Tag) extends Table[(Int, String)](tag, "USERS"):
def id = column[Int]("ID", O.PrimaryKey)
def name = column[String]("NAME")
def * = (id, name)
val users = TableQuery[Users]
// Scala 코드로 SQL 작성
val query = users
.filter(_.id === 1)
.map(_.name)
.result
val action = query
db.run(action).map(println)
장점 — SQL을 모르고도 안전한 쿼리, IDE 자동완성.
단점 — 복잡한 쿼리에서 DSL이 한계, 디버깅 어려움.
어떤 걸 골라야 하나
| 상황 | 추천 |
|------|------|
| SQL 잘 아는 팀 | doobie |
| ORM 익숙한 팀에서 마이그레이션 | Slick |
| Cats Effect 스택 | doobie (자연스러움) |
| 복잡한 동적 쿼리 | doobie (raw SQL 자유롭게) |
| 마이그레이션 자동화 함께 | Slick (codegen 강력) |
Quill — 또 다른 옵션
[Quill](https://zio.dev/zio-quill/)은 컴파일 타임에 Scala 코드를 SQL로 변환합니다. ZIO 진영이 좋아하는 옵션.
val ctx = new SqlMirrorContext(PostgresDialect, SnakeCase)
case class User(id: Int, name: String)
val q = quote {
query[User].filter(_.id == 1).map(_.name)
}
println(ctx.run(q).string)
// SELECT name FROM user WHERE id = 1
14. Lichess — Scala로 쓴 체스 사이트
Scala로 만들어진 가장 유명한 프로덕션 시스템 중 하나가 [Lichess](https://lichess.org)입니다. 100% 무료, 100% 오픈소스의 체스 사이트로 **월간 활성 사용자가 수백만 명**입니다.
Lichess의 규모
| 지표 | 값 (2025년 기준) |
|------|------------------|
| 일간 게임 수 | 700만+ |
| 월간 활성 사용자 | 1억+ 페이지뷰 |
| 동시 접속 | 수만 명 |
| 직원 수 | 풀타임 3~4명 |
| 운영 비용 | 월 1만 달러 수준 (기부 의존) |
| 코드베이스 | 100% Scala (백엔드) |
이 효율성이 미친 수준입니다. 같은 규모의 사이트가 수십 명의 엔지니어를 운영하는 데 비해, Lichess는 소수 인원과 Scala로 운영합니다.
Lichess가 Scala를 쓰는 이유 (Thibault Duplessis 인터뷰 요약)
- **타입 시스템으로 버그를 컴파일 타임에 잡음** — 운영 인력이 적기 때문에 필수
- **함수형 패러다임으로 동시성 안전** — 수만 동시 접속을 안전하게
- **Akka(현재는 Pekko)로 액터 기반 게임 처리** — 게임 한 판이 액터 하나
- **MongoDB + reactivemongo로 비동기 DB** — 모두 Scala 친화적
Lichess의 기술 스택
- 언어 — Scala 3 (2024년에 Scala 2에서 마이그레이션 완료)
- 웹 프레임워크 — Play Framework
- 액터 모델 — Pekko (전 Akka)
- DB — MongoDB
- 프론트엔드 — TypeScript (Snabbdom)
- 인프라 — 베어메탈 서버 (OVH)
배울 수 있는 점
- Scala의 표현력은 **소규모 팀이 큰 시스템을 운영하는 데 결정적**
- "스타트업 = JS/Python" 공식이 절대적이지 않음
- 오픈소스 운영의 모범 사례 — 코드는 [github.com/lichess-org](https://github.com/lichess-org)에 다 있음
Lichess는 Scala를 검토하는 팀에게 "이게 가능하다"는 살아있는 증거입니다.
15. 한국 / 일본 — 토스 일부, 메가존, Septeni, Money Forward
Scala는 한국·일본에서 주류 언어는 아니지만 **특정 회사에서 적극 활용**되고 있습니다.
한국의 Scala 채택
| 회사 | 사용처 | 비고 |
|------|--------|------|
| 토스 페이먼츠 | 일부 백엔드 (정산·통계) | 핵심은 Kotlin, 일부 Scala |
| 메가존 클라우드 | 데이터 플랫폼 | Spark 기반 |
| 라인 일부 | 데이터 엔지니어링 | Spark 중심 |
| 카카오 일부 | 검색·추천 시스템 | Spark + Scala |
| 데이터 회사 다수 | Spark 기반 ETL | Scala가 사실상 표준 |
한국에서는 **데이터 엔지니어링·플랫폼 영역**에서 Scala가 살아있고, **순수 백엔드는 거의 Kotlin/Java**로 옮겨갔습니다.
일본의 Scala 채택
일본은 한국보다 Scala 채택이 활발한 편입니다.
| 회사 | 사용처 | 비고 |
|------|--------|------|
| Septeni (CyberAgent 그룹) | 광고 플랫폼 백엔드 | 대규모 Scala 사용 |
| Money Forward | 가계부·B2B 회계 | Scala + Rails 혼용 |
| freee | 회계 SaaS 일부 | 일부 Scala 모듈 |
| Chatwork | 채팅 SaaS | Scala + Pekko |
| CyberAgent (AbemaTV) | 동영상 플랫폼 일부 | Scala + Go |
| ドワンゴ (드왕고) | 니코니코 동영상 | Scala 사용 이력 |
일본은 **2010년대 중반부터 Scala 커뮤니티가 활발**했고, ScalaMatsuri 같은 큰 컨퍼런스가 꾸준히 열립니다.
동아시아에서 Scala를 배워야 할까
- **순수 백엔드 개발자** — Kotlin이 우선, Scala는 선택
- **데이터 엔지니어** — Spark를 깊이 다룬다면 Scala는 큰 무기
- **함수형 깊이 파고 싶은 사람** — Scala는 JVM에서 최고의 함수형 언어
- **이직 시장** — 한국은 좁고, 일본은 도쿄 중심으로 시장 있음
학습 리소스 (한국어/일본어)
- [Scala School (트위터 공식 한국어 번역)](https://twitter.github.io/scala_school/ko/index.html)
- [Programming in Scala (Odersky 책, 한국어 번역)](http://www.acornpub.co.kr/book/programming-in-scala-4e)
- 일본어 — [Scala逆引きレシピ](https://www.shoeisha.co.jp/book/detail/9784798125411)
- [ScalaMatsuri](https://scalamatsuri.org) — 도쿄 매년
16. 누가 Scala를 골라야 하나 — 데이터 / FP / JVM + ML
2026년에 Scala를 새로 배워야 할 사람과 그렇지 않은 사람을 정직하게 정리합니다.
Scala가 맞는 경우
- **데이터 엔지니어** — Spark이 중심인 환경
- **함수형 깊이** — Haskell이나 OCaml에 끌리지만 JVM 생태계가 필요한 경우
- **고성능 동시성** — Pekko로 액터 기반 시스템 설계
- **타입 안전성 최전선** — Iron, refined types, capture checking
- **소규모 팀이 큰 시스템** — Lichess 같은 운영 효율
- **ML on JVM** — BigDL, Smile, Frameless 활용
Scala가 안 맞는 경우
- **빠른 채용** — Scala 개발자는 비교적 드뭄
- **간단한 CRUD 백엔드** — Kotlin/Spring이 훨씬 빠른 개발
- **Java/Kotlin 팀에 막 합류** — 정치적 비용이 큼
- **풀스택 단독 개발** — JS/TS 생태계가 풍부
- **Cloud Native, Kubernetes 도구** — Go가 사실상 표준
학습 경로 제안
초보자
↓
Scala CLI로 작은 스크립트 (1~2주)
↓
"Programming in Scala 5판" 또는
"Effective Programming in Scala" (Scala Center)
↓
case class / sealed trait / for comprehension 익숙해지기
↓
선택: ZIO 진영 or Cats Effect 진영
↓
실전 프로젝트 — http4s + Tapir로 작은 API
↓
필요시 Pekko, Spark, Iron, doobie 등 확장
다른 JVM 언어와의 위치
| 언어 | 위치 | Scala와의 관계 |
|------|------|----------------|
| Java | 풍부, 회사가 많음 | Scala가 보완 — 어려운 부분만 Scala |
| Kotlin | 백엔드의 새 강자 | Scala보다 가벼움, FP는 약함 |
| Clojure | Lisp 계열, 동적 | Scala와 매우 다른 철학 |
| Groovy | DSL용 | Scala가 더 강력 |
ML on JVM 정리
Python이 ML의 표준이지만, JVM 진영에서도 다음이 있습니다.
| 라이브러리 | 역할 |
|------------|------|
| BigDL | Spark 위 분산 딥러닝 |
| Smile | 통계·ML 라이브러리 |
| Frameless | 타입 안전 Spark |
| Deeplearning4j | DL on JVM (Java 위주) |
| ONNX Runtime Java | Python에서 학습 → JVM에서 추론 |
"학습은 Python, 추론은 JVM" 패턴이 늘고 있고, Scala가 그 추론 레이어를 깔끔하게 처리할 수 있습니다.
17. 참고 / References
Scala 공식
- [Scala 공식 사이트](https://www.scala-lang.org)
- [Scala 3 Reference](https://docs.scala-lang.org/scala3/reference/)
- [Scala 3.6 Release Notes](https://www.scala-lang.org/news/3.6.0/)
- [Scala 3.7 Release Notes](https://www.scala-lang.org/news/3.7.0/)
- [Scala Center](https://scala.epfl.ch)
빌드 도구
- [sbt 공식](https://www.scala-sbt.org)
- [Mill 빌드 도구](https://mill-build.com)
- [Scala CLI](https://scala-cli.virtuslab.org)
- [Coursier](https://get-coursier.io)
효과 시스템
- [ZIO](https://zio.dev)
- [Cats Effect](https://typelevel.org/cats-effect/)
- [Typelevel 진영](https://typelevel.org)
액터·동시성
- [Apache Pekko](https://pekko.apache.org)
- [Akka (Lightbend, BSL)](https://akka.io)
- [Lightbend BSL 공지](https://www.lightbend.com/blog/why-we-are-changing-the-license-for-akka)
웹 프레임워크
- [Play Framework](https://www.playframework.com)
- [http4s](https://http4s.org)
- [Tapir](https://tapir.softwaremill.com)
- [Scalatra](https://scalatra.org)
다른 플랫폼
- [Scala.js](https://www.scala-js.org)
- [Scala Native](https://scala-native.org)
- [Laminar (Scala.js UI)](https://laminar.dev)
데이터
- [Apache Spark](https://spark.apache.org)
- [Frameless](https://typelevel.org/frameless/)
- [Smile (ML)](https://haifengl.github.io/)
- [BigDL](https://bigdl.readthedocs.io)
타입 시스템
- [Iron (refined types)](https://github.com/Iltotore/iron)
- [Magnolify (typeclass derivation)](https://github.com/spotify/magnolify)
DB
- [doobie](https://typelevel.org/doobie/)
- [Slick](https://scala-slick.org)
- [Quill](https://zio.dev/zio-quill/)
테스트·로깅
- [ScalaTest](https://www.scalatest.org)
- [MUnit](https://scalameta.org/munit/)
- [Scribe (로깅)](https://github.com/outr/scribe)
Effect.ts (Scala 영향)
- [Effect.ts 공식](https://effect.website)
- [Effect.ts vs ZIO 비교 글](https://effect.website/docs/why-effect)
대표 프로덕션 사례
- [Lichess (Scala로 쓴 체스 사이트)](https://lichess.org)
- [Lichess GitHub](https://github.com/lichess-org)
- [Lichess Thibault Duplessis 인터뷰](https://lichess.org/blog)
컨퍼런스·커뮤니티
- [Scala Days](https://scaladays.org)
- [ScalaMatsuri (Tokyo)](https://scalamatsuri.org)
- [Scala Korea (Meetup)](https://www.meetup.com/scala-korea/)
책
- "Programming in Scala, 5th Edition" — Martin Odersky 외
- "Effective Programming in Scala" — Julien Richard-Foy (Scala Center)
- "Functional Programming in Scala, 2nd Edition" — Paul Chiusano, Runar Bjarnason
- "Zionomicon" — John A. De Goes, Adam Fraser (ZIO 책, 무료)
현재 단락 (1/588)
Scala는 한때 "이상한 언어"로 불렸습니다. 2020년대 초만 해도 "Scala는 어렵다", "Scala 2는 컴파일이 느리다", "팀에 도입하기엔 학습 곡선이 너무 가파르다"...