Tiszta függvény
|
Ez a szócikk vagy szakasz lektorálásra, tartalmi javításokra szorul. |
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]
- 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).
- 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
[szerkesztés]Tiszta függvények
[szerkesztés]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
[szerkesztés]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
[szerkesztés]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
[szerkesztés]
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
[szerkesztés]- A fordítási időfüggvény végrehajtása : a tiszta funkciók értékelése a fordítási időben
- Tisztán funkcionális adatszerkezet
- Referencia-átláthatóság (informatika)
- Lambda kalkulus
- Mellékhatás (informatika)
- Tiszta eljárás
- Idempotencia
- tiszta kulcsszó a Fortranban a tiszta függvények megjegyzésével
- constexpr kulcsszó a C ++ jelzésben a fordítási idő alatt használható tiszta függvényekben
- ↑ 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.”
- ↑ 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.”
- ↑ a b GCC 8.1 Manual. GCC, the GNU Compiler Collection. Free Software Foundation, Inc., 2018 (Hozzáférés: 2018. június 28.)
- ↑ Fortran 95 language features#Pure Procedures
- ↑ 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. szeptember 11.). ISBN 0-521 826144. Hozzáférés ideje: 2014. július 17. [archiválás ideje: 2021. május 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.)