it-swarm.asia

"Yan etki" nedir?

Yan etki kavramını net bir şekilde anlamadım.

  • Programlamada yan etki nedir?
  • Programlama dili bağımlı mı?
  • Dış ve iç yan etkiler gibi bir şey var mı?

Lütfen yan etkiler oluşturan nedenlere bazı örnekler verin.

101
Amir Rezaei

Bir yan etki basitçe bir tür durumun değiştirilmesini ifade eder - örneğin:

  • Bir değişkenin değerini değiştirme;
  • Bazı verileri diske yazma;
  • Kullanıcı Arayüzündeki bir düğmeyi etkinleştirme veya devre dışı bırakma.

Bazı insanların söylediklerinin aksine :

  • Bir yan etki gizli veya beklenmedik olmak zorunda değildir (olabilir, ancak bunun bilgisayar bilimi için geçerli olduğu için tanımla ilgisi yoktur) ;

  • Bir yan etkinin idempotency ile ilgisi yoktur . Bir idempotent fonksiyonun yan etkileri olabilir ve idempotent olmayan bir fonksiyonun herhangi bir yan etkisi olmayabilir (geçerli sistem tarihini ve saatini almak gibi).

Gerçekten çok basit. Yan etki = bir yerde bir şeyleri değiştirmek.

Not; Yorum yapan benjol'ün işaret ettiği gibi, birkaç kişi bir yan etki tanımını saf fonksiyon ile sınırlandırıyor olabilir, bu (a) idempotent ve (b) ) hiçbir yan etkisi yoktur. Biri genel bilgisayar biliminde diğerini ima etmez, ancak işlevsel programlama dilleri tipik olarak her iki kısıtlamayı da uygulama eğilimindedir.

114
Aaronaught

Bilgisayarın durumunu değiştiren veya dış dünya ile etkileşime giren herhangi bir işlemin yan etkisi olduğu söylenir. Bkz. Wikipedia ( Yan Etkisi .

Örneğin, bu işlevin yan etkisi yoktur. Bunun sonucu yalnızca girdi argümanlarına bağlıdır ve programın durumu veya ortamı hakkında hiçbir şey çağrıldığında değişmez:

int square(int x) { return x * x; }

Buna karşılık, bu işlevleri çağırmak, onları arama sırasına bağlı olarak size farklı sonuçlar verecektir, çünkü bilgisayarın durumu hakkında bir şey değiştirirler:

int n = 0;
int next_n() { return n++; }
void set_n(int newN) { n = newN; }      

Bu fonksiyonun çıktıya veri yazmanın yan etkisi vardır. İşlevi çağırmazsınız çünkü dönüş değerini istiyorsunuz; "dış dünya" üzerindeki etkisini istediğiniz için diyorsunuz:

int Write(const char* s) { return printf("Output: %s\n", s); }
38

Mevcut cevapların oldukça iyi olduğunu düşünüyorum. IMO'nun yeterince vurgulanmadığı bazı yönleri ele almak istiyorum.

Matematikte bir işlev sadece bir değer dizisinden bir değere eşleme anlamına gelir. Bu nedenle, f işlevi ve x değeri verildiğinde, f(x) her zaman aynı sonuç olacaktır y. f(x) ifadesini, ifadenin her yerinde y ile değiştirebilirsiniz; hiçbir şey değişmez.

Birçok programlama dilinde işlev (veya yordam) olarak adlandırılan, yürütülebilecek bir yapıdır (kod parçası):

  1. Matematiksel anlamda bir işlevi hesaplar, yani girdi değerleri verildiğinde bir sonuç döndürür veya
  2. Bazı efektler üretir, örn. ekrana bir şeyler yazdırır, veritabanındaki bir değeri değiştirir, füzeleri başlatır, 10 saniye uyur, SMS gönderir.

Bu yüzden etkiler devletle ilgili olabilir, aynı zamanda bir füze ateşlemek veya birkaç saniye boyunca infazı duraklatmak gibi diğer yönlerle de ilgili olabilir.

Yan etki terimi kulağa olumsuz gelebilir, ancak normalde bir işlevi çağırmanın etkisi işlevin kendisinin amacıdır. Sanırım, işlev terimi başlangıçta Matematik'te kullanıldığından, bir değerin hesaplanmasının bir işlevin birincil etki olarak kabul edilirken, diğer etkilerin dikkate alındığı yan etkiler . Bazı programlama dilleri, matematiksel anlamda işlevlerle karışıklığı önlemek için prosedür terimini kullanır.

Bunu not et

  1. Bazı prosedürler hem geri dönüş değerleri hem de yan etkileri için faydalıdır.
  2. Bazı prosedürler yalnızca bir sonuç değerini hesaplar ve başka bir etkisi yoktur. Çoğunlukla saf fonksiyonlar olarak adlandırılırlar çünkü yaptıkları tek şey matematiksel anlamda bir fonksiyon hesaplamaktır.
  3. Bazı prosedürler, ör. Python'daki sleep(), yalnızca (yan) etkileri için yararlıdır,. Bunlar genellikle özel bir değer None veya unit veya () Veya ... döndüren işlevler olarak modellenir; bu da hesaplamanın doğru bir şekilde sonlandığını gösterir.
24
Giorgio

Bir yan etki, bir işlemin amaçlanan kullanım dışındaki bir değişken/nesne üzerinde bir etkisinin olmasıdır.

Bazı global değişkenleri değiştirmenin bir yan etkisi olan karmaşık bir işleve bir çağrı yaptığınızda, aradığınız neden olmasa da (belki bir veritabanından bir şey ayıklamak için çağırdınız) olabilir.

Tamamen tutarlı görünmeyen basit bir örnek bulmakta sorun yaşadığımı itiraf ediyorum ve üzerinde çalıştığım şeylerden örnekler burada yayınlamak için çok uzun (ve işle ilgili olduğu için muhtemelen yine de yapmamalıyım) ).

