Saya belum mengerti konsep efek samping.
- Apa efek samping dalam pemrograman?
- Apakah tergantung pada bahasa pemrograman?
- Adakah efek samping eksternal dan internal?
Tolong beri beberapa contoh penyebab yang menciptakan efek samping.
Saya belum mengerti konsep efek samping.
Tolong beri beberapa contoh penyebab yang menciptakan efek samping.
Jawaban:
Sebuah efek samping mengacu hanya untuk modifikasi semacam negara - misalnya:
Bertentangan dengan apa yang dikatakan beberapa orang:
Efek samping yang tidak harus disembunyikan atau tak terduga (itu bisa, tapi itu tidak ada hubungannya dengan definisi yang berlaku untuk ilmu komputer);
Efek samping tidak ada hubungannya dengan idempotensi. Fungsi idempoten dapat memiliki efek samping, dan fungsi non-idempoten mungkin tidak memiliki efek samping (seperti mendapatkan tanggal dan waktu sistem saat ini).
Ini sangat sederhana. Efek samping = mengubah sesuatu di suatu tempat.
PS Seperti yang ditunjukkan komentator benjol, beberapa orang mungkin menggabungkan definisi efek samping dengan definisi fungsi murni , yang merupakan fungsi yang (a) idempoten dan (b) tidak memiliki efek samping. Satu tidak menyiratkan yang lain dalam ilmu komputer umum, tetapi bahasa pemrograman fungsional biasanya akan cenderung menegakkan kedua kendala.
++a
.. Tidak terlihat seperti tugas. b = ++a;
memiliki dua efek samping. Yang jelas dan tugas crypto a
. Itulah jenis efek samping yang diinginkan (bagi sebagian orang). Tetapi telah disebut efek samping untuk seluruh karier saya agar tidak halus.
Setiap operasi yang mengubah keadaan komputer atau yang berinteraksi dengan dunia luar dikatakan memiliki efek samping. Lihat Wikipedia tentang Efek Samping .
Misalnya, fungsi ini tidak memiliki efek samping. Hasilnya hanya bergantung pada argumen inputnya, dan tidak ada apa pun tentang keadaan program atau lingkungannya yang berubah ketika dipanggil:
int square(int x) { return x * x; }
Sebaliknya, memanggil fungsi-fungsi ini akan memberi Anda hasil yang berbeda tergantung pada urutan Anda memanggilnya, karena mereka mengubah sesuatu tentang keadaan komputer:
int n = 0;
int next_n() { return n++; }
void set_n(int newN) { n = newN; }
Fungsi ini memiliki efek samping dari penulisan data ke keluaran. Anda tidak memanggil fungsi karena Anda ingin nilai pengembaliannya; Anda menyebutnya karena Anda menginginkan efeknya terhadap "dunia luar":
int Write(const char* s) { return printf("Output: %s\n", s); }
Write
contoh Anda menunjukkan, memiliki efek samping tidak menyiratkan bahwa fungsi tersebut pernah mengubah outputnya sehubungan dengan inputnya, atau bahkan bahwa outputnya tergantung pada input sama sekali.
square(x)
dapat menyebabkan modul di mana fungsi didefinisikan untuk diambil dari disk. Haruskah ini dianggap efek samping? Lagi pula, ini mensyaratkan bahwa panggilan (pertama) memakan waktu lama secara tak terduga, bahwa penggunaan RAM naik, dll.
square(x)
karena Anda ingin keadaan komputer eksternal itu berubah, Anda dapat menganggap itu sebagai efek samping.
Saya pikir jawaban yang ada cukup bagus. Saya ingin menguraikan beberapa aspek bahwa IMO belum cukup ditekankan.
Dalam matematika, fungsi hanyalah pemetaan dari sejumlah nilai ke nilai. Jadi, diberi fungsi f
dan nilai x
, f(x)
akan selalu hasil yang sama y
. Anda dapat mengganti f(x)
dengan y
di mana saja dalam ekspresi dan tidak ada yang akan berubah.
Apa yang disebut fungsi (atau prosedur) dalam banyak bahasa pemrograman adalah konstruksi (potongan kode) yang dapat dieksekusi karena:
Jadi efek dapat dikaitkan dengan keadaan tetapi juga dengan aspek lain seperti menembakkan rudal atau menjeda eksekusi selama beberapa detik.
Istilah efek samping mungkin terdengar negatif tetapi biasanya efek memanggil fungsi adalah tujuan utama dari fungsi itu sendiri. Saya mengira bahwa, karena istilah fungsi awalnya digunakan dalam Matematika, menghitung nilai dianggap sebagai efek utama dari suatu fungsi sedangkan efek lainnya dianggap efek samping . Beberapa bahasa pemrograman menggunakan istilah prosedur untuk menghindari kebingungan dengan fungsi dalam arti matematika.
Catat itu
sleep()
dengan Python, hanya berguna untuk efek (sisi) mereka,. Ini sering dimodelkan sebagai fungsi yang mengembalikan nilai khusus None
, unit
atau ()
atau ..., yang hanya menunjukkan bahwa perhitungan telah diakhiri dengan benar.Efek samping adalah ketika operasi memiliki efek pada variabel / objek yang berada di luar penggunaan yang dimaksud.
Itu bisa terjadi ketika Anda membuat panggilan ke fungsi kompleks yang memiliki efek samping mengubah beberapa variabel global, meskipun itu bukan alasan Anda menyebutnya (mungkin Anda memanggilnya untuk mengekstrak sesuatu dari database).
Saya akui saya mengalami masalah dengan contoh sederhana yang tidak terlihat dibuat-buat, dan contoh dari hal-hal yang telah saya kerjakan terlalu lama untuk dikirim di sini (dan karena ini terkait dengan pekerjaan, saya mungkin tidak seharusnya demikian. ).
Salah satu contoh yang pernah saya lihat (beberapa waktu lalu) adalah fungsi yang membuka koneksi database jika koneksi dalam keadaan tertutup. Masalahnya adalah bahwa itu seharusnya menutup koneksi di akhir fungsi, tetapi pengembang lupa untuk menambahkan kode itu. Jadi di sini, ada efek samping yang tidak diinginkan : memanggil prosedur seharusnya hanya melakukan kueri dan efek sampingnya adalah koneksi tetap terbuka dan jika fungsinya dipanggil dua kali berturut-turut, akan muncul kesalahan mengatakan koneksi itu sudah terbuka.
Ok, jadi karena semua orang memberikan contoh sekarang, saya pikir saya juga akan;)
/*code is PL/SQL-styled pseudo-code because that's what's on my mind right now*/
g_some_global int := 0; --define a globally accessible variable somewhere.
function do_task_x(in_a in number) is
begin
b := calculate_magic(in_a);
if b mod 2 == 0 then
g_some_global := g_some_global + b;
end if;
return (b * 2.3);
end;
Fungsi ini do_task_x
memiliki efek utama mengembalikan hasil beberapa perhitungan, dan efek samping dari kemungkinan memodifikasi variabel global.
Tentu saja, mana yang utama dan mana efek sampingnya bisa terbuka untuk interpretasi dan mungkin tergantung pada penggunaan aktual. Jika saya menyebut fungsi ini untuk tujuan memodifikasi global dan saya membuang nilai yang dikembalikan daripada saya akan mengatakan bahwa memodifikasi global adalah efek utama.
Dalam ilmu komputer, suatu fungsi atau ekspresi dikatakan memiliki efek samping jika ia memodifikasi beberapa keadaan atau memiliki interaksi yang dapat diamati dengan fungsi panggilan atau dunia luar.
Fungsi, dalam pengertian matematika, adalah pemetaan dari input ke output. Efek yang dimaksudkan dari memanggil suatu fungsi adalah memetakan input ke output yang dikembalikan. Jika fungsi melakukan hal lain, itu tidak masalah apa, tetapi jika ia memiliki perilaku yang tidak memetakan input ke output, perilaku itu dikenal sebagai efek samping.
Dalam istilah yang lebih umum, efek samping adalah efek yang bukan merupakan efek yang dimaksudkan oleh perancang konstruksi.
Efek adalah segala sesuatu yang memengaruhi seorang aktor. Jika saya memanggil fungsi yang mengirimkan pesan teks perpisahan kepada pacar saya, yang memengaruhi banyak aktor, saya, dia, jaringan perusahaan telepon seluler, dll. Satu-satunya efek yang dimaksudkan untuk memanggil fungsi bebas efek samping, adalah untuk fungsi tersebut untuk mengembalikan saya pemetaan dari input saya. Jadi untuk:
public void SendBreakupTextMessage() {
Messaging.send("I'm breaking up with you!")
}
Jika ini dimaksudkan sebagai fungsi, maka satu-satunya hal yang harus dilakukan adalah mengembalikan batal. Jika efek sampingnya gratis, seharusnya tidak benar-benar mengirim pesan teks.
Dalam sebagian besar bahasa pemrograman, tidak ada konstruksi untuk fungsi matematika. Tidak ada konstruksi yang dimaksudkan untuk digunakan. Itu sebabnya sebagian besar bahasa mengatakan Anda memiliki metode atau prosedur. Secara desain, itu dimaksudkan untuk dapat melakukan lebih banyak efek. Dalam bahasa pemrograman yang umum, tidak ada yang benar-benar peduli tentang maksud dari apa metode atau prosedur itu, jadi ketika seseorang mengatakan fungsi ini memiliki efek samping, maksudnya secara efektif, konstruk ini tidak berperilaku seperti fungsi matematika. Dan ketika seseorang mengatakan fungsi ini bebas efek samping, maksudnya, konstruk ini secara efektif berperilaku seperti fungsi matematika.
Fungsi murni selalu efek samping gratis, menurut definisi. Fungsi murni, adalah cara untuk mengatakan, fungsi ini, meskipun menggunakan konstruk yang memungkinkan lebih banyak efek, hanya memiliki efek yang sama dengan fungsi matematika.
Saya menantang siapa pun untuk memberi tahu saya ketika fungsi bebas efek samping tidak akan murni. Kecuali efek yang dimaksudkan utama dari konteks kalimat menggunakan istilah murni dan efek samping bebas bukanlah efek matematika yang dimaksudkan dari suatu fungsi, maka mereka selalu sama.
Karena itu, kadang-kadang, meskipun lebih jarang, dan saya percaya ini adalah perbedaan yang kurang dan juga menyesatkan orang (karena itu bukan asumsi yang paling umum) dalam jawaban yang diterima, tetapi kadang-kadang diasumsikan bahwa efek yang dimaksudkan dari fungsi pemrograman adalah untuk memetakan input ke output, di mana input tidak dibatasi pada parameter fungsi yang eksplisit, tetapi output dibatasi pada nilai balik eksplisit. Jika Anda menganggap itu adalah efek yang dimaksudkan, maka fungsi membaca file dan mengembalikan hasil berbeda berdasarkan apa yang ada dalam file tersebut masih bebas efek samping, karena Anda mengizinkan input datang dari tempat lain dalam efek yang Anda maksudkan.
Jadi, mengapa ini semua penting?
Ini semua tentang kontrol dan menjaganya. Jika Anda memanggil fungsi, dan ia melakukan sesuatu yang lain lalu mengembalikan nilai, sulit untuk beralasan tentang perilakunya. Anda perlu melihat ke dalam fungsi untuk kode aktual untuk menebak apa yang dilakukannya dan menegaskan kebenarannya. Situasi yang ideal adalah sangat jelas dan mudah untuk mengetahui apa input yang digunakan fungsi dan tidak melakukan hal lain kemudian mengembalikan output untuk itu. Anda dapat sedikit merilekskan hal ini, dan mengatakan bahwa mengetahui persis apa input yang digunakannya tidak membantu seperti memastikan itu tidak melakukan hal lain yang Anda mungkin tidak sadari kemudian mengembalikan nilai, jadi mungkin Anda puas dengan hanya menegakkan bahwa itu tidak melakukan apa pun selain memetakan input, tidak peduli dari mana mendapatkannya, ke output.
Dalam hampir semua kasus, tujuan program adalah untuk memiliki efek selain memetakan hal-hal yang masuk ke hal-hal yang keluar. Gagasan mengendalikan efek samping adalah Anda dapat mengatur kode dengan cara yang lebih mudah dipahami dan dipikirkan. Jika Anda menempatkan semua efek samping bersama-sama, di tempat yang sangat eksplisit dan sentral, mudah untuk mengetahui ke mana harus mencari dan percaya bahwa ini semua yang terjadi, tidak lebih. Jika Anda memiliki input yang sangat eksplisit juga, ini membantu menguji perilaku untuk input yang berbeda, dan lebih mudah digunakan, karena Anda tidak perlu mengubah input di banyak tempat yang berbeda, beberapa yang mungkin tidak jelas, hanya saja untuk mendapatkan apa yang Anda inginkan.
Karena yang paling membantu untuk memahami, menalar dan mengendalikan perilaku suatu program adalah membuat semua input dikelompokkan secara jelas dan eksplisit, serta semua efek samping dikelompokkan bersama dan secara eksplisit, inilah yang biasanya dibicarakan orang ketika mereka mengatakan efek samping, murni, dll.
Karena yang paling membantu adalah pengelompokan efek samping dan kesaksian mereka, kadang-kadang orang hanya akan memaksudkan itu, dan membedakannya dengan mengatakan itu tidak murni, tetapi masih "efek samping" bebas. Tetapi efek sampingnya relatif terhadap asumsi "efek utama yang dituju", jadi itu adalah istilah kontekstual. Ini saya temukan kurang sering digunakan, meskipun secara mengejutkan ini banyak dibicarakan di utas ini.
Akhirnya, idempoten berarti memanggil fungsi ini berkali-kali dengan input yang sama (tidak masalah dari mana asalnya) akan selalu menghasilkan efek yang sama (efek samping atau tidak).
Dalam pemrograman efek samping adalah ketika suatu prosedur mengubah variabel dari luar ruang lingkupnya. Efek samping tidak tergantung pada bahasa. Ada beberapa kelas bahasa yang bertujuan untuk menghilangkan efek samping (bahasa fungsional murni), tetapi saya tidak yakin apakah ada yang memerlukan efek samping, tetapi saya bisa saja salah.
Sejauh yang saya tahu, tidak ada efek samping internal dan eksternal.
Ini adalah contoh sederhana:
int _totalWrites;
void Write(string message)
{
// Invoking this function has the side effect of
// incrementing the value of _totalWrites.
_totalWrites++;
Debug.Write(message);
}
Definisi efek samping tidak spesifik untuk pemrograman, jadi bayangkan saja efek samping obat-obatan Anda atau makan terlalu banyak makanan.
x++
memodifikasi variabel x
biasanya dianggap sebagai efek samping. Nilai ekspresi itu adalah nilai pra-kenaikan x
; ini adalah bagian efek non-sisi dari ekspresi.
Efek samping adalah hal-hal yang terjadi dalam kode yang tidak jelas terlihat.
Misalnya katakanlah Anda memiliki kelas ini
public class ContrivedRandomGenerator {
public int Seed { get; set; }
public int GetRandomValue()
{
Random(Seed);
Seed++;
}
}
Saat Anda awalnya membuat kelas, Anda memberinya seed.
var randomGenerator = new ContrivedRandomGenerator();
randomGenerator.Seed = 15;
randomGenerator.GetRandomValue();
Anda tidak tahu internal, Anda hanya berharap untuk mendapatkan nilai acak, dan Anda akan mengharapkan generalGenerator. Memang masih 15 ... tapi tidak.
Panggilan fungsi memiliki efek samping mengubah nilai Seed.