Funkcionális programozás

Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2022. február 2-án felülvizsgált verziótól ; az ellenőrzések 2 szerkesztést igényelnek .

A funkcionális programozás  egy olyan programozási paradigma , amelyben a számítási folyamat a függvények értékeinek kiszámítása az utóbbi matematikai megértésében (szemben a függvényekkel , mint szubrutinokkal a procedurális programozásban ).

Szemben az imperatív programozás paradigmájával , amely a számítási folyamatot az állapotok egymást követő változásaként írja le ( az automata elméletéhez hasonló értelemben ). Ha szükséges, a funkcionális programozásban a számítási folyamat szekvenciális állapotainak teljes halmazát explicit módon ábrázoljuk, például lista formájában .

A funkcionális programozás a függvények eredményeinek a bemeneti adatokból és más függvények eredményeiből történő kiszámításáról szól, és nem jelenti a program állapotának explicit tárolását. Ennek megfelelően ez sem jelenti ennek az állapotnak a változékonyságát (ellentétben az imperatívusszal , ahol az egyik alapfogalom egy olyan változó , amely tárolja az értékét, és lehetővé teszi az algoritmus végrehajtása során annak megváltoztatását ).

A gyakorlatban az a különbség a matematikai függvény és a „függvény” fogalma között az imperatív programozásban, hogy az imperatív függvények nemcsak argumentumokra, hanem a függvényen kívüli változók állapotára is támaszkodhatnak, emellett mellékhatásokkal és változással is járhatnak. a külső változók állapota. Így az imperatív programozás során ugyanazon függvény azonos paraméterekkel, de az algoritmus végrehajtásának különböző szakaszaiban történő meghívásakor a változó állapot függvényre gyakorolt ​​hatása miatt eltérő kimeneti adatokat kaphatunk. Funkcionális nyelvben pedig egy függvény ugyanazon argumentumokkal történő meghívásakor mindig ugyanazt az eredményt kapjuk: a kimenet csak a bemenettől függ. Ez lehetővé teszi, hogy a funkcionális nyelvi futtatókörnyezetek gyorsítótárba helyezzék a függvények eredményeit, és az algoritmus által nem meghatározott sorrendben meghívják őket, és párhuzamosítsák azokat anélkül, hogy a programozó részéről további munkavégzésre kerülne sor (ami mellékhatások nélküli funkciókat biztosít – tiszta függvények ) .

A lambda kalkulus a funkcionális programozás alapja, számos funkcionális nyelv „kiegészítőnek” tekinthető [1] .

Funkcionális programozási nyelvek

A leghíresebb funkcionális programozási nyelvek :

A Lisp és az APL még nem teljesen működőképes kezdeti verziói külön hozzájárultak a funkcionális programozás létrehozásához és fejlesztéséhez. A Lisp későbbi verziói, mint például a Scheme , valamint az APL különféle változatai támogatták a funkcionális nyelv összes jellemzőjét és koncepcióját [3] .

A funkcionális programozási nyelvek, különösen a tisztán funkcionális nyelvek iránti érdeklődés általában inkább tudományos, mint kereskedelmi. Azonban olyan nevezetes nyelvek, mint az Erlang , OCaml , Haskell , Scheme (1986 után), valamint a specifikus R (statisztika), Wolfram (szimbolikus matematika), J és K (pénzügyi elemzés) és XSLT ( XML ) megtalálták a magukét. utat a kereskedelmi programozási iparba. A széles körben elterjedt deklaratív nyelvek, mint például az SQL és a Lex / Yacc , tartalmazzák a funkcionális programozás egyes elemeit, például nem használnak változókat. A táblázatkezelő nyelvek funkcionálisnak is tekinthetők, mivel a táblázatcellák egy sor olyan funkciót tartalmaznak, amelyek általában csak más celláktól függenek, és ha változókat akarunk modellezni, akkor egy kötelező makrónyelv képességeit kell igénybe venni.

Történelem

A lambda-számítás a függvények leírásának és kiszámításának elméleti alapja lett. Mivel matematikai absztrakció , nem programnyelv , ma szinte minden funkcionális programozási nyelv alapját képezi. Egy hasonló elméleti koncepció, a kombinatorikus logika , elvontabb, mint a λ-számítás, és korábban jött létre. Ezt a logikát használják néhány ezoterikus nyelvben , például az Unlambdában . Mind a λ-számítást, mind a kombinatorikus logikát a matematika elveinek és alapjainak egyértelműbb és pontosabb leírására fejlesztették ki [4] .

