Belajar Scala - Konsep Dasar & Arsitektur Utama
Episode 2 of 23

Belajar Scala - Konsep Dasar & Arsitektur Utama

Membongkar arsitektur Scala: bagaimana scalac mengkompilasi source code menjadi bytecode JVM, peran scala runner, REPL, dan format TASTy dalam interoperabilitas antar versi, serta dukungan lintas platform lewat Scala.js dan Scala Native.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 1 kita memahami sejarah dan filosofi "scalable" di balik Scala, pada episode ini kita membedah mesin di balik bahasa ini: bagaimana sebuah file .scala menjadi program yang berjalan. Memahami arsitektur ini bukan sekadar pengetahuan akademis — ia menentukan cara kalian debugging, memilih tool, dan menilai kinerja program Scala di produksi.

Mengapa arsitektur penting? Karena banyak misteri Scala — kenapa startup-nya agak lambat, kenapa library Java bisa dipakai langsung, kenapa ada file .tasty di classpath — semuanya terjawab oleh satu fakta dasar: Scala dikompilasi menjadi bytecode JVM. Dari fakta tunggal ini, hampir semua perilaku tooling Scala bisa dijelaskan.

Kompilasi ke Bytecode JVM

Compiler Scala (scalac) bekerja dalam beberapa tahap. Simplifikasinya begini:

100%
  1. scalac mem-parse source code menjadi AST (Abstract Syntax Tree).
  2. Melakukan type-checking menyeluruh — di sinilah type system Scala yang ekspresif bekerja.
  3. Menurunkan (lowering) ke bentuk yang lebih sederhana, lalu menghasilkan bytecode JVM dalam file .class.
  4. JVM mengeksekusi bytecode, sama seperti Java.

Konsekuensi paling penting: library Java apa pun bisa dipakai langsung dari Scala, dan sebaliknya. Kalian menulis Scala, tetapi berbagi classpath dan runtime yang sama dengan Java. Ini adalah salah satu alasan terbesar Scala tetap relevan — ia mewarisi seluruh ekosistem JVM yang sudah matang.

Memakai library Java dari Scala
import java.time.LocalDate
 
val today = LocalDate.now()
println(today)

LocalDate adalah class Java murni — tanpa adapter, tanpa bridge, langsung bekerja.

Komponen Utama Toolchain

Arsitektur Scala tidak hanya scalac. Ada beberapa komponen yang saling melengkapi:

KomponenPeran
scalacCompiler — mengubah .scala menjadi bytecode
scala runnerMenjalankan program dan REPL (Scala CLI default sejak 3.5)
REPLShell interaktif untuk eksperimen cepat
sbt / Mill / Scala CLIBuild tool & dependency management
TASTyFormat tipe antar versi — interoperabilitas 2 → 3

scala Runner dan REPL

Sejak Scala 3.5, scala adalah front-end default untuk menjalankan kode — menggantikan peran terpisah antara scala runner lama dan scala-cli. Di Scala 3.8, REPL dipisah menjadi artifact tersendiri (scala3-repl) agar kompilasi inti lebih ringan:

Masuk REPL scala
scala
Sesi REPL
scala> val x = 1 + 2
val x: Int = 3
 
scala> x * 2
val res0: Int = 6
 
scala> :quit

REPL adalah teman terbaik untuk mempelajari bahasa: ketik ekspresi, lihat tipe hasilnya, ulangi. Di series ini kita sering menggunakannya untuk demonstrasi cepat.

TASTy: Format Interop Antar Versi

TASTy (Typed Abstract Syntax Trees) adalah format file yang dihasilkan scalac di samping bytecode. Fungsinya: menyimpan informasi tipe lengkap hasil type-checking sehingga kompiler versi lebih baru bisa membaca kode yang dikompilasi versi lama — khususnya memungkinkan Scala 3 memakai library Scala 2.

Lihat file hasil kompilasi
scalac hello.scala
ls *.class *.tasty

Ini menjawab misteri "kenapa ada dua macam file": .class untuk JVM, .tasty untuk compiler. Java hanya melihat .class; scalac memakai .tasty untuk type inference yang akurat.

Dukungan Lintas Platform: Scala.js dan Scala Native

JVM bukan satu-satunya target Scala. Arsitektur Scala 3 mendukung tiga backend sekaligus:

BackendTargetKasus pakai
JVMBytecode JVMBackend service, data pipeline (default series ini)
Scala.jsJavaScriptFrontend, berbagi logic antara client dan server
Scala NativeBinary nativeAplikasi dengan startup cepat & footprint kecil

Dengan Scala.js, kode domain yang sama bisa dipakai di server (JVM) dan browser — pola ini populer di project full-stack. Scala Native menargetkan binary tanpa JVM, cocok untuk CLI tools dan aplikasi embedded. Ketiganya dikompilasi dari source yang sama, meski dengan karakteristik runtime berbeda.

Note

Untuk series ini kita fokus penuh di backend JVM — itu target paling umum dan tempat ekosistem tooling (sbt, Metals, Spark, Kafka) paling matang. Konsep bahasa yang kalian pelajari berlaku sama untuk semua backend.

Alur Kerja Khas: Edit → Compile → Run

Arsitektur ini membentuk alur kerja harian kalian. Saat menggunakan Metals, alurnya terotomasi, tetapi penting memahami lapisannya:

100%

Metals memanggil scalac secara incremental (hanya file yang berubah) sehingga error muncul detik demi detik, bukan menit. Ini dimungkinkan karena format TASTy dan incremental compiler yang menjadi fondasi tooling Scala modern.

Common Pitfalls

Beberapa kesalahan pemahaman yang sering terjadi:

  • "Scala lambat karena kompilasinya lama" — kompilasi penuh memang bisa lama, tetapi workflow normal memakai incremental compilation; yang dirasakan lambat saat runtime biasanya berasal dari JVM warmup, bukan bahasa.
  • "File .tasty rusak" — TASTy yang dihasilkan versi Scala 2 tidak bisa dibaca Scala 3 secara langsung untuk semua kasus; inilah sebabnya library Scala 2 harus dikompilasi ulang (re-publish) agar kompatibel penuh.
  • "Scala pasti butuh library tambahan untuk Java" — tidak; interop Java adalah bawaan, bukan fitur library.

Penutup

Inti yang harus dibawa pulang:

  • Scala dikompilasi scalac menjadi bytecode JVM — inilah akar interoperabilitas dengan Java.
  • scala runner dan REPL adalah teman belajar terbaik; REPL dipisah ke artifact scala3-repl di 3.8.
  • TASTy adalah format tipe antar versi yang memungkinkan Scala 3 memakai library Scala 2.
  • Scala.js (JavaScript) dan Scala Native (binary) memperluas target di luar JVM.
  • Alur kerja normal berbasis incremental compilation via Metals/sbt.

Di episode 3 selanjutnya, kita masuk praktik pertama yang sesungguhnya: instalasi dan Hello World — verifikasi ulang toolchain, menulis program pertama dengan @main, menjalankannya lewat scala run, dan mengenal struktur program minimal Scala. Sampai jumpa di episode 3!