Tiszta függvény

Innen: Hungaropédia
A lap korábbi változatát látod, amilyen imported>InternetArchiveBot 2022. október 20., 23:28-kor történt szerkesztése után volt. (1 forrás archiválása és 0 megjelölése halott linkként.) #IABot (v2.0.9.2)
(eltér) ← Régebbi változat | Aktuális változat (eltér) | Újabb változat→ (eltér)
Ugrás a navigációhozUgrás a kereséshez

A számítógépes programozásban a tiszta függvény egy olyan függvény, amely a következő tulajdonságokkal rendelkezik:[1][2]

  1. Visszatérési értéke ugyanaz, ugyanazon argumentum esetén (nincs változás a helyi Statikus változókkal, nem lokális változókkal, mutálható referencia argumentumokkal vagy bemeneti folyamokkal az I/O eszközökből).
  2. Az értékelésnek nincs mellékhatása (a helyi statikus változók, nem lokális változók, mutálható referencia-argumentumok vagy I/O-folyamok nem mutálódnak).

Így egy tiszta függvény egy matematikai függvény számítási analógja. Egyes szerzők, különösen az imperatív nyelvi közösség, a "tiszta" kifejezést használják minden olyan függvényre, amely csak a fenti tulajdonságokkal rendelkezik.[3][4]

Példák

Tiszta függvények

A C++ függvények következő példái tiszták:

  • floor, egy szám egészrészét adja vissza;
  • max, két érték közül a nagyobbik értékét adja vissza;
  • sin, egy szám szinuszával tér vissza.

Tisztátlan függvények

A következő C++ függvények nem tiszták, mivel nem felelnek meg a fenti 1. pontnak:

  • a nem lokális változó visszatérési értékváltozása miatt
int f() {
  return x;
}
  • a visszatérő érték változása miatt, amely mutálható referencia argumentummal rendelkezik
int f(int* x) {
  return *x;
}

A következő C++ függvények nem tiszták, mivel nem felelnek meg a fenti 2. pontnak:

  • a helyi statikus változó mutációja miatt
void f() {
  static int x = 0;
  ++x;
}
  • nem lokális változó mutációja miatt
void f() {
  ++x;
}
  • egy mutálható referencia argumentum mutációja miatt
void f(int* x) {
  ++*x;
}
  • egy kimeneti áramlat mutációja miatt
void f() {
  std::cout << "Hello, world!" << std::endl;
}

A következő C++ függvények nem tiszták, mivel hiányoznak mind a fenti 1, mind a 2 tulajdonságok:

  • a visszatérő értékváltozás miatt a helyi statikus változóval és a helyi statikus változó mutációjával
int f() {
  static int x = 0;
  ++x;
  return x;
}
  • a visszatérési érték változása miatt egy bemeneti árammal és egy bemeneti áram mutációjával
int f() {
  int x = 0;
  std::cin >> x;
  return x;
}

I/O tiszta funkciókban

Az I/O eredetileg tisztázatlan: a bemeneti műveletek aláássák a referencia-átláthatóságot, és a kimeneti műveletek mellékhatásokat hoznak létre. Mindazonáltal van értelme, hogy a függvény képes legyen bemeneti vagy kimeneti feladatok elvégzésére, és még mindig tiszta legyen, ha a vonatkozó I/O-eszközök működésének sorrendje kifejezetten mint argumentum és eredmény, és az I/O műveletekre nem sikerül, ha a bemeneti sorrend nem írja le a program végrehajtása óta ténylegesen végrehajtott műveleteket. A második pont biztosítja, hogy az egyetlen argumentumként használható szekvencia minden I/O műveletnél megváltozzon; az első lehetővé teszi az I/O-teljesítő funkcióhoz tartozó különböző hívások különböző eredményeinek visszaadását a megváltozott szekvencia argumentumok miatt.[5][6] Az I/O monád egy olyan programozási idióma, amelyet tipikusan az I/O végrehajtására használnak tiszta funkcionális nyelveken.

Fordító optimalizálások

Azok a funkciók, amelyek csak a fenti 2. pontnak felelnek meg, lehetővé tesznek fordítóoptimalizálási technikákat, mint például az aritmetikai operátorokhoz hasonló közös alexpressziós eltávolítás és hurok optimalizálás.[3] Egy C++ példa a length metódus, amely a karakterlánc nagyságát adja vissza, amely memória tartalmától függ amelyre a karakterláncra mutat, ezért nem felel meg a fenti 1. pontnak. Mindazonáltal egyszálú környezetben az alábbi C++ kód

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];
}

optimalizálható úgy, hogy az s.length() értékét csak egyszer, a hurok előtt számoljuk ki.

Fortran-ban a pure kulcsszó használható arra, hogy egy függvényt csak mellékhatássá nyilvánítson (azaz csak a fenti tulajdonság 2). A C ++ -ban a constexpr kulcsszó használható arra, hogy egy függvényt a fenti 1-es és 2-es tulajdonságokkal constexpr (azaz tisztán legyen ebben a cikkben használt értelemben); az ilyen funkciók a többszálas környezetben is közös alexpressziós eltávolítási és hurok optimalizálásnak vannak kitéve.

Lásd még

  1. Bartosz Milewski: Basics of Haskell. School of Haskell. FP Complete, 2013 [2016. október 27-i dátummal az eredetiből archiválva]. (Hozzáférés: 2018. július 13.) „Here are the fundamental properties of a pure function: 1. A function returns exactly the same result every time it's called with the same set of arguments. In other words a function has no state, nor can it access any external state. Every time you call it, it behaves like a newborn baby with blank memory and no knowledge of the external world. 2. A function has no side effects. Calling a function once is the same as calling it twice and discarding the result of the first call.”
  2. Brian Lonsdorf: Professor Frisby's Mostly Adequate Guide to Functional Programming. GitBook, 2015 [2019. július 6-i dátummal az eredetiből archiválva]. (Hozzáférés: 2018. július 14.) „A pure function is a function that, given the same input, will always return the same output and does not have any observable side effect.”
  3. 3,0 3,1 GCC 8.1 Manual. GCC, the GNU Compiler Collection. Free Software Foundation, Inc., 2018 (Hozzáférés: 2018. június 28.)
  4. Fortran 95 language features#Pure Procedures
  5. Peyton Jones, Simon L.. Haskell 98 Language and Libraries: The Revised Report [archivált változat]. Cambridge, United Kingdom: Cambridge University Press, 95. o. (2003. április 26.). ISBN 0-521 826144. Hozzáférés ideje: 2014. július 17. [archiválás ideje: 2021. május 6.] 
  6. Hanus: Curry: An Integrated Functional Logic Language. http://www-ps.informatik.uni-kiel.de/currywiki/. Institut für Informatik, Christian-Albrechts-Universität zu Kiel. [2014. július 25-i dátummal az eredetiből archiválva]. (Hozzáférés: 2014. július 17.)

További információk