Az első funkcionális nyelv a Lisp volt , amelyet John McCarthy hozott létre az ötvenes évek végén az MIT -nél, és kezdetben az IBM 700 /7000-hez [5] valósították meg . Lisp volt az első, aki számos funkcionális nyelvi fogalmat vezetett be, bár a nyelv nem csupán a funkcionális programozási paradigmát használja [6] . A Lisp-et olyan nyelvek fejlesztették tovább, mint a Scheme és a Dylan .

Az Information Processing Language , az IPL néha a legelső gépi funkcionális nyelvként definiálható [7] . Ez egy assembly nyelv a szimbólumok listájával való munkavégzéshez. Volt benne egy "generátor" fogalma, amely egy függvényt használt argumentumként, és mivel egy assembly szintű nyelvről van szó, elhelyezhető olyan nyelvként, amely magasabb rendű függvényekkel rendelkezik. Általában azonban az IPL hangsúlyozza az imperatív fogalmak használatát [8] .

Kenneth Iverson a hatvanas évek elején fejlesztette ki az APL nyelvet , amelyet A Programming Language ( ISBN 978-0-471-43014-8 ) című könyvében dokumentált [9] . Az APL jelentős hatással volt a John Backus által létrehozott FP nyelvre . Az 1990-es évek elején Iverson és Roger Hui létrehozta az APL utódját, a programozási nyelvet . A kilencvenes évek közepén Arthur Whitney , aki korábban Iversonnal dolgozott, megalkotta a K nyelvet , amelyet később kereskedelmi forgalomba is használtak a pénzügyi szektorban.

Robin Milner az 1970 -es években az Edinburgh-i Egyetemen hozta létre az ML nyelvet , David Turner pedig a St. Andrews -i Egyetemen indította el a SASL -t , később pedig a Kenti Egyetemen Miranda . Végül több nyelvet hoztak létre az ML alapján, amelyek közül a leghíresebbek az Objective Caml és a Standard ML . Szintén a hetvenes években a Scheme (nem csak funkcionális paradigma megvalósítása) elvén alapuló programozási nyelvet fejlesztettek ki, amelyet a híres „Lambda-papírok” című mű, valamint a nyolcvanötödik év könyve ír le. „ Számítógépes programok felépítése és értelmezése ”.

1972-ben Per Martin-Löf megalkotta az intuicionista (konstruktív) típuselméletet . Ebben az elméletben a funkcionális programozás konstruktív bizonyítékot kapott arra, amit korábban függő típusnak neveztek. Ez erőteljes lökést adott az interaktív tételbizonyítás kifejlesztéséhez és számos funkcionális nyelv későbbi létrehozásához.

A Haskell az 1980-as évek végén jött létre azzal a céllal, hogy egyesítse a funkcionális programozási kutatásokból származó ötleteket [3] .

Fogalmak

Egyes fogalmak és paradigmák a funkcionális programozásra jellemzőek, és többnyire idegenek az imperatív programozástól (beleértve az objektum-orientált programozást is ). A programozási nyelvek azonban általában több programozási paradigma hibridjei, így a „többnyire kötelező” programozási nyelvek használhatják ezen fogalmak bármelyikét [10] .

Magasabb rendű funkciók

A magasabb rendű függvények olyan függvények, amelyek argumentumként vehetnek részt, és más függvényeket is visszaadhatnak. [11] . A matematikusok gyakran nevezik az ilyen függvényeket operátornak , például derivált operátornak vagy integrációs operátornak.

A magasabb rendű függvények lehetővé teszik a currying használatát  – egy függvény átalakítását egy argumentumpárból olyan függvényté, amely egyenként veszi át az argumentumokat. Ez az átalakulás Haskell Curry nevéhez fűződik .

Tiszta függvények

Tiszta függvények azok, amelyeknek nincs I/O és memória mellékhatása (csak a paramétereiktől függenek és csak az eredményüket adják vissza). A tiszta függvényeknek számos hasznos tulajdonsága van, amelyek közül sok felhasználható a kód optimalizálására:

A memoizációnak köszönhetően, ha a függvényt később ugyanazokkal az argumentumokkal hívjuk meg, akkor annak eredménye közvetlenül az értéktáblázatból vehető ki számítás nélkül (ezt néha referencia átlátszóság elvnek is nevezik). A memoizáció kis memóriafelhasználás árán jelentősen növelheti a teljesítményt és csökkentheti egyes rekurzív algoritmusok növekedési sorrendjét.

