F# adalah bahasa pemrograman functional-first bertipe statis yang berjalan di atas runtime .NET. Topik ini membahas posisi F# di ekosistem .NET, arti functional-first, peran inferensi tipe, kesetaraan struktural, dan situasi yang umumnya sesuai untuk bahasa ini. Di bagian akhir, sebuah skrip kecil dijalankan agar ciri-ciri tersebut dapat diamati pada kode dan keluaran yang nyata.
F# di ekosistem .NET#
Kode F# dikompilasi menjadi IL (Intermediate Language), yaitu instruksi perantara yang digunakan bersama oleh bahasa-bahasa .NET, lalu dijalankan oleh runtime .NET. Karena menumpang pada platform yang sama, program F# dapat menggunakan pustaka kelas .NET (Base Class Library), paket NuGet, dan pustaka yang ditulis dengan C# tanpa lapisan tambahan. Arah sebaliknya juga berlaku karena pustaka F# menghasilkan assembly berformat sama, sehingga proyek C# dapat memanggilnya secara langsung.
Pengembangan F# berlangsung terbuka di repositori dotnet/fsharp dan versi bahasanya menyertai rilis .NET, sehingga F# 10 diperoleh bersama .NET SDK 10 tanpa pemasangan terpisah. Program F# juga lintas platform karena kode yang sama dijalankan pada Linux, Windows, dan macOS di atas runtime .NET masing-masing. Diagram berikut merangkum posisi tersebut.
Arti functional-first#
Functional-first berarti fungsi menjadi unit utama penyusunan logika dan gaya penulisan condong ke ekspresi, bukan pernyataan berurutan. Nilai yang diikat dengan let bersifat imutabel secara bawaan, sehingga data dibangun dengan membuat nilai baru, bukan mengubah nilai lama. Koleksi bawaan seperti list menyediakan fungsi transformasi, contohnya List.filter dan List.map, yang dirangkai dengan operator pipeline |> dari kiri ke kanan.
Istilah ini sering disalahartikan sebagai bahasa murni yang melarang efek samping. F# menempatkan diri di tengah, yaitu gaya fungsional menjadi pilihan bawaan, sedangkan mutable, kelas, dan exception tetap tersedia ketika kebutuhan riil muncul. Potongan berikut memperlihatkan karakter tersebut dalam beberapa baris: list awal tidak diubah, melainkan diturunkan menjadi list baru melalui dua langkah transformasi.
let genapKuadrat =
[ 1 .. 10 ]
|> List.filter (fun n -> n % 2 = 0)
|> List.map (fun n -> n * n)
printfn "%A" genapKuadrat[4; 16; 36; 64; 100]Penentu format %A pada printfn mencetak tampilan umum untuk banyak tipe, termasuk list. Setiap bilangan pada keluaran adalah kuadrat dari bilangan genap 2 sampai 10, mengikuti urutan rantai yang ditulis dari atas ke bawah. Tanpa operator pipeline, rantai yang sama ditulis sebagai panggilan bersarang yang dibaca dari dalam ke luar.
Tipe statis dan inferensi tipe#
F# bertipe statis (statically typed), artinya tipe setiap ekspresi diperiksa saat kompilasi, sebelum program dijalankan. Salah mengetik nama fungsi atau memberikan string kepada operasi bilangan ditolak oleh compiler dengan pesan yang menyebut berkas dan barisnya. Pemeriksaan ini menggeser banyak kesalahan dari waktu berjalan ke waktu kompilasi, tempat perbaikannya lebih murah.
Kode tetap ringkas berkat inferensi tipe (type inference), yaitu kemampuan compiler menyimpulkan tipe dari definisi dan penggunaan tanpa anotasi pada setiap baris. Angka 42 disimpulkan sebagai int, teks yang diapit tanda kutip disimpulkan sebagai string, dan angka desimal disimpulkan sebagai float. Anotasi tipe tetap dapat ditulis, dan lazimnya digunakan pada batas publik sebuah pustaka agar maksudnya terbaca dan hasil penyimpulannya terkendali.
Kesetaraan struktural#
Tipe data gabungan bawaan F#, seperti record dan tuple, dibandingkan berdasarkan isinya. Cara ini disebut kesetaraan struktural (structural equality), yaitu dua nilai dianggap sama apabila seluruh bagian penyusunnya sama, tanpa memandang keduanya dibuat dari ekspresi yang berbeda. Kebiasaan pada banyak bahasa berbasis kelas adalah sebaliknya, yaitu perbandingan menguji referensi objek, sehingga dua objek berisi sama tetap dilaporkan berbeda.
Ciri bahasa dalam satu skrip#
Skrip berikut merangkai inferensi tipe dan kesetaraan struktural yang baru dibahas, ditambah pattern matching yang menjadi cara F# menggerakkan logika atas tipe domain. Skripnya sengaja dibuat pendek agar setiap ciri dapat ditunjuk langsung pada barisnya. Simpan berkasnya sebagai perkenalan.fsx, lalu jalankan dengan perintah dotnet fsi perkenalan.fsx dari folder tempat berkas itu berada.
// Skrip perkenalan: inferensi tipe, kesetaraan struktural, dan pattern matching.
// Inferensi tipe: kompilator menyimpulkan tipe tanpa anotasi.
let bilangan = 42
let nama = "Citra"
let persen = 0.75
printfn "bilangan: %A (int)" bilangan
printfn "nama: %A (string)" nama
printfn "persen: %A (float)" persen
// Kesetaraan struktural: dua record berisi sama dianggap sama.
type Nilai = { MataPelajaran: string; Skor: int }
let nilaiAli = { MataPelajaran = "Matematika"; Skor = 88 }
let nilaiBudi = { MataPelajaran = "Matematika"; Skor = 88 }
printfn "setara: %b" (nilaiAli = nilaiBudi)
// Pattern matching atas discriminated union.
type Predikat = Lulus | Remedial
let predikatDari skor =
match skor with
| s when s >= 75 -> Lulus
| _ -> Remedial
let status skor =
match predikatDari skor with
| Lulus -> "lulus"
| Remedial -> "remedial"
printfn "skor 88: %s" (status 88)
printfn "skor 60: %s" (status 60)bilangan: 42 (int)
nama: "Citra" (string)
persen: 0.75 (float)
setara: true
skor 88: lulus
skor 60: remedialTiga pengenal pertama mendapat tipe tanpa satu anotasi pun, dan keluaran menampilkan kesimpulan tersebut berikut tipenya. Record Nilai memuat dua nilai bernama, dan kesetaraan struktural membuat nilaiAli serta nilaiBudi dianggap sama karena seluruh isinya sama, sehingga keluaran menampilkan setara: true. Pengujian serupa pada bahasa berbasis kelas biasanya memerlukan penimpaan metode kesetaraan, sedangkan di sini cukup operator =.
Baris type Predikat = Lulus | Remedial mendeklarasikan discriminated union, yaitu tipe yang menyatakan nilai hanya boleh berada pada salah satu kasus yang didaftarkan. Ekspresi match menguraikan nilai Predikat menjadi dua cabang, sedangkan klausul when menyaring skor sebelum cabangnya dipilih. Apabila satu kasus terlewat, compiler memberi peringatan, sehingga penambahan kasus baru pada tipe memandu perubahan di seluruh program.
Kapan F# dipilih#
Kecocokan F# dinilai dari karakter pekerjaan yang dilakukan, bukan dari ukuran proyeknya. Kecenderungan berikut diambil dari karakter fitur bahasa yang sudah dibahas, bukan dari tolok ukur kinerja. Tabel berikut merangkum kecenderungan yang umum dijumpai pada praktik .NET.
| Situasi | Pertimbangan |
|---|---|
| Pemodelan domain dengan banyak status dan aturan | Record dan discriminated union memuat bentuk data yang sah, sedangkan pattern matching memaksa semua kasus diperhitungkan. |
| Pengolahan data dan skrip analisis | Pipeline merangkai transformasi berlapis secara linear, dan dotnet fsi memungkinkan eksperimen tanpa kerangka proyek. |
| Interop dengan ekosistem .NET | Pustaka NuGet dan pustaka C# dipanggil langsung, sehingga F# dapat digunakan pada satu bagian layanan tanpa menulis ulang keseluruhan sistem. |
| Kerangka kerja dengan contoh komunitas berbahasa C# | Sisi berorientasi objek F# tetap kompatibel, tetapi sebagian contoh komunitas perlu diadaptasi ketika dipindahkan ke F#. |
Kecenderungan di atas bukan larangan teknis, karena F# dan C# berbagi runtime serta pustaka yang sama. Keduanya dapat hidup berdampingan dalam satu solusi karena hasil kompilasinya saling terhubung tanpa jembatan tambahan. Keputusan yang paling sering menentukan adalah kecocokan gaya bahasa dengan pekerjaannya dan kesinambungan tim yang memeliharanya.
Ringkasan#
- F# adalah bahasa functional-first bertipe statis yang dikompilasi menjadi IL dan dijalankan di atas runtime .NET yang sama dengan C# dan Visual Basic.
- Gaya functional-first menempatkan fungsi, ekspresi, dan nilai imutabel sebagai bawaan, sedangkan kelas, mutable, dan exception tetap tersedia.
- Inferensi tipe mengurangi anotasi, kesetaraan struktural menyederhanakan pengujian data, dan pattern matching menggerakkan logika atas tipe domain.
Referensi#
- Panduan F# — Microsoft Learn — halaman induk dokumentasi resmi F# di .NET.
- Tour of F# — Microsoft Learn
— tur fitur bahasa F#, termasuk
let, tipe record dan union, serta pattern matching. - What’s new in F# 10 — Microsoft Learn — ringkasan perubahan F# 10 yang dirilis bersama .NET 10.
- F# Software Foundation — situs komunitas F# dengan dokumentasi dan tautan alat pendukung.