Topik ini membahas cara menulis fungsi pada Julia, mulai dari definisi ringkas satu baris dan blok function, operator yang berupa fungsi biasa, argumen kata kunci, hingga anotasi tipe pada argumen. Fungsi anonim dan do-block turut dibahas sebagai cara ringkas untuk fungsi sekali pakai. Setelah membacanya, fungsi utilitas sederhana dapat ditulis dalam dua gaya definisi, dan batasan tipenya dapat dinyatakan dengan tepat.
Dua bentuk definisi fungsi#
Bentuk ringkas menuliskan seluruh isi fungsi dalam satu baris setelah tanda sama dengan, sedangkan bentuk blok menggunakan kata kunci function yang ditutup end. Nilai kembali (return value) sebuah fungsi adalah nilai dari ekspresi terakhirnya, dan kata kunci return mengakhiri fungsi lebih cepat apabila diperlukan.
gandakan(x) = x * 2
function perkenalan(nama, umur)
println("Perkenalkan, ", nama, "!")
println("Umur: ", umur)
end
println(gandakan(21))
perkenalan("Citra", 19)42
Perkenalkan, Citra!
Umur: 19Fungsi gandakan mengembalikan nilai x * 2, sehingga hasilnya ditampilkan oleh println(). Fungsi perkenalan menampilkan dua baris teks dan pemanggilannya dituliskan tanpa pembungkus println() tambahan. Kedua bentuk definisi setara dari sisi perilaku, sehingga pilihannya menyesuaikan panjang isi fungsi. Isi yang panjang atau bercabang lebih nyaman ditulis dalam blok function, sedangkan rumus pendek cocok dengan bentuk ringkas.
Kata kunci return penting ketika fungsi perlu keluar lebih awal. Ekspresi yang ditulis setelah return tidak dieksekusi lagi, sehingga pola ini lazim untuk memilih nilai kembali berdasarkan syarat tertentu.
Operator adalah fungsi biasa#
Sebagian besar operator pada Julia adalah fungsi biasa, dan bentuk infix seperti 2 + 3 hanyalah cara penulisan yang lebih nyaman daripada +(2, 3). Karena itu, operator dapat dirujuk tanpa operand, diteruskan sebagai argumen ke fungsi lain, dan diikat ke nama baru.
println(+(2, 3))
println(>(5, 4))
kali = *
println(kali(6, 7))5
true
42Pemanggilan >(5, 4) sama dengan 5 > 4 dan menghasilkan true. Pengikatan kali = * menyalin rujukan fungsi perkalian ke nama baru, sehingga kali(6, 7) menghitung 42. Sifat ini membuat operator dapat dilewatkan ke fungsi tingkat tinggi seperti map(), yang dicontohkan pada bagian fungsi anonim.
Argumen kata kunci#
Argumen kata kunci (keyword argument) dideklarasikan setelah titik koma pada definisi fungsi dan dapat diberi nilai bawaan (default). Pemanggilannya menyebut nama argumennya, sehingga makna setiap nilai terbaca langsung dari baris pemanggilan.
function nilai_akhir(tugas, ujian; bobot_tugas = 0.4)
return tugas * bobot_tugas + ujian * (1 - bobot_tugas)
end
println(nilai_akhir(80, 90))
println(nilai_akhir(80, 90; bobot_tugas = 0.5))
println(nilai_akhir(80, 90, bobot_tugas = 0.5))
try
println(nilai_akhir(80, 90, 0.5))
catch err
println(typeof(err))
end86.0
85.0
85.0
MethodErrorPemanggilan pertama menggunakan nilai bawaan bobot 0,4, sehingga bobot ujian otomatis menjadi 0,6 dan hasilnya 86.0. Pemanggilan kedua dan ketiga menunjukkan dua gaya penulisan yang setara, yaitu dengan titik koma eksplisit atau dengan koma biasa setelah argumen posisional. Pemanggilan keempat menyerahkan 0.5 sebagai argumen posisional ketiga, dan fungsi yang hanya menerima dua argumen posisional menolaknya dengan MethodError.
Sebagai contoh utuh, berkas berikut mendefinisikan konverter suhu dengan satu argumen kata kunci untuk mengatur pembulatan.
# Konverter suhu dengan argumen kata kunci
function celsius_ke_fahrenheit(c; dua_desimal = true)
f = c * 9 / 5 + 32
if dua_desimal
return round(f, digits = 2)
end
return f
end
println(celsius_ke_fahrenheit(25.7; dua_desimal = false))
println(celsius_ke_fahrenheit(37; dua_desimal = false))
println(celsius_ke_fahrenheit(37))78.25999999999999
98.6
98.6Pemanggilan tanpa pembulatan memperlihatkan jejak presisi biner Float64 pada nilai 78.25999999999999, sedangkan pembulatan dua desimal menghasilkan 98.6. Pernyataan if pada definisi hanya memilih nilai kembali dan dibahas lengkap pada topik alur kendali.
Anotasi tipe pada argumen#
Anotasi tipe (type annotation) ditulis dengan :: diikuti nama tipe pada argumen fungsi. Sifatnya selektif, yaitu membatasi argumen yang diterima tanpa melakukan konversi. Pemanggilan dengan argumen yang bertipe cocok dijalankan, sedangkan argumen di luar tipe tersebut memicu MethodError.
function luas_segitiga(alas::Real, tinggi::Real)
return alas * tinggi / 2
end
println(luas_segitiga(6, 4))
println(luas_segitiga(2.5, 4))
try
println(luas_segitiga("enam", 4))
catch err
println(typeof(err))
end12.0
5.0
MethodErrorTipe abstrak Real mencakup Int64 dan Float64, sehingga kedua pemanggilan pertama berjalan tanpa konversi apa pun. String "enam" bukan Real, sehingga pemanggilan ketiganya ditolak. Anotasi juga tidak mengonversi nilai yang hampir cocok, sebagaimana diperlihatkan pada contoh berikut.
function ambil_bulat(n::Int64)
return n
end
println(ambil_bulat(7))
try
println(ambil_bulat(7.5))
catch err
println(typeof(err))
end7
MethodErrorNilai 7.5 bertipe Float64 dan tidak dikonversi menjadi Int64 secara diam-diam. Apabila pembulatannya memang dikehendaki, panggil round(Int64, 7.5) secara eksplisit. Perlu dicatat bahwa anotasi pada satu definisi hanya menyaring masukan fungsi tersebut, sedangkan pemilihan metode berdasarkan tipe seluruh argumen, yaitu multiple dispatch, dibahas pada topik tentang tipe dan dispatch.
Fungsi anonim dan do-block#
Fungsi yang hanya digunakan sekali dapat ditulis tanpa nama menggunakan panah ->. Bentuk ini disebut fungsi anonim (anonymous function) dan sering diteruskan langsung sebagai argumen ke fungsi lain.
kuadrat = x -> x^2
println(kuadrat(9))
println(map(x -> x^2, 1:5))81
[1, 4, 9, 16, 25]Pengikatan kuadrat = x -> x^2 memberi nama pada fungsi anonim, sedangkan pemanggilan map() menerapkannya ke setiap elemen rentang 1:5. Bentuk panah paling cocok untuk fungsi pendek yang rumusnya muat dalam satu baris.
Do-block menyediakan fungsi anonim multi-baris untuk argumen pertama sebuah pemanggilan fungsi. Pola ini lazim untuk sumber daya yang harus ditutup, seperti berkas, karena fungsi penerimanya menjamin penutupan.
mktempdir() do folder
jalur = joinpath(folder, "catatan.txt")
open(jalur, "w") do io
print(io, "catatan hari pertama")
end
println(read(jalur, String))
endcatatan hari pertamaFungsi mktempdir() membuat direktori sementara, meneruskannya ke blok sebagai folder, lalu menghapus direktori tersebut setelah blok selesai dijalankan. Dengan demikian, tidak ada berkas sementara yang tertinggal. Pemanggilan open() menggunakan do-block juga memastikan berkas ditutup secara otomatis, termasuk ketika terjadi kesalahan di dalam blok. Kedua mekanisme ini menjadikan pola do pilihan yang tepat untuk mengelola berkas dan sumber daya lainnya.
Kesalahan umum#
Kesalahan pertama adalah mengira fungsi otomatis mencetak hasilnya. Pada skrip, nilai kembali gandakan(21) tidak tampil di mana pun kecuali diteruskan ke println() atau ditampung dalam variabel. Pemanggilan yang hasilnya tidak digunakan biasanya menjadi tanda ada langkah yang terlewat.
Kesalahan kedua adalah menyerahkan argumen kata kunci seolah-olah argumen posisional. Fungsi nilai_akhir menolak pemanggilan dengan tiga argumen posisional melalui MethodError, dan perbaikannya adalah menyebut nama argumen kata kunci secara eksplisit.
Kesalahan ketiga adalah memilih anotasi tipe yang terlalu sempit. Anotasi n::Int64 menolak nilai 7.5 alih-alih mengonversinya, sehingga fungsi yang memang ditujukan untuk beragam bilangan riil lebih baik menerima Real. Anotasi yang sesuai dengan maksud penggunaan membuat pesan error yang muncul lebih mudah ditafsirkan.
Kesalahan keempat adalah memanggil fungsi sebelum definisinya dijalankan. Skrip Julia dieksekusi baris demi baris dari atas, sehingga definisi harus mendahului pemanggilan pertamanya. Pesan UndefVarError pada nama fungsi hampir selalu berasal dari urutan ini.
Ringkasan#
- Fungsi ditulis dalam bentuk ringkas
f(x) = ...atau blokfunction ... end, dengan nilai kembali berupa nilai ekspresi terakhir ataureturn. - Operator adalah fungsi biasa, sehingga dapat dirujuk tanpa operand, diteruskan sebagai argumen, dan diikat ke nama lain.
- Argumen kata kunci ditulis setelah titik koma, dapat bernilai bawaan, dan memisahkan opsi dari data posisional tanpa menjadi dasar pemilihan metode.
- Anotasi
::Tmembatasi tipe argumen tanpa melakukan konversi, sedangkan fungsi anonim dan do-block meringkas fungsi sekali pakai beserta pembersihan sumber dayanya.
Referensi#
- Functions — The Julia Language — Bentuk definisi fungsi, argumen kata kunci, fungsi anonim, dan do-block.
- Methods — The Julia Language — Definisi metode beserta hubungannya dengan anotasi tipe argumen.