Míg a kötelező programozási nyelvek fordítóinak többsége felismeri a tiszta függvényeket, és eltávolítja a közös részkifejezéseket a tiszta függvényhívásoknál, nem mindig tudják ezt megtenni az előre lefordított könyvtárak esetében, amelyek általában nem biztosítják ezt az információt. Egyes fordítók, mint például a gcc , optimalizálási célból tiszta függvénykulcsszavakat biztosítanak a programozónak [12] . A Fortran 95 lehetővé teszi a funkciók "tiszta" (tiszta) kijelölését [13] .

Rekurzió

A funkcionális nyelvekben a ciklus általában rekurzióként valósul meg. Szigorúan véve a funkcionális programozási paradigmában nincs olyan, hogy hurok. A rekurzív függvények hívják magukat, lehetővé téve a műveletek újra és újra elvégzését. A rekurzió használatához nagy veremre lehet szükség , de ez elkerülhető a farokrekurzióval . A farokrekurziót a fordító felismerheti és optimalizálhatja olyan kódká, amely egy kötelező programozási nyelven egy hasonló iteráció fordításából származik. [14] A Scheme nyelvi szabványai megkövetelik a farokrekurzió felismerését és optimalizálását. A farokrekurziót úgy lehet optimalizálni, hogy a programot a fordítás során a folytatások használatának stílusára alakítjuk át, mint az egyik mód. [tizenöt]

A rekurzív függvények általánosíthatók magasabb rendű függvényekre, például katamorfizmus és anamorfizmus (vagy "konvolúció" és "kiterjesztés") felhasználásával [16] . Az ilyen jellegű funkciók egy ilyen fogalom szerepét töltik be, mint egy ciklus az imperatív programozási nyelvekben [17] .

Érvértékelési megközelítés

A funkcionális nyelvek osztályozhatók aszerint, hogy a függvényargumentumokat hogyan kezelik a kiértékelés során. Technikailag a különbség a kifejezés denotációs szemantikájában rejlik . Például egy kifejezés kiértékelésének szigorú megközelítésével:

nyomtatás ( len ([ 2 + 1 , 3 * 2 , 1 / 0 , 5 - 4 ]))

a kimenet hiba lesz, mivel a lista harmadik eleme nullával való osztást tartalmaz. Nem szigorú megközelítéssel a kifejezés értéke 4 lesz, mivel szigorúan véve elemeinek értékei nem fontosak a lista hosszának kiszámításához, és előfordulhat, hogy egyáltalán nem számíthatók ki. Szigorú (alkalmazó) értékelési sorrend esetén az összes argumentum értéke előre kiszámításra kerül, mielőtt magát a függvényt kiértékelné. Nem szigorú megközelítéssel (normál kiértékelési sorrend) az argumentumok értékei nem kerülnek kiértékelésre mindaddig, amíg az értékükre nincs szükség a függvény kiértékelésekor [18] .

Általános szabály, hogy a nem szigorú megközelítést gráfredukció formájában valósítják meg. A nem szigorú kiértékelés az alapértelmezett több tisztán funkcionális nyelvben, köztük a Mirandában és a Haskellben [19] .

Nem funkcionális nyelveken

Elvileg nincs akadálya a funkcionális stílusú programok írásának olyan nyelveken, amelyek hagyományosan nem tekinthetők funkcionálisnak, mint ahogy az objektum-orientált stílusú programok is írhatók strukturális nyelveken. Egyes kötelező nyelvek támogatják a funkcionális nyelvekre jellemző konstrukciókat, például a magasabb rendű függvényeket és a listamegértéseket, amelyek megkönnyítik a funkcionális stílus használatát ezekben a nyelvekben, különösen ezt a megközelítést széles körben használják a Python nyelv gyakorlatában. . Egy másik példa a Ruby nyelv , amely egyszerre képes névtelen függvényeket létrehozni kötött változók (λ-objektumok) használatával, és képes a magasabb rendű névtelen függvények blokkon keresztül történő rendszerezésére a yield. A C nyelvben a függvénymutatók argumentumtípusként használhatók magasabb rendű függvények létrehozására. A magasabb rendű függvények és a halasztott listastruktúra a C++ könyvtárakban valósul meg . Java 8 és újabb, valamint C# 3.0 és újabb verziókban a λ-függvények segítségével funkcionális stílusban írhatunk programokat.

Programozási stílusok