Gördüğüm bir örnek (bir süre önce), bağlantı kapalı durumdaysa veritabanı bağlantısı açan bir işlevdi. Sorun, işlevin sonunda bağlantıyı kapatması gerekiyordu, ancak geliştirici bu kodu eklemeyi unuttu. Yani burada istenmeyen bir yan etki vardı: bir prosedürü çağırmanın sadece bir sorgu yapması gerekiyordu ve yan etki bağlantının açık kalması ve eğer işlev arka arkaya iki kez çağrıldı, bağlantının zaten açık olduğunu belirten bir hata oluştu.


Tamam, şimdi herkes örnek verdiğinden, ben de yapacağım;)

/*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;

İşlev do_task_x, bazı hesaplamaların sonucunu döndürmek için birincil etkisi ve genel olarak bir değişkeni değiştirmek için yan etkisine sahiptir.

Tabii ki, hangisi birincildir ve hangisi yan etki yorumlamaya açık olabilir ve gerçek kullanıma bağlı olabilir. Bu işlevi genel olarak değiştirmek amacıyla çağırırsam ve döndürülen değeri genel olarak değiştirmenin birincil etki olduğunu söylediğimden atarsam.

Bilgisayar biliminde, bir fonksiyonun veya ifadenin, bir durumu değiştirirse veya çağrı fonksiyonları veya dış dünya ile gözlemlenebilir bir etkileşimi varsa, bir yan etkiye sahip olduğu söylenir.

Gönderen Wikipedia - Yan Etki

Matematiksel anlamda bir işlev, girdiden çıktıya bir eşlemedir. Bir işlevi çağırmanın amaçlanan etkisi, girdiyi döndürdüğü çıkışla eşlemesidir. İşlev başka bir şey yaparsa, ne olduğu önemli değildir, ancak girdiyi çıktıya eşlemeyen bir davranış varsa, bu davranışın bir yan etki olduğu bilinir.

Daha genel anlamda, bir yan etki, yapı tasarımcının amaçlanan etkisi olmayan herhangi bir etkidir.

Etki, bir aktörü etkileyen her şeydir. Kız arkadaşımın bir parça metin mesajı gönderen bir işlevi çağırırsam, bir grup aktörü, ben, onu, cep telefonu şirketinin ağını vb. Etkiler. Yan etkisiz bir işlevi çağırmanın tek amacı etki içindir. girdimden bir eşleme döndürmek için. İçin böylece:

   public void SendBreakupTextMessage() {
        Messaging.send("I'm breaking up with you!")
   }

Bunun bir işlev olması amaçlanıyorsa, yapması gereken tek şey geri dönüşüdür. Yan etki içermiyorsa, kısa mesaj göndermemelidir.

Çoğu programlama dilinde, matematiksel bir fonksiyon için bir yapı yoktur. Hiçbir yapının bu şekilde kullanılması amaçlanmamıştır. Bu yüzden çoğu dil yöntem veya prosedürleriniz olduğunu söylüyor. Tasarım gereği, bunların çok daha fazla etki yapabilmesi amaçlanmıştır. Ortak programlama görüşünde, hiç kimse gerçekten bir yöntemin veya prosedürün ne olduğunu umursamaz, , bu yüzden birisi bu fonksiyonun yan etkisi olduğunu söylediğinde, etkili bir şekilde, bu yapı davranmaz matematik işlevi gibi. Birisi bu fonksiyonun yan etkisiz olduğunu söylediğinde, bu yapı etkili bir şekilde matematiksel bir fonksiyon gibi davranır.

Saf bir fonksiyon, tanım gereği her zaman yan etkisizdir. Saf bir işlev, daha fazla etkiye izin veren bir yapı kullansa da, bu fonksiyonun sadece matematiksel bir işleve eşit bir yapıya sahip olduğunu söylemenin bir yoludur.

Yan etkisi olmayan bir fonksiyonun ne zaman saf olmayacağını söylemesi için herkese meydan okuyorum. Saf ve yan etki serbest terimini kullanarak cümlenin bağlamının birincil amaçlanan etkisi, bir fonksiyonun matematiksel amaçlanan etkisi ile aynı değilse, her zaman eşittir.

Bu nedenle, bazen, daha nadiren olsa da ve bunun kabul edilen cevapta insanları eksik ve aynı zamanda yanlış yönlendiren (en yaygın varsayım olmadığı için) olduğuna inanıyorum, ancak bazen bir programlama fonksiyonunun amaçlanan etkisinin girdiyi çıktı ile eşleştirmek için, burada girdi işlevin açık parametreleriyle sınırlı değildir, çıktı ise açık dönüş değeriyle sınırlıdır. Amaçlanan etki olduğunu varsayarsanız, bir dosyayı okuyan ve dosyadakilere bağlı olarak farklı bir sonuç döndüren bir işlev, girdilerin amaçlanan efektinizdeki diğer yerlerden gelmesine izin verdiğiniz için hala yan etki içermez.

Peki, neden hepsi önemli?

Her şey kontrol ve tutmakla ilgilidir. Bir işlevi çağırırsanız ve başka bir şey yapar ve sonra bir değer döndürürse, davranışı hakkında mantık bulmak zordur. Gerçek kodun ne yaptığını tahmin etmek ve doğruluğunu iddia etmek için işlevin içine bakmanız gerekir. İdeal durum, fonksiyonun kullandığı girdinin ne olduğunu bilmenin çok açık ve kolay olması ve bunun için bir çıktı döndürerek başka bir şey yapmamasıdır. Bunu biraz rahatlatabilir ve tam olarak hangi girdiyi kullandığını bilmek, başka bir şey yapmadığından emin olmanın o kadar yararlı olmadığını söyleyebilir, sonra bir değer döndürdüğünüzden emin olabilirsiniz, bu yüzden belki sadece zorlamadan memnunsunuzdur. harita girdisinden başka bir şey yapmıyorsa, nereden alırsa alınsın çıktıya.

Hemen hemen tüm durumlarda, bir programın amacı ortaya çıkan şeyleri haritalamaktan başka etkilere sahip olmaktır. Yan etkiyi kontrol etme fikri, kodu daha kolay anlaşılabilecek ve gerekçelendirilebilecek şekilde düzenleyebilmenizdir. Tüm yan etkiyi bir araya getirirseniz, çok açık ve merkezi bir yerde, nerede olup bittiğine bakmak ve güvenmek bilmek kolaydır, daha fazla değil. Girişiniz de çok açıksa, farklı giriş için davranışın test edilmesine yardımcı olur ve kullanımı daha kolaydır, çünkü girişi çok farklı yerlerde değiştirmeniz gerekmez, bazıları belli olmayabilir, sadece istediğini elde etmek için.

Bir programın davranışını anlamak, akıl yürütmek ve kontrol etmek için en yararlı olan, tüm girdilerin açıkça birlikte ve açık bir şekilde gruplandırılması ve tüm yan etkilerin birlikte gruplanması ve açık olması olduğundan, genellikle insanların söyledikleri şeyden bahseder. yan etki, saf, vb.

En faydalı olan yan etkilerin gruplanması ve açık olmaları olduğundan, bazen insanlar sadece bunu ifade edecek ve saf değil, ama yine de "yan etki" özgür olduğunu söyleyerek ayırt edecektir. Ancak yan etki, varsayılan "amaçlanan birincil etki" ile ilgilidir, dolayısıyla bağlamsal bir terimdir. Bulduğum bu daha az kullanılır, ancak şaşırtıcı bir şekilde bu konuda çok konuşulur.

Son olarak, idempotent, bu işlevi birçok kez aynı girişlerle çağırmak anlamına gelir (nereden geldikleri önemli değildir) her zaman aynı etkilere neden olur (yan etki veya değil).

3
Didier A.

Programlamada bir yan etki, bir prosedürün bir değişkeni kapsamının dışından değiştirmesidir. Yan etkiler dile bağlı değildir. Yan etkileri (saf fonksiyonel diller) ortadan kaldırmayı amaçlayan bazı dil sınıfları vardır, ancak yan etkiler gerektiren herhangi bir şey olup olmadığından emin değilim, ama yanlış olabilirim.

Bildiğim kadarıyla, iç ve dış yan etkileri yoktur.

2
indyK1ng

İşte basit bir örnek:

int _totalWrites;
void Write(string message)
{
    // Invoking this function has the side effect of 
    // incrementing the value of _totalWrites.
    _totalWrites++;
    Debug.Write(message);
}

Yan etkinin tanımı programlamaya özgü değildir, bu yüzden ilaçlarınızın yan etkilerini veya çok fazla yemek yiyin.

0
ChaosPandion