Tapi itu akan segera berubah. Semakin banyak konsep FP diintegrasikan ke dalam bahasa seperti Java dan Python . Dan bahasa yang lebih modern seperti Haskell berfungsi penuh. Untuk menempatkan pemrograman fungsional dalam istilah sederhana
, maka ini adalah pembuatan fungsi untuk bekerja dengan variabel yang tidak dapat diubah. Sebaliknya, pemrograman berorientasi objek adalah ketika sekumpulan fungsi yang relatif konstan digunakan, dan programmer terutama sibuk memodifikasi variabel yang ada dan membuat yang baru.
FP, pada dasarnya, cocok untuk memecahkan masalah mendesak, seperti analisis data dan pembelajaran mesin . Ini tidak berarti bahwa Anda perlu mengucapkan selamat tinggal pada pemrograman berorientasi objek dan sepenuhnya beralih ke pemrograman fungsional. Sangat berguna bagi programmer modern untuk mengetahui prinsip-prinsip dasar FP, yang akan memungkinkannya untuk menerapkan prinsip-prinsip ini di tempat yang dapat mereka layani dengan baik.
Pemrograman fungsional adalah tentang menghilangkan efek samping
Untuk memahami prinsip-prinsip pemrograman fungsional, pertama-tama Anda perlu memahami apa itu "fungsi". Ini mungkin tampak membosankan, tetapi pada akhirnya, ini akan memungkinkan Anda untuk melihat apa yang sekilas tidak terlihat. Jadi mari kita bicara tentang fungsi.
Sebuah fungsi, dalam istilah sederhana, adalah entitas yang mengubah beberapa input yang diteruskan ke data output yang dikembalikan ke tempat panggilan. Benar, pada kenyataannya, semuanya tidak selalu terlihat sederhana. Lihatlah fungsi Python berikut:
def square(x):
return x*x
Fungsi ini sangat sederhana. Dibutuhkan satu argumen,
xyang mungkin dari tipe int, dan mungkin dari tipe floatatau double, dan mengembalikan hasil dari xkuadrat itu.
Dan inilah fungsi lainnya:
global_list = []
def append_to_list(x):
global_list.append(x)
Pada pandangan pertama, tampaknya ia menerima
xbeberapa jenis dan tidak mengembalikan apa-apa, karena tidak ada ekspresi di dalamnya return. Tapi jangan langsung mengambil kesimpulan!
Fungsi tersebut tidak akan bisa bekerja secara normal jika variabel tidak dideklarasikan sebelumnya
global_list. Hasil dari fungsi ini adalah daftar modifikasi yang disimpan di global_list. Meskipun global_listtidak dideklarasikan sebagai nilai yang diteruskan ke input suatu fungsi, variabel ini berubah setelah fungsi dipanggil.
append_to_list(1)
append_to_list(2)
global_list
Setelah beberapa panggilan ke fungsi dari contoh sebelumnya, tidak
global_listakan ada lagi daftar kosong, tetapi daftar [1,2]. Ini memungkinkan kita untuk mengatakan bahwa list, pada kenyataannya, adalah nilai yang diberikan ke input fungsi, meskipun ini tidak diperbaiki dengan cara apa pun saat fungsi tersebut dideklarasikan. Ini bisa jadi masalah.
Ketidakjujuran saat mendeklarasikan fungsi
Nilai input atau output implisit ini memiliki nama resmi: efek samping. Kami menggunakan contoh yang sangat sederhana di sini, tetapi dalam program yang lebih kompleks, efek samping dapat menyebabkan komplikasi yang nyata .
Pikirkan tentang bagaimana Anda akan menguji fungsi tersebut
append_to_list. Tidaklah cukup untuk membaca baris pertama deklarasinya, dan mencari tahu bahwa itu perlu diuji dengan memberikan beberapa nilai x. Sebagai gantinya, Anda perlu membaca seluruh kode fungsi, mencari tahu apa yang sebenarnya terjadi di sana, mendeklarasikan variabel global_list, dan kemudian menguji fungsinya. Apa dalam contoh sederhana kami, tampaknya, tidak menimbulkan kesulitan khusus, dalam program yang terdiri dari ribuan baris kode, itu akan terlihat sangat berbeda.
Untungnya, masalah di atas mudah diperbaiki. Anda hanya perlu jujur saat menentukan apa sebenarnya yang harus dimasukkan ke input fungsi. Versi selanjutnya dari fungsi kami terlihat jauh lebih baik dari yang sebelumnya:
newlist = []
def append_to_list2(x, some_list):
some_list.append(x)
append_to_list2(1,newlist)
append_to_list2(2,newlist)
newlist
Kami tidak banyak berubah dalam kode ini. Akibatnya, fungsi dalam
newlist, seperti sebelumnya global_list, ternyata [1,2], dan segala sesuatu yang lain terlihat sama seperti sebelumnya.
Namun, kami membuat satu perubahan signifikan pada kode ini. Kami menyingkirkan efek sampingnya. Dan ini sangat bagus.
Yaitu, sekarang, setelah membaca baris pertama dari deklarasi fungsi, kita tahu persis dengan input data apa yang bekerja dengannya. Akibatnya, jika program tidak berperilaku seperti yang diharapkan, mudah untuk menguji setiap fungsi yang dikandungnya dan menemukan yang tidak berfungsi dengan baik. Fungsi murni lebih mudah dirawat.
Pemrograman fungsional menulis fungsi murni
Sebuah fungsi yang, ketika dideklarasikan, dengan jelas menunjukkan apa yang dibutuhkan dan apa yang dikembalikannya adalah fungsi tanpa efek samping. Fungsi tanpa efek samping adalah fungsi murni.
Berikut adalah definisi pemrograman fungsional yang sangat sederhana. Ini adalah program penulisan yang hanya terdiri dari fungsi murni. Fungsi murni tidak pernah mengubah data yang diteruskan kepadanya, mereka hanya membuat yang baru dan mengembalikannya. (Perhatikan bahwa saya menyontek sedikit di contoh sebelumnya. Ini ditulis dalam semangat pemrograman fungsional, tetapi di dalamnya fungsi memodifikasi daftar variabel global. Tetapi di sini kita hanya memeriksa prinsip-prinsip dasar FP, itulah sebabnya saya melakukan hal itu. Jika Anda mau, di sini Anda bisa temukan contoh yang lebih ketat dari fungsi murni.)
Lebih lanjut, saat bekerja dengan fungsi murni, Anda dapat mengharapkan bahwa mereka, menerima data yang sama sebagai masukan, akan selalu menghasilkan keluaran yang sama. Dan fungsi yang tidak murni mungkin bergantung pada beberapa jenis variabel global. Akibatnya, mereka menerima masukan yang sama, dapat menghasilkan hasil yang berbeda, tergantung pada nilai variabel global. Fakta ini dapat memperumit proses debug dan pemeliharaan kode secara signifikan.
Ada aturan praktis sederhana untuk mendeteksi efek samping. Karena ketika mendeklarasikan fungsi murni, harus didefinisikan dengan jelas apa yang mereka terima sebagai masukan dan pengembalian, fungsi yang tidak menerima atau mengembalikan apa pun tidak akan bersih. Jika Anda memutuskan untuk memasukkan teknik pemrograman fungsional ke dalam proyek Anda, hal pertama yang ingin Anda lakukan mungkin adalah memeriksa deklarasi fungsi Anda.
Apa pemrograman fungsional bukan
▍Memetakan dan mengurangi fungsi
Loop adalah mekanisme yang tidak berhubungan dengan pemrograman fungsional. Lihatlah loop Python berikut:
integers = [1,2,3,4,5,6]
odd_ints = []
squared_odds = []
total = 0
for i in integers:
if i%2 ==1
odd_ints.append(i)
for i in odd_ints:
squared_odds.append(i*i)
for i in squared_odds:
total += i
Dengan bantuan kode ini, kami menyelesaikan masalah sederhana, tetapi ternyata cukup lama. Dan itu, terlebih lagi, tidak berfungsi, karena variabel global dimodifikasi di sini.
Dan sekarang - versi lain dari kode ini:
from functools import reduce
integers = [1,2,3,4,5,6]
odd_ints = filter(lambda n: n % 2 == 1, integers)
squared_odds = map(lambda n: n * n, odd_ints)
total = reduce(lambda acc, n: acc + n, squared_odds)
Ini adalah kode yang berfungsi penuh. Lebih pendek. Ini lebih cepat karena Anda tidak perlu melakukan iterasi pada banyak elemen array. Dan, jika Anda memahami fungsinya
filter, mapdan reduce, ternyata kode ini tidak jauh lebih sulit untuk dipahami daripada yang digunakan loop.
Ini tidak berarti bahwa dalam kode fungsi apa pun digunakan
map, reducedan fungsi lain semacam itu. Dan ini tidak berarti bahwa untuk menangani fungsi-fungsi seperti itu, Anda perlu mengetahui pemrograman fungsional. Intinya adalah bahwa fungsi ini sering digunakan saat menghilangkan loop.
▍Fungsi Lambda
Ketika orang berbicara tentang sejarah pemrograman fungsional, mereka sering memulai dengan berbicara tentang penemuan fungsi lambda. Namun, meskipun fungsi lambda tidak diragukan lagi merupakan landasan pemrograman fungsional, fungsi lambda bukanlah penyebab utama FP.
Fungsi Lambda adalah alat yang dapat digunakan untuk menulis program dalam gaya fungsional. Tetapi fungsi-fungsi ini juga dapat digunakan dalam pemrograman berorientasi objek.
▍ Pengetikan statis
Contoh di atas tidak diketik secara statis. Tapi tetap saja itu adalah contoh kode fungsional.
Meskipun pengetikan statis menambahkan lapisan keamanan ekstra ke kode Anda, itu bukan persyaratan untuk membuat kode fungsional. Namun, ini bisa menjadi tambahan yang bagus untuk gaya pemrograman fungsional.
Perlu dicatat bahwa beberapa bahasa lebih mudah diprogram dalam gaya fungsional daripada yang lain.
Beberapa bahasa "lebih fungsional" dari yang lain
▍Perl
Perl memiliki pendekatan untuk menangani efek samping yang membedakannya dari kebanyakan bahasa lain. Yakni, ia memiliki "variabel ajaib"
$_yang membawa efek samping ke tingkat salah satu fitur utama bahasa tersebut. Perl memiliki kelebihannya, tetapi saya tidak akan mencoba melakukan pemrograman fungsional dalam bahasa ini.
▍Java
Saya harap Anda beruntung menulis kode Java fungsional. Itu tidak akan menyakitimu. Pertama, kata kunci akan mengambil setengah dari kode
static. Kedua, kebanyakan programmer Java akan menyebut kode Anda sebagai kesalahpahaman.
Ini tidak berarti bahwa Java adalah bahasa yang buruk. Tetapi itu tidak dirancang untuk memecahkan jenis masalah yang cocok untuk pemrograman fungsional. Misalnya - untuk manajemen database atau untuk mengembangkan aplikasi dari bidang pembelajaran mesin.
▍Scala
Scala adalah bahasa yang menarik. Tujuannya adalah untuk menyatukan pemrograman fungsional dan berorientasi objek. Jika ini tampak aneh bagi Anda, ketahuilah bahwa Anda tidak sendiri. Bagaimanapun, pemrograman fungsional ditujukan untuk sepenuhnya menghilangkan efek samping. Dan pemrograman berorientasi objek adalah tentang membatasi efek samping pada objek.
Dengan pemikiran ini, kami dapat mengatakan bahwa banyak pengembang melihat Scala sebagai bahasa yang akan membantu mereka berpindah dari pemrograman berorientasi objek ke pemrograman fungsional. Menggunakan Scala dapat mempermudah mereka untuk bertransisi ke gaya pemrograman yang berfungsi penuh di masa mendatang.
▍Python
Gaya pemrograman fungsional didorong dengan Python. Ini dapat dipahami jika kita memperhitungkan fakta bahwa setiap fungsi, secara default, memiliki setidaknya satu parameter -
self. Ini, dalam banyak hal, dalam semangat " Zen Python ": "Eksplisit lebih baik daripada implisit."
▍Clojure
Clojure, menurut pencipta bahasa itu, sekitar 80% berfungsi. Semua nilai tidak dapat diubah secara default. Tapi inilah yang dibutuhkan untuk menulis kode fungsional. Namun, Anda bisa menyiasatinya dengan menggunakan kontainer yang bisa berubah, di mana nilai yang tidak bisa diubah ditempatkan. Dan jika Anda mengekstrak nilai dari penampung, nilai tersebut menjadi tidak dapat diubah lagi.
▍Haskell
Ini adalah salah satu dari sedikit bahasa yang berfungsi penuh dan diketik secara statis. Meskipun menggunakannya dalam proses pengembangan mungkin tampak membutuhkan waktu terlalu lama untuk mengimplementasikan mekanisme fungsional, upaya semacam itu akan membuahkan hasil berkali-kali selama proses debug kode. Bahasa ini tidak mudah dipelajari seperti yang lain, tetapi mempelajarinya jelas merupakan investasi yang berharga.
Hasil
Perlu dicatat bahwa sekarang ini masih awal dari era data besar. Data besar datang, dan tidak sendirian tetapi dengan teman - dengan pemrograman fungsional.
Pemrograman fungsional, jika dibandingkan dengan pemrograman berorientasi objek, masih merupakan fenomena khusus. Namun, jika kita menganggap integrasi prinsip FP dalam Python dan bahasa lain sebagai fenomena yang signifikan, maka kita dapat menyimpulkan bahwa pemrograman fungsional semakin populer.
Dan ini masuk akal, karena pemrograman fungsional menunjukkan dirinya sendiri dengan baik dalam bekerja dengan database, dalam pemrograman paralel, di bidang pembelajaran mesin. Dan dalam dekade terakhir, semua ini terus meningkat.
Meskipun kode berorientasi objek memiliki manfaat yang tak terhitung jumlahnya, kode fungsional tidak boleh diabaikan. Jika seorang programmer mempelajari beberapa prinsip dasar FP, maka ini, dalam banyak kasus, mungkin cukup untuk meningkatkan level profesionalnya. Pengetahuan ini juga akan membantunya mempersiapkan "masa depan fungsional".
Bagaimana perasaan Anda tentang pemrograman fungsional?