Az imperatív programok általában a lépések sorozatát hangsúlyozzák valamilyen művelet végrehajtásához, míg a funkcionális programok a funkciók elrendezését és összetételét hangsúlyozzák, gyakran nem jelölik a lépések pontos sorrendjét. Egy egyszerű példa ugyanannak a problémának a két megoldására (ugyanazon Python nyelv használatával ) szemlélteti ezt.

# imperative style target = [] # hozzon létre egy üres listát a forráslista eleméhez : # a forráslista minden eleméhez transz1 = G ( elem ) # alkalmazza a G ( ) függvényt trans2 = F ( transz1 ) # alkalmazza az F() függvényt target . append ( trans2 ) # a konvertált elem hozzáfűzése a listához

A funkcionális változat másképp néz ki:

# funkcionális stílus # FP nyelvekben gyakran van a compose() beépítve a compose2 -be = lambda A , B : lambda x : A ( B ( x )) target = map ( compose2 ( F , G ), forrás_lista )

Az imperatív stílustól eltérően, amely a cél eléréséhez vezető lépéseket írja le, a funkcionális stílus az adatok és a cél közötti matematikai kapcsolatot írja le.

Pontosabban, a funkcionális stílus kialakulásának négy szakasza van, az adatok programokban betöltött szerepének csökkenő sorrendjében:

Az első esetben a program teljes szerkezetét az adatstruktúra határozza meg, az utóbbi esetben az adatok, mint olyanok, egyáltalán nem szerepelnek a forráskódban, csak a bemeneten szerepelnek. Egyes nyelvek számos stílust támogatnak: például a Haskell lehetővé teszi, hogy alkalmazó, kombinatív és pont nélküli stílusban is írjon.

Jellemzők

A funkcionális programozás fő jellemzője, amely meghatározza ennek a paradigmának az előnyeit és hátrányait is, hogy állapot nélküli számítási modellt valósít meg. Ha egy imperatív programnak a végrehajtás bármely szakaszában van állapota, azaz az összes változó értékkészlete, és mellékhatásokat produkál, akkor a tisztán funkcionális programnak nincs állapota sem egészben, sem részben, és nem hoz létre mellékhatást. hatások. Amit a kötelező nyelvekben a változókhoz értékek hozzárendelésével tesznek, azt a funkcionális nyelvekben úgy érik el, hogy kifejezéseket adnak át a függvényparamétereknek. Ennek azonnali következménye, hogy egy tisztán funkcionális program nem tudja megváltoztatni a már meglévő adatait, hanem csak a régiek másolásával vagy kiterjesztésével tud újakat generálni. Ennek következménye a ciklusok elutasítása a rekurzió javára.

Erősségek

A kód megbízhatóságának növelése

Az állapot nélküli számítástechnika vonzó oldala a kód megnövekedett megbízhatósága a világos strukturálás miatt, és a mellékhatások követésének hiánya. Bármely függvény csak helyi adatokkal működik, és mindig ugyanúgy működik velük, függetlenül attól, hogy hol, hogyan és milyen körülmények között hívják. Az adatok mutációjának lehetetlensége, ha ezeket a program különböző helyein használjuk, kiküszöböli a nehezen észlelhető hibák megjelenését (például egy kötelező programban véletlenül helytelen értéket adunk egy globális változóhoz).

Az egységtesztelés egyszerű megszervezése

Mivel a funkcionális programozásban egy függvény nem tud mellékhatásokat kiváltani, az objektumok sem a hatókörön belül, sem azon kívül nem változtathatók meg (ellentétben az imperatív programokkal, ahol az egyik függvény beállíthat valamilyen külső változót, amelyet a második függvény olvasson be). Egy függvény kiértékelésének egyetlen hatása a visszaadott eredmény, és az egyetlen tényező, amely befolyásolja az eredményt, az argumentumok értéke.

Így lehetőség van egy program minden függvényének tesztelésére úgy, hogy egyszerűen kiértékeli azt különböző argumentumértékekből. Ebben az esetben nem kell aggódnia a függvények megfelelő sorrendben történő meghívásával, vagy a külső állapot helyes kialakításával. Ha a program bármely funkciója átmegy az egységteszteken, akkor biztos lehet a teljes program minőségében. Az imperatív programokban nem elegendő egy függvény visszatérési értékének ellenőrzése: a függvény módosíthatja a külső állapotot, amit szintén ellenőrizni kell, ami a funkcionális programokban nem szükséges [20] .

A fordító optimalizálási lehetőségei

