it-swarm-id.com

Apa itu "efek samping?"

Saya belum mengerti konsep efek samping.

  • Apa efek samping dalam pemrograman?
  • Apakah ini tergantung pada bahasa pemrograman?
  • Adakah efek samping eksternal dan internal?

Tolong beri beberapa contoh penyebab yang menciptakan efek samping.

101
Amir Rezaei

A efek samping hanya merujuk pada modifikasi beberapa jenis keadaan - misalnya:

  • Mengubah nilai suatu variabel;
  • Menulis beberapa data ke disk;
  • Mengaktifkan atau menonaktifkan tombol di Antarmuka Pengguna.

Bertentangan dengan apa yang beberapa orang katakan:

  • Efek samping tidak tidak harus disembunyikan atau tidak terduga (bisa jadi, tapi itu tidak ada hubungannya dengan definisi yang berlaku untuk ilmu komputer) ;

  • Efek samping tidak memiliki tidak ada 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).

Benar-benar sangat sederhana. Efek samping = mengubah sesuatu di suatu tempat.

P.S. Seperti yang ditunjukkan oleh komentator benjol, beberapa orang mungkin menggabungkan definisi efek samping dengan definisi fungsi murni , yang merupakan fungsi yang (a) idempoten dan (b) tidak memiliki sisi - efek. Satu tidak menyiratkan yang lain dalam ilmu komputer umum, tetapi bahasa pemrograman fungsional biasanya akan cenderung menegakkan kedua kendala.

114
Aaronaught

Setiap operasi yang mengubah keadaan komputer atau yang berinteraksi dengan dunia luar dikatakan memiliki efek samping. Lihat Wikipedia di 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); }
38

Saya pikir jawaban yang ada cukup bagus. Saya ingin menguraikan beberapa aspek yang belum ditekankan oleh IMO.

Dalam matematika, fungsi hanyalah pemetaan dari sejumlah nilai ke nilai. Jadi, diberi fungsi f dan nilai x, f(x) akan selalu menjadi hasil yang sama y. Anda dapat mengganti f(x) dengan y di mana-mana 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:

  1. Ini menghitung fungsi dalam arti matematika, mis. Diberi nilai input, mengembalikan hasil, atau
  2. Ini menghasilkan beberapa efek, mis. mencetak sesuatu ke layar, mengubah nilai pada basis data, meluncurkan rudal, tidur selama 10 detik, mengirim SMS.

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 fungsi sedangkan efek lainnya dianggap efek samping . Beberapa bahasa pemrograman menggunakan istilah procedure untuk menghindari kebingungan dengan fungsi dalam arti matematika.

Catat itu

  1. Beberapa prosedur berguna untuk nilai pengembalian dan efek sampingnya.
  2. Beberapa prosedur hanya menghitung nilai hasil dan tidak memiliki efek lain. Mereka sering disebut fungsi murni karena semua yang mereka lakukan adalah menghitung fungsi dalam arti matematika.
  3. Beberapa prosedur, mis. sleep() dengan Python, hanya berguna untuk efek (sisi) mereka,. Ini sering dimodelkan sebagai fungsi yang mengembalikan nilai khusus None, atau unit atau () atau ..., yang secara sederhana mengindikasikan bahwa perhitungan telah diakhiri dengan benar.
24
Giorgio

Efek samping adalah ketika operasi memiliki efek pada variabel/objek yang berada di luar penggunaan yang dimaksud.

Itu bisa terjadi ketika Anda melakukan panggilan ke fungsi kompleks yang memiliki efek samping mengubah beberapa variabel global, meskipun itu bukan alasan Anda menyebutnya (mungkin Anda menyebutnya 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 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 fungsi dipanggil dua kali berturut-turut, akan muncul kesalahan mengatakan koneksi 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 do_task_x memiliki efek primer untuk mengembalikan hasil beberapa perhitungan, dan --- samping efek kemungkinan memodifikasi variabel global.

Tentu saja, yang adalah yang utama dan yang merupakan efek samping dapat terbuka untuk interpretasi dan mungkin tergantung pada penggunaan aktual. Jika saya memanggil 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.

Dari Wikipedia - Efek Samping

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. Maka 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, artinya 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 yang dimaksudkan secara matematis dari suatu fungsi, maka itu selalu sama.

Dengan demikian, 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 ke parameter fungsi eksplisit, tetapi output dibatasi ke nilai pengembalian 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 suatu fungsi, dan ia melakukan sesuatu yang lain lalu mengembalikan nilai, sulit untuk berpikir tentang perilakunya. Anda harus 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 input apa yang digunakannya tidak membantu seperti memastikannya tidak melakukan hal lain yang mungkin tidak Anda 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 untuk 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" gratis. 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).

3
Didier A.

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.

2
indyK1ng

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.

0
ChaosPandion