Closure & Fungsi Tingkat Tinggi

NusaScript mendukung fungsi sebagai nilai (first-class functions), closure, dan pola functional programming yang powerful.

Fungsi sebagai Nilai

Di NusaScript, fungsi adalah nilai seperti halnya bilangan atau teks. Fungsi bisa disimpan dalam variabel, dikirim sebagai argumen, atau dikembalikan dari fungsi lain.

Contoh — Fungsi sebagai Variabel
// Simpan fungsi dalam variabel
buat sapa = fungsi(nama) {
    kembalikan "Halo, " + nama + "!"
}

// Panggil seperti biasa
tampilkan(sapa("Budi"))   // Halo, Budi!
tampilkan(sapa("Siti"))   // Halo, Siti!

// Kirim fungsi sebagai argumen
fungsi terapkan(fn, nilai) {
    kembalikan fn(nilai)
}

buat hasil = terapkan(sapa, "Indonesia")
tampilkan(hasil)  // Halo, Indonesia!
Output
Halo, Budi!
Halo, Siti!
Halo, Indonesia!

Closure

Closure adalah fungsi yang "mengingat" lingkungan (variabel) dari scope tempat ia dibuat, bahkan setelah scope tersebut selesai dieksekusi.

Contoh — Counter Closure
// Pabrik fungsi counter
fungsi buat_counter(mulai) {
    buat hitung = mulai

    // Fungsi ini adalah closure — mengingat 'hitung'
    kembalikan fungsi() {
        hitung += 1
        kembalikan hitung
    }
}

// Buat dua counter independen
buat counterA = buat_counter(0)
buat counterB = buat_counter(100)

tampilkan(counterA())  // 1
tampilkan(counterA())  // 2
tampilkan(counterA())  // 3
tampilkan(counterB())  // 101
tampilkan(counterB())  // 102
tampilkan(counterA())  // 4 (tetap independen dari counterB)
Output
1
2
3
101
102
4

Fungsi Map — Transformasi Array

Contoh — Map Manual
// Implementasi map: terapkan fungsi ke setiap elemen
fungsi peta_array(arr, fn) {
    buat hasil = []
    buat i = 0
    selama i < panjang(arr) {
        hasil = tambah_elemen(hasil, fn(arr[i]))
        i += 1
    }
    kembalikan hasil
}

// Gunakan dengan fungsi anonim
buat angka   = [1, 2, 3, 4, 5]
buat kuadrat = peta_array(angka, fungsi(x) { kembalikan x * x })
buat ganda   = peta_array(angka, fungsi(x) { kembalikan x * 2 })

tampilkan(ke_json(kuadrat))  // [1,4,9,16,25]
tampilkan(ke_json(ganda))    // [2,4,6,8,10]
Output
[1,4,9,16,25]
[2,4,6,8,10]

Fungsi Filter

Contoh — Filter Array
// Implementasi filter: ambil elemen yang memenuhi kondisi
fungsi saring(arr, fn_kondisi) {
    buat hasil = []
    buat i = 0
    selama i < panjang(arr) {
        jika fn_kondisi(arr[i]) {
            hasil = tambah_elemen(hasil, arr[i])
        }
        i += 1
    }
    kembalikan hasil
}

buat nilai = [85, 42, 91, 67, 55, 78, 95, 38]

// Filter hanya nilai >= 70 (lulus)
buat lulus = saring(nilai, fungsi(v) { kembalikan v >= 70 })

// Filter hanya nilai genap
buat genap = saring(nilai, fungsi(v) { kembalikan v % 2 == 0 })

tampilkan("Lulus:", ke_json(lulus))  // [85,91,67,78,95]
tampilkan("Genap:", ke_json(genap))  // [42,78,38]
Output
Lulus: [85,91,78,95]
Genap: [42,78,38]

Fungsi Reduce — Akumulasi

Contoh — Reduce / Fold
// Implementasi reduce
fungsi lipat(arr, fn, awal) {
    buat akumulator = awal
    buat i = 0
    selama i < panjang(arr) {
        akumulator = fn(akumulator, arr[i])
        i += 1
    }
    kembalikan akumulator
}

buat angka = [1, 2, 3, 4, 5]

// Jumlahkan semua
buat total = lipat(angka, fungsi(acc, x) { kembalikan acc + x }, 0)
tampilkan("Total:", total)  // 15

// Kalikan semua (faktorial-like)
buat produk = lipat(angka, fungsi(acc, x) { kembalikan acc * x }, 1)
tampilkan("Produk:", produk)  // 120

// Cari maksimum
buat maks_val = lipat(angka, fungsi(acc, x) {
    jika x > acc { kembalikan x }
    kembalikan acc
}, angka[0])
tampilkan("Maksimum:", maks_val)  // 5
Output
Total: 15
Produk: 120
Maksimum: 5

Closure untuk Konfigurasi

Contoh — Builder Pattern
// Buat fungsi logger yang sudah dikonfigurasi
fungsi buat_logger(prefix) {
    kembalikan fungsi(pesan) {
        tampilkan("[" + prefix + "] " + format_waktu(waktu_sekarang()) + " - " + pesan)
    }
}

buat log_info  = buat_logger("INFO")
buat log_error = buat_logger("ERROR")
buat log_db    = buat_logger("DB")

log_info("Server dimulai di port 8080")
log_db("Koneksi SQLite berhasil")
log_error("Gagal memuat konfigurasi")
log_info("Siap menerima request")
Output
[INFO]  22-04-2026 08:00:01 WIB - Server dimulai di port 8080
[DB]    22-04-2026 08:00:01 WIB - Koneksi SQLite berhasil
[ERROR] 22-04-2026 08:00:01 WIB - Gagal memuat konfigurasi
[INFO]  22-04-2026 08:00:01 WIB - Siap menerima request

Rekursi

Contoh — Rekursi
// Faktorial rekursif
fungsi faktorial(n) {
    jika n <= 1 {
        kembalikan 1
    }
    kembalikan n * faktorial(n - 1)
}

tampilkan(faktorial(5))   // 120
tampilkan(faktorial(10))  // 3628800

// Fibonacci rekursif
fungsi fib(n) {
    jika n <= 1 { kembalikan n }
    kembalikan fib(n - 1) + fib(n - 2)
}

buat i = 0
selama i <= 10 {
    tampilkan("fib(" + ke_teks(i) + ") =", fib(i))
    i += 1
}
Output
120
3628800
fib(0) = 0
fib(1) = 1
fib(2) = 1
fib(3) = 2
fib(4) = 3
...
📌 Tips Performa: Untuk rekursi dengan banyak pemanggilan berulang (seperti Fibonacci), gunakan memoization dengan peta untuk menyimpan hasil yang sudah dihitung sebelumnya.