A funkcionális programozás hagyományosan említett pozitív tulajdonsága, hogy lehetővé teszi a program úgynevezett "deklaratív" formában történő leírását, amikor az eredmény kiszámításához szükséges számos művelet végrehajtásának merev sorozata nincs kifejezetten megadva, hanem automatikusan létrejön a programban. a függvények kiszámításának folyamata. Ez a körülmény, valamint az állapotok hiánya lehetővé teszi az automatikus optimalizálás meglehetősen összetett módszereinek alkalmazását a funkcionális programokra.

Párhuzamossági képességek

A funkcionális programok másik előnye, hogy a számítások automatikus párhuzamosítására adják a legszélesebb lehetőséget . Mivel a mellékhatások hiánya garantált, bármely függvényhívásban mindig megengedett két különböző paraméter párhuzamos kiértékelése – a kiértékelésük sorrendje nem befolyásolhatja a hívás eredményét.

Helyi kód olvashatósága

Egy imperatív program kódjának elemzésekor fontos tudni, hogy „hol vagyunk most”. A környezet ismerete nélkül nehéz megváltoztatni a kódot, ezért a változtatások végrehajtása előtt először meg kell érteni a végrehajtás általános kontextusát, vagy legalábbis a szerkesztett modulon belül. A funkcionális programozásban viszont a kód helyben olvasható és szerkeszthető, anélkül, hogy attól kellene tartani, hogy ez váratlan következményekkel járna. Ez lehetővé teszi, hogy a különböző hozzáférési szintekkel rendelkező résztvevők együtt dolgozhassanak a programon anélkül, hogy a kód modularitása érdekében többletköltségek merülnének fel.

Hátrányok

A funkcionális programozás hátrányai ugyanazokból a tulajdonságokból fakadnak. A hozzárendelések hiánya és új adatok generálásával történő helyettesítése állandó memóriaelosztást és automatikus felszabadítást tesz szükségessé, ezért egy funkcionális program végrehajtó rendszerében kötelezőszemétgyűjtő válik alkatrészévé . A nem szigorú számítási modell a függvényhívások előre nem látható sorrendjéhez vezet, ami problémákat okoz az I/O-ban, ahol a műveletek sorrendje fontos. Természetesen a bemeneti függvények természetes formájukban (például a szabványos Cgetchar() könyvtárból ) nem tiszták, mivel ugyanazon argumentumokhoz különböző értékeket tudnak visszaadni, és ennek kiküszöbölésére bizonyos trükkökre van szükség.

A funkcionális programok hiányosságainak kiküszöbölésére már az első funkcionális programozási nyelvek is nemcsak tisztán funkcionális eszközöket, hanem kötelező programozási mechanizmusokat is tartalmaztak (a hozzárendelés, a ciklus, az "implicit PROGN" már a Lisp-ben volt). Az ilyen eszközök használata megold néhány gyakorlati problémát, de azt jelenti, hogy eltávolodunk a funkcionális programozás gondolataitól (és előnyeitől), és kötelező programokat írunk funkcionális nyelveken. A tisztán funkcionális nyelvekben ezeket a problémákat más eszközökkel oldják meg, például a Haskellben az I/O-t monádok segítségével valósítják meg  , ez a fogalom a kategóriaelméletből kölcsönzött.

