Sepertinya, ketika membaca sesuatu seperti artikel Wikipedia ini tentang "fungsi murni" , mereka mendaftar Today()
sebagai contoh fungsi tidak murni tetapi tampaknya cukup murni bagi saya. Apakah karena tidak ada argumen input formal? Mengapa waktu aktual hari tidak diperlakukan sebagai "input ke fungsi" dalam hal ini jika Anda memberikan input yang sama, yaitu dieksekusi today()
dua kali pada waktu yang sama, atau melakukan perjalanan kembali pada waktu untuk mengeksekusinya kembali (mungkin hipotetis: )), output akan menjadi waktu yang sama. Today()
tidak pernah memberi Anda nomor acak. selalu memberi Anda waktu sepanjang hari.
Artikel Wikipedia mengatakan "waktu yang berbeda akan menghasilkan hasil yang berbeda" tetapi itu seperti mengatakan untuk yang berbeda x
sin(x)
akan memberikan Anda rasio yang berbeda. Dan sin(x)
merupakan contoh fungsi murni mereka.
sumber
Jawaban:
Itu karena output tergantung pada sesuatu yang bukan input, yaitu waktu saat ini.
Karena Anda tidak meneruskannya sebagai parameter. Jika Anda mengirimkannya sebagai parameter, fungsi tersebut akan menjadi fungsi identitas pada tanggal, yang sangat tidak berguna. Seluruh titik
Today()
fungsi adalah untuk mengeluarkan sesuatu yang bergantung pada nilai eksternal dan waktu yang terus berubah.Keuntungan dari fungsi murni adalah bahwa perilaku mereka benar-benar dapat direproduksi dan deterministik, sehingga mudah untuk memiliki bukti formal dan jaminan keras. Mereka selalu melakukan hal yang sama.
Today()
hampir kebalikannya: selalu (memungkinkan granularitas waktu) melakukan sesuatu yang berbeda.sumber
Today()
)Today()
menjadi tidak murni. TheToday()
fungsi mungkin sedikit contoh konyol. Lebih tepat mungkin beberapaCount()
fungsi. Mengingat jumlah item yang sama untuk dihitungCount()
akan selalu mengembalikan nomor yang sama, tetapi karena itu di luar ruang lingkupCount()
itu tidak murni.count()
pada sebagian besar bahasa pemrograman jelas murni. Ini memiliki nilai input eksplisit: koleksi yang jumlah yang Anda inginkan. Jangan bingung dengan sintaksis sepertimyCollection.count()
; itu hanya gulacount(myCollection)
.sin(x)
akan selalu mengembalikan nilai yang sama, selamax
tetap sama.Today()
dapat mengembalikan hasil yang berbeda dari waktu ke waktu karena itu tergantung pada nilai di luar kendali Anda . Misalnya, jika sesuatu di luar kendali program Anda mengubah internal sistem$current_datetime
saat program Anda berjalan,Today()
tiba-tiba akan menghasilkan hasil yang berbeda.sumber
Today()
akan kembali "Kamis" pada hari Senin.Today () adalah fungsi yang tidak murni karena hasilnya tergantung pada sesuatu yang tidak Anda berikan; khususnya, waktu sistem saat ini. Oleh karena itu, hasilnya tidak deterministik ketika hanya didasarkan pada input yang diberikan saat doa.
Fungsi murni akan menjadi
int Add(int a, int b) {return a + b;}
. Fungsi ini hanya berfungsi dengan apa yang diberikan, dan tidak menggunakan data keadaan eksternal lainnya. Hasil alami dari ini adalah Anda dapatAdd(2,2)
dan mendapatkan 4 dari sekarang hingga akhir waktu. Selain itu, karena fungsi tidak mengubah keadaan eksternal (tidak memiliki "efek samping"), Tambahkan () dari 2 dan 2 dari sekarang sampai akhir waktu tidak akan mengubah hal lain dalam sistem, kecuali jika Anda kemudian tetapkan hasil fungsi ke variabel atau gunakan nilai untuk memperbarui status (yang bukan operasi yang dilakukan oleh fungsi itu sendiri). Hampir semua operasi matematika klasik adalah fungsi murni dan dapat diimplementasikan seperti itu.Today (), di sisi lain, dapat menghasilkan nilai yang sama ketika dipanggil dua kali berturut-turut, tetapi tidak jika dipanggil berulang kali selama beberapa hari. Ini karena itu tergantung pada data keadaan eksternal yang tidak Anda berikan sebagai parameter untuk fungsi tersebut. Akibatnya, tidak mungkin, dalam batas-batas program, untuk mengontrol hasil fungsi Today (). Ini akan menghasilkan nilai yang diberikan pada hari tertentu, dan tidak akan pernah menghasilkan nilai itu pada hari lain, kecuali jika Anda mengubah jam sistem komputer yang menjalankannya (perubahan umumnya terjadi di luar batas-batas program).
Fungsi yang tidak murni tidak selalu merupakan hal yang buruk; fungsi yang tidak murni diperlukan, bahkan dalam bahasa fungsional, untuk berinteraksi dengan apa pun di luar batas program, seperti penyimpanan data, saluran komunikasi, tampilan UI, perangkat periferal, dll. Program yang tidak melakukan hal-hal ini adalah program yang sangat terbatas dalam kegunaannya; Saya bahkan akan menyebut program seperti itu sepele, karena tanpa sarana untuk menerima input atau jalan apa pun untuk memberi tahu Anda tentang hasilnya, mungkin juga tidak melakukan apa-apa. Program yang ditulis dalam bahasa fungsional hanya dapat memiliki input yang disediakan oleh runtime dan menghasilkan output yang dilaporkan ke runtime tanpa ada metode yang tidak murni, tetapi itu karena runtime sedang mengabstraksi semua detail yang tidak murni dari pekerjaan dalam sistem komputer yang tidak sempurna,
Ini hanyalah Hal yang Sangat Baik untuk mengetahui fungsi mana yang Anda gunakan yang murni dan mana yang tidak, sehingga Anda dapat membuat keputusan yang baik tentang bagaimana mereka digunakan. Fungsi yang tidak murni, karena mereka melakukan hal-hal atau bergantung pada hal-hal yang tidak terlihat dari penggunaannya, dapat berperilaku tidak terduga dengan hanya diberi pengetahuan tentang penggunaannya. Pengetahuan lebih lanjut tentang tujuan fungsi, dan dengan demikian apa yang dibutuhkannya dari atau lakukan untuk keadaan eksternal, diperlukan untuk menempatkan suatu sistem yang menggunakannya dalam keadaan konsisten dan dengan demikian mengharapkan hasil deterministik.
sumber
Tampaknya cukup jelas bahwa fungsi ini gagal dalam tes kemurnian pertama yang diberikan pada awal halaman itu:
Perhatikan bahwa karena tidak memerlukan argumen, hanya ada satu set nilai argumen yang mungkin - set kosong. Dan fungsi ini dapat dan tidak mengembalikan hasil yang berbeda untuk 'nilai argumen' yang sama '.
Selanjutnya, fungsi nilai hasil tidak tergantung pada "tersembunyi ... negara yang dapat berubah sebagai hasil eksekusi program". Jadi kegagalan lain.
sumber
() => 1
akan menjadi fungsi murni, karena selalu mengembalikan 1.Today()
dapat mengembalikan "Senin" atau "Selasa" atau hampir semua nilai lainnya.Cara lain untuk memikirkannya adalah fungsi murni tidak bergantung pada negara. Dunia biasanya dianggap sebagai negara. Anda perlu mengetahui keadaan realitas untuk mengetahui hari apa hari ini.
Namun Anda tidak perlu tahu sesuatu yang istimewa tentang keadaan dunia untuk mengetahui apa
sin(x)
itu. Dan panggilansin(x)
untuk diberikanx
akan mengembalikan nilai yang sama.sumber
Date(timestamp)
akan menjadi fungsi murni. Karena idempotensinya. Dan karena tidak akan ada efek samping.Today()
dapat memvariasikan hasilnya tergantung pada kapan Anda memanggilnya. Itulah yang membuatnya tidak murni. Itu bukan idempoten. Meskipun tidak memiliki efek samping, tetapi itu tidak membuatnya murni.sumber
Berikut adalah kode pseudo kecil yang saya pikirkan ketika membahas fungsi murni
Jika itu berjalan tanpa batas waktu dan tidak pernah dapat memicu pernyataan, itu adalah fungsi murni. Lebih dari itu, jika Anda memiliki fungsi yang menggunakan args, maka sedikit modifikasi ....
Jika Anda dapat menggunakannya setelah setiap penugasan variabel di aplikasi Anda, dan itu tidak mengubah hasil dalam aplikasi Anda, dan itu tidak pernah dapat gagal menegaskan, maka itu adalah fungsi murni.
sumber
Pertama, tidak ada yang namanya fungsi tanpa argumen (atau array tanpa indeks atau peta tanpa kunci). Ini adalah karakteristik yang menentukan fungsi untuk memetakan satu atau lebih nilai argumen ke nilai lain.
Karenanya,
today
sama sekali bukan fungsi sama sekali, karenanya tidak ada fungsi murni. Atau kita dapat menginterpretasikan sintakssedikit sehingga artinya
Di Haskell, misalnya, ini akan valid:
karena ada tipe () dengan nilai tunggal ().
Pertanyaannya hanya, bagaimana bisa
today
menghitung hari dalam seminggu, jika hanya memiliki ()? Tidak mungkin tanpa membaca pengatur waktu sistem, secara langsung atau melalui fungsi pembantu yang tidak murni.Timer sistem adalah contoh yang sangat baik untuk keadaan global.
sumber
Masalahnya
today()
adalah ia dapat menghasilkan hasil yang berbeda jika dipanggil dua kali atau lebih dalam suatu fungsi.Berikut adalah contoh kode, yang dapat memperkenalkan bug.
Itu mungkin dalam contoh di atas. Bahwa
if
pernyataan kedua tidak akan dieksekusi. Bahkan jika yang pertama melakukannya. Meninggalkan sumber daya dalam kondisi buruk.sumber
Untuk menjadi fungsi murni, memberikan parameter yang sama harus memberikan hasil yang sama setiap saat.
Setiap kali kami menelepon
Today()
, kami memberikan parameter yang sama (tidak ada), namun belum tentu mendapatkan hasil yang sama (Senin, Selasa, dll.).sumber