Saf fonksiyon - Pure function

Gelen bilgisayar programlama , bir saf fonksiyon bir olduğunu fonksiyonu aşağıdaki özelliklere sahiptir:

  1. İşlev dönüş değerleri , özdeş bağımsız değişkenler için aynıdır (yerel statik değişkenler , yerel olmayan değişkenler , değiştirilebilir başvuru bağımsız değişkenleri veya giriş akışları ile değişiklik yok ).
  2. İşlev uygulamasının hiçbir yan etkisi yoktur (yerel statik değişkenlerin mutasyonu, yerel olmayan değişkenler, değiştirilebilir referans argümanları veya giriş/çıkış akışları).

Böylece saf bir fonksiyon, matematiksel bir fonksiyonun hesaplamalı bir analogudur . Bazı yazarlar, özellikle zorunlu dil topluluğundan, "saf" terimini, yalnızca yukarıdaki 2 özelliğine sahip olan tüm işlevler için kullanır ( aşağıda tartışılmıştır ).

Örnekler

Saf fonksiyonlar

Aşağıdaki C++ işlevleri örnekleri saftır:

  • floor, bir sayının tabanını döndürmek ;
  • max, maksimum iki değer döndürülür.
  • f fonksiyonu olarak tanımlanır
    void f() {
      static std::atomic<unsigned int> x = 0;
      ++x;
    }
    
    Bu kod örneği saf değil gibi görünse de aslında öyle. Değeri xsadece diğer çağrıları içine görülebilir f()ve aynı f()değerini iletişim kurmaz xçevresine, bu işlevinden farksızdır void f() {}hiçbir şey yapmaz. Not xolan std::atomicyürütme birden çok iş parçacığı bir değişiklik, bu yüzden f()aynı zamanda bir sonuçlanmayan veri ırk sahiptir, tanımsız davranış C ve C ++.

saf olmayan fonksiyonlar

Aşağıdaki C++ işlevleri, yukarıdaki özellik 1'den yoksun oldukları için saf değildir:

  • statik bir değişkenle dönüş değeri değişimi nedeniyle
    int f() {
      static int x = 0;
      ++x;
      return x;
    }
    
  • yerel olmayan bir değişkenle dönüş değeri değişimi nedeniyle
    int f() {
      return x;
    }
    
    Aynı nedenle, örneğin C++ kitaplığı işlevi sin()saf değildir, çünkü sonucu çalışma zamanında değiştirilebilen IEEE yuvarlama moduna bağlıdır .
  • değiştirilebilir bir referans argümanı ile dönüş değeri değişimi nedeniyle
    int f(int* x) {
      return *x;
    }
    
  • bir giriş akışı ile dönüş değeri değişimi nedeniyle
    int f() {
      int x = 0;
      std::cin >> x;
      return x;
    }
    

Aşağıdaki C++ işlevleri, yukarıdaki özellik 2'den yoksun oldukları için saf değildir:

  • yerel bir statik değişkenin mutasyonu nedeniyle
    void f() {
      static int x = 0;
      ++x;
    }
    
  • yerel olmayan bir değişkenin mutasyonu nedeniyle
    void f() {
      ++x;
    }
    
  • değişken bir referans argümanının mutasyonu nedeniyle
    void f(int* x) {
      ++*x;
    }
    
  • bir çıkış akımının mutasyonu nedeniyle
    void f() {
      std::cout << "Hello, world!" << std::endl;
    }
    

Aşağıdaki C++ işlevleri, yukarıdaki özellikler 1 ve 2'nin her ikisinden de yoksun oldukları için saf değildir:

  • yerel bir statik değişken ile dönüş değeri değişimi ve yerel bir statik değişkenin mutasyonu nedeniyle
    int f() {
      static int x = 0;
      ++x;
      return x;
    }
    
  • bir giriş akışındaki dönüş değeri değişimi ve bir giriş akışının mutasyonu nedeniyle
    int f() {
      int x = 0;
      std::cin >> x;
      return x;
    }
    

Saf fonksiyonlarda I/O

G/Ç doğası gereği saf değildir: girdi işlemleri bilgi şeffaflığını baltalar ve çıktı işlemleri yan etkiler yaratır. Bununla birlikte, ilgili G/Ç aygıtlarındaki işlemlerin sırası hem bir argüman hem de bir sonuç olarak açıkça modellenirse ve G/Ç işlemleri, giriş veya çıkış gerçekleştirebilir ve yine de saf olabilir. giriş dizisi, program yürütmeye başladığından beri gerçekleştirilen işlemleri gerçekten açıklamadığında başarısız olur.

İkinci nokta, bağımsız değişken olarak kullanılabilen tek sıranın her G/Ç eylemiyle değişmesini sağlar; ilki, değişen dizi argümanları nedeniyle farklı sonuçlar döndürmek için bir G/Ç gerçekleştirme işlevine yapılan farklı çağrılara izin verir.

I / O atom a, programlama deyim tipik olarak saf fonksiyonel dilde I / O gerçekleştirmek için kullanılır.

Derleyici optimizasyonları

Sadece yukarıdaki 2 özelliğine sahip fonksiyonlar, aritmetik operatörlere benzer ortak alt ifade eliminasyonu ve döngü optimizasyonu gibi derleyici optimizasyon tekniklerine izin verir . Bir C++ örneği, lengthdizenin işaret ettiği bellek içeriğine bağlı olan, dolayısıyla yukarıdaki özellik 1'den yoksun bir dize boyutunu döndüren yöntemdir. Bununla birlikte, tek iş parçacıklı bir ortamda aşağıdaki C++ kodu

std::string s = "Hello, world!";
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int l = 0;

for (int i = 0; i < 10; ++i) {
  l += s.length() + a[i];
}

değeri s.length()döngüden önce yalnızca bir kez hesaplanacak şekilde optimize edilebilir .

Bazı programlama dilleri, bir işleve saf bir özellik bildirmeye izin verir:

  • Gelen Fortran ve D, pureanahtar (yani, yukarıdaki özelliği var 2) sadece yan etkisi serbest olduğu bir işlev bildirmek için kullanılabilir. Derleyici, bildirimin üstünde özellik 1'i çıkarabilir.
  • In GCC , puresüre niteliği belirtir mülkiyet 2, constniteliği her iki özelliklere sahip gerçekten saf işlevi belirtir.
  • Derleme zamanı işlev yürütmesi sunan diller , bazen başka kısıtlamaların eklenmesiyle işlevlerin saf olmasını gerektirebilir. Örnekler arasında constexprC++ (her iki özellik) bulunur.

Birim testi

Saf işlevlerin aynı argümanlar için aynı dönüş değerleri olduğundan , bunlar birim testine çok uygundur .

Ayrıca bakınız

Referanslar