Jegyzetek

  1. A. Field, P. Harrison Funkcionális programozás: Per. angolról. - M .: Mir, 1993. - 637 p., ill. ISBN 5-03-001870-0 . oldal 120 [6. fejezet: Matematikai alapok: λ-számítás].
  2. 1 2 Paul Hudak A funkcionális programozási nyelvek koncepciója, fejlődése és alkalmazása  (angol)  // Association for Computing Machinery Computing Surveys : folyóirat. - 1989. - szeptember ( 21. évf. , 3. sz.). - P. 359-411 . - doi : 10.1145/72551.72554 . Archiválva az eredetiből 2013. június 5-én.
  3. Roger Penrose . 2. fejezet: Church's Lambda Calculus // The King's New Mind. A számítógépekről, a gondolkodásról és a fizika törvényeiről = The Emperors New Mind: Concerning Computers, Minds and The Laws of Physics. - Szerkesztői URSS, 2003. - ISBN 5-354-00005-X . + az ISBN 978-5-382-01266-7 ismételt kiadása ; 2011
  4. McCarthy, John Lisp története  // A Számítástechnikai Gépek Szövetségében SIGPLAN Programozási nyelvek története ​​konferencia. - 1978. - június. - S. 217-223 . - doi : 10.1145/800025.808387 . Archiválva az eredetiből 2008. június 7-én.
  5. J. Harrison, 1997 , Ch. 3. A λ-kalculus mint programozási nyelv.
  6. Herbert Simon (1991), Models of My Life pp.189-190 ISBN 0-465-04640-1 című emlékiratában kijelenti, hogy az ő, Al. Newell és Cliff Shaw, akiket "gyakran a mesterséges intelligencia atyjaként emlegetnek" a Logic Theorist program megírásáért, amely automatikusan bizonyítja a Principia Mathematica tételeit . Ennek eléréséhez olyan nyelvet és paradigmát kellett kidolgozniuk, amely utólag funkcionális programozásnak tekinthető.
  7. Programozási nyelvek története: IPL (downlink) . Letöltve: 2012. április 15. Az eredetiből archiválva : 2006. november 1.. 
  8. XIV. APL Session // A programozási nyelv története / Richard L. Wexelbblat. - Akadémiai Kiadó, 1981. - S.  661 -693. — 749 p. — ISBN 0-12-745040-8 .
  9. Jevgenyij Kirpicsev. Funkcionális nyelvek elemei  // Funkcionális programozás gyakorlata. - 2009. - december ( 3. szám ). — ISSN 2075-8456 . Az eredetiből archiválva: 2017. szeptember 3.
  10. PDF letöltése: "A funkcionális programozás technikái, V. A. Potapenko" 8. o. "Magasabb rendű funkciók" . Hozzáférés dátuma: 2009. január 10. Az eredetiből archiválva : 2009. június 30.
  11. GCC, A funkciók tulajdonságainak deklarálása . Letöltve: 2012. augusztus 28. Az eredetiből archiválva : 2012. augusztus 18..
  12. XL Fortran for AIX, V13.1 > Nyelvi referencia, tiszta eljárások (Fortran 95)
  13. Tail call optimalizálás . Hozzáférés dátuma: 2012. július 31. Az eredetiből archiválva : 2012. augusztus 1..
  14. Átdolgozott5 Jelentés az algoritmikus nyelvi rendszerről, 3.5. Megfelelő farokrekurzió . Hozzáférés időpontja: 2012. július 31. Az eredetiből archiválva : 2007. január 5..
  15. Meijer, Erik ; Fokinga, Maarten; Paterson, Ross (1991). Funkcionális programozás banánnal, lencsékkel, borítékokkal és szögesdróttal (PDF) . Konferencia a funkcionális programozási nyelvekről és a számítógépes architektúráról (FPCA). Springer. pp. 124-144. CiteSeerX  10.1.1.41.125 . ISBN  3-540-54396-1 . Archivált (PDF) az eredetiből ekkor: 2017-07-09 . Letöltve: 2020-03-03 . Elavult használt paraméter |deadlink=( súgó )
  16. Madár, Richard. A funkcionális algoritmus  tervezés gyöngyszemei ​​. - Cambrigde : University Press , 2010. - 277 p. - ISBN 978-0-521-51338-8 . Archiválva : 2022. március 8. a Wayback Machine -nél
  17. N. A. Roganova Funkcionális programozás: Tankönyv felsőoktatási intézmények hallgatóinak - M .: GINFO, 2002. - 260 p. oldal 14. o 3.1. Lusta és lelkes számítástechnika
  18. Lusta értékelés – áttekintés | ScienceDirect témák . www.sciencedirect.com . Letöltve: 2021. március 23.
  19. Ahmechet V. "Funkcionális programozás mindenkinek" . Hozzáférés dátuma: 2009. január 11. Az eredetiből archiválva : 2009. február 2..

Irodalom

  • Gorodnyaya LV A funkcionális programozás alapjai. Előadások menete - M .: Internet University of Information Technologies, 2004. S. 280. ISBN 5-9556-0008-6
  • Dushkin R. V. Funkcionális programozás Haskellben. — M.: DMK Press, 2006. S. 608. ISBN 5-94074-335-8
  • Field A., Harrison P. Funkcionális programozás = Funkcionális programozás. — M .: Mir, 1993. — 637 p. — ISBN 5-03-001870-0 .
  • N. A. Roganova Funkcionális programozás: Tankönyv felsőoktatási intézmények hallgatói számára - M .: GINFO, 2002. - 260 p.
  • John Harrison. Funkcionális programozás. Előadások menete = Funkcionális programozás . – 1997.
  • A. M. Mironov. A funkcionális programok elmélete.

Linkek