Toiminnallinen ohjelmointi

Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 2. helmikuuta 2022 tarkistetusta versiosta . tarkastukset vaativat 2 muokkausta .

Funktionaalinen ohjelmointi  on ohjelmointiparadigma , jossa laskentaprosessi tulkitaan funktioiden arvojen laskemiseksi viimeksi mainitun matemaattisessa ymmärryksessä (toisin kuin toiminnot alirutiineina proseduuriohjelmointissa ).

Toisin kuin imperatiivisen ohjelmoinnin paradigma , joka kuvaa laskentaprosessia peräkkäisenä tilojen muutoksena (samanlaisessa mielessä kuin automaatioteoriassa ). Tarvittaessa funktionaalisessa ohjelmoinnissa koko laskentaprosessin peräkkäisten tilojen joukko esitetään eksplisiittisesti, esimerkiksi listana .

Funktionaalinen ohjelmointi tarkoittaa funktioiden tulosten laskemista syöttötiedoista ja muiden funktioiden tuloksista, eikä se tarkoita ohjelman tilan nimenomaista tallentamista. Vastaavasti se ei myöskään tarkoita tämän tilan muuttuvuutta (toisin kuin imperatiivi , jossa yksi peruskäsitteistä on muuttuja , joka tallentaa arvonsa ja jonka avulla voit muuttaa sitä algoritmia suoritettaessa ).

Käytännössä ero matemaattisen funktion ja "funktion" käsitteen välillä imperatiivisessa ohjelmoinnissa on se, että imperatiiviset funktiot voivat perustua argumenttien lisäksi myös funktion ulkopuolisten muuttujien tilaan, ja niillä voi olla sivuvaikutuksia ja muutoksia . ulkoisten muuttujien tila. Siten pakollisessa ohjelmoinnissa, kun kutsut samaa funktiota samoilla parametreilla, mutta algoritmin suorittamisen eri vaiheissa, voit saada erilaisia ​​lähtötietoja johtuen muuttujan tilan vaikutuksesta funktioon. Ja toiminnallisella kielellä, kun kutsumme funktiota samoilla argumenteilla, saamme aina saman tuloksen: tulos riippuu vain syötteestä. Tämä mahdollistaa funktionaalisten kielten ajonaikaisten funktioiden tulosten tallentamisen välimuistiin ja kutsumisen järjestyksessä, jota algoritmi ei ole määrittänyt, ja rinnakkaista niitä ilman ohjelmoijan lisätyötä (joka tarjoaa toimintoja ilman sivuvaikutuksia - puhtaita toimintoja ) .

Lambda-laskenta on toiminnallisen ohjelmoinnin perusta, monia toiminnallisia kieliä voidaan pitää sen "lisäosina" [1] .

Toiminnalliset ohjelmointikielet

Tunnetuimmat toiminnalliset ohjelmointikielet ovat :

Sekä Lisp :n että APL :n ei vielä täysin toimineet alkuperäiset versiot antoivat erityisen panoksen toiminnallisen ohjelmoinnin luomiseen ja kehittämiseen. Lispin myöhemmät versiot, kuten Scheme , sekä erilaiset APL-versiot tukivat kaikkia toiminnallisen kielen ominaisuuksia ja konsepteja [3] .

Kiinnostus toiminnallisiin ohjelmointikieliin, erityisesti puhtaasti toiminnallisiin, on yleensä ollut enemmän tieteellistä kuin kaupallista. Huomattavat kielet, kuten Erlang , OCaml , Haskell , Scheme (vuoden 1986 jälkeen) sekä erityinen R (tilastot), Wolfram (symbolinen matematiikka), J ja K (taloudellinen analyysi) ja XSLT ( XML ) löysivät omansa . tie kaupalliselle ohjelmointiteollisuudelle. Laajalle levinneet deklaratiiviset kielet, kuten SQL ja Lex / Yacc , sisältävät joitain toiminnallisen ohjelmoinnin elementtejä, esimerkiksi eivät käytä muuttujia. Taulukkokieliä voidaan pitää myös toimivina, koska laskentataulukon solut sisältävät joukon toimintoja, jotka yleensä riippuvat vain muista soluista, ja jos haluat mallintaa muuttujia, sinun on turvauduttava pakollisen makrokielen ominaisuuksiin .

Historia

Lambda-laskennasta on tullut teoreettinen perusta funktioiden kuvaamiselle ja laskemiselle. Koska se on matemaattinen abstraktio , ei ohjelmointikieli , se on muodostanut perustan lähes kaikille toiminnallisille ohjelmointikielille nykyään. Samanlainen teoreettinen käsite, kombinatorinen logiikka , on abstraktimpi kuin λ-laskenta ja se luotiin aikaisemmin. Tätä logiikkaa käytetään joissakin esoteerisissa kielissä , kuten Unlambda . Sekä λ-laskenta että kombinatorinen logiikka kehitettiin kuvaamaan selkeämmin ja tarkemmin matematiikan periaatteita ja perusteita [4] .

Ensimmäinen toiminnallinen kieli oli Lisp , jonka John McCarthy loi MIT: ssä 1950-luvun lopulla ja joka toteutettiin alun perin IBM 700/7000 :lle [5] . Lisp esitteli ensimmäisenä monia toiminnallisia kielikonsepteja, vaikka kieli käyttää muutakin kuin toiminnallista ohjelmointiparadigmaa [6] . Lispiä kehittivät edelleen sellaiset kielet kuin Scheme ja Dylan .

Tietojenkäsittelykieli , IPL määritellään joskus ensimmäiseksi koneen toiminnalliseksi kieleksi [ 7] . Se on kokoonpanokieli symboliluettelon kanssa työskentelemiseen. Siinä oli "generaattorin" käsite, joka käytti funktiota argumenttina, ja koska se on kokoonpanotason kieli, se voidaan sijoittaa kieleksi, jolla on korkeamman asteen funktioita. Yleisesti IPL kuitenkin korostaa pakottavien käsitteiden käyttöä [8] .

Kenneth Iverson kehitti APL-kielen 1960-luvun alussa ja dokumentoi sen kirjassaan A Programming Language ( ISBN 978-0-471-43014-8 ) [9] . APL vaikutti merkittävästi John Backuksen luomaan FP -kieleen . 1990-luvun alussa Iverson ja Roger Hui loivat APL:n seuraajan, - ohjelmointikielen . 1990-luvun puolivälissä Arthur Whitney , joka oli aiemmin työskennellyt Iversonin kanssa, loi K -kielen , jota käytettiin myöhemmin kaupallisesti rahoitusalalla.

Robin Milner loi ML -kielen Edinburghin yliopistossa 1970-luvulla , ja David Turner aloitti SASL :n St. Andrewsin yliopistossa ja myöhemmin Mirandan Kentin yliopistossa. Lopulta ML:n perusteella luotiin useita kieliä, joista tunnetuimmat ovat Objective Caml ja Standard ML . Myös 70-luvulla kehitettiin ohjelmointikieli, joka perustuu Scheme-periaatteeseen (ei vain toiminnallisen paradigman toteutus), joka kuvattiin kuuluisassa teoksessa "Lambda Papers" sekä kahdeksannenkymmenennenviidennen vuoden kirjassa. " Tietokoneohjelmien rakenne ja tulkinta ".

Vuonna 1972 Per Martin-Löf loi intuitionistisen tyyppiteorian (kutsutaan myös konstruktiiviseksi). Tässä teoriassa toiminnallinen ohjelmointi sai rakentavan todisteen siitä, mitä aiemmin kutsuttiin riippuvaiseksi tyypiksi. Tämä antoi voimakkaan sysäyksen interaktiivisten lauseiden todistamisen kehittämiselle ja monien toiminnallisten kielten luomiselle.

Haskell luotiin 1980-luvun lopulla yrittäessään yhdistää monia toiminnallisen ohjelmoinnin tutkimuksen ideoita [3] .

Käsitteet

Jotkut käsitteet ja paradigmat ovat ominaisia ​​toiminnalliselle ohjelmoimiselle ja enimmäkseen vieraita pakottavalle ohjelmointille (mukaan lukien olioohjelmointi ). Ohjelmointikielet ovat kuitenkin yleensä useiden ohjelmointiparadigmien hybridi, joten "enimmäkseen pakolliset" ohjelmointikielet voivat käyttää mitä tahansa näistä käsitteistä [10] .

Korkeamman asteen toiminnot

Korkeamman asteen funktiot ovat funktioita, jotka voivat toimia argumenteina ja palauttaa muita toimintoja. [11] . Matemaatikko kutsuu tällaista funktiota usein operaattoriksi , esimerkiksi johdannaisoperaattoriksi tai integraatiooperaattoriksi.

Korkeamman asteen funktiot mahdollistavat curryingin käytön  – funktion muuntamisen argumenttiparista funktioksi, joka ottaa argumentit yksi kerrallaan. Tämä muunnos on nimetty Haskell Curryn mukaan .

Puhtaat funktiot

Puhtaat funktiot ovat sellaisia, joilla ei ole I/O- ja muistisivuvaikutuksia ( ne riippuvat vain parametreistaan ​​ja palauttavat vain tuloksensa). Puhtailla funktioilla on useita hyödyllisiä ominaisuuksia, joista monia voidaan käyttää koodin optimointiin:

Memoisoinnin ansiosta, jos funktiota kutsutaan myöhemmin samoilla argumenteilla, sen tulos voidaan ottaa suoraan arvotaulukosta ilman laskemista (kutsutaan joskus referenssiläpinäkyvyysperiaatteeksi). Memoisointi pienen muistinkulutuksen kustannuksella voi lisätä merkittävästi suorituskykyä ja vähentää joidenkin rekursiivisten algoritmien kasvujärjestystä.

Vaikka useimmat pakollisten ohjelmointikielten kääntäjät tunnistavat puhtaat funktiot ja poistavat yleiset osalausekkeet puhtaille funktiokutsuille, he eivät aina voi tehdä niin esikäännetyille kirjastoille, jotka eivät yleensä tarjoa näitä tietoja. Jotkut kääntäjät, kuten gcc , tarjoavat ohjelmoijalle puhtaita funktion avainsanoja optimointia varten [12] . Fortran 95 mahdollistaa funktioiden määrittämisen "puhtaiksi" (puhtaiksi) [13] .

Rekursio

Toiminnallisissa kielissä silmukka toteutetaan yleensä rekursiona. Tarkkaan ottaen toiminnallisessa ohjelmointiparadigmassa ei ole sellaista asiaa kuin silmukka. Rekursiiviset funktiot kutsuvat itseään, jolloin toiminto voidaan suorittaa yhä uudelleen ja uudelleen. Rekursion käyttäminen saattaa vaatia suuren pinon , mutta tämä voidaan välttää tail-rekursiolla . Kääntäjä voi tunnistaa tail-rekursion ja optimoida sen koodiksi, joka on seurausta kääntämällä samanlainen iteraatio pakollisella ohjelmointikielellä. [14] Scheme-kielistandardit edellyttävät tail-rekursion tunnistamista ja optimointia. Tail-rekursio voidaan optimoida muuntamalla ohjelma käännöstyyliin, jossa käytetään jatkoja, yhtenä tapana. [viisitoista]

Rekursiiviset funktiot voidaan yleistää korkeamman asteen funktioiksi käyttämällä esimerkiksi katamorfia ja anamorfia (tai "konvoluutio" ja "laajeneminen") [16] . Tällaisilla toiminnoilla on tällaisen käsitteen rooli syklinä pakollisissa ohjelmointikielissä [17] .

Argumenttien arvioinnin lähestymistapa

Toiminnalliset kielet voidaan luokitella sen mukaan, kuinka funktion argumentteja käsitellään arvioinnin aikana. Teknisesti ero on ilmaisun denotaatiosemantiikassa . Esimerkiksi tiukka lähestymistapa lausekkeen arviointiin:

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

tulos on virhe, koska luettelon kolmas elementti sisältää nollalla jaon. Ei-tiukalla lähestymistavalla lausekkeen arvo on 4, koska tarkasti ottaen sen elementtien arvot eivät ole tärkeitä luettelon pituuden laskennassa, eikä niitä välttämättä lasketa ollenkaan. Tiukassa (sovellisessa) arviointijärjestyksessä kaikkien argumenttien arvot lasketaan etukäteen ennen itse funktion arviointia. Ei-tiukalla lähestymistavalla (normaali arviointijärjestys) argumenttien arvoja ei arvioida ennen kuin niiden arvoa tarvitaan funktiota arvioitaessa [18] .

Yleensä ei-tiukka lähestymistapa toteutetaan graafin pienentämisen muodossa. Ei-tiukka arviointi on oletuksena useissa puhtaasti toiminnallisissa kielissä, mukaan lukien Miranda ja Haskell [19] .

Ei-toiminnallisilla kielillä

Periaatteessa ei ole esteitä funktionaalisten ohjelmien kirjoittamiselle kielillä, joita ei perinteisesti pidetä toiminnallisina, aivan kuten oliotyyppisiä ohjelmia voidaan kirjoittaa rakennekielillä. Jotkut pakottavat kielet tukevat toiminnallisille kielille tyypillisiä rakenteita, kuten korkeamman asteen funktioita ja listan ymmärtämistä, jotka helpottavat funktionaalisen tyylin käyttöä näissä kielissä, erityisesti tämä lähestymistapa on laajalti käytössä Python-kielen käytännössä. . Toinen esimerkki on Ruby -kieli , jolla on kyky luoda sekä anonyymejä toimintoja käyttämällä sidottuja muuttujia (λ-objekteja) että kyky järjestää korkeamman asteen anonyymejä toimintoja lohkon kautta käyttämällä yield. C : ssä funktioosoittimia argumenttityypeinä voidaan käyttää korkeamman asteen funktioiden luomiseen. Korkeamman asteen funktiot ja viivästetty listarakenne on toteutettu C++-kirjastoissa . Java 8: ssa ja uudemmissa sekä C# 3.0:ssa ja uudemmissa versioissa λ-funktioita voidaan käyttää ohjelman funktionaaliseen tyyliin kirjoittamiseen.

Ohjelmointityylit

Pakollisilla ohjelmilla on taipumus korostaa vaihesarjoja jonkin toiminnon suorittamiseksi, kun taas toiminnallisilla ohjelmilla on taipumus korostaa toimintojen järjestelyä ja kokoonpanoa, mutta ne eivät usein tarkoita tarkkaa vaiheiden järjestystä. Yksinkertainen esimerkki kahdesta ratkaisusta samaan ongelmaan (käyttämällä samaa Python-kieltä ) valaisee tätä.

# imperative style target = [] # luo tyhjä lista kohteelle lähdeluettelossa : # jokaiselle lähdeluettelon elementille trans1 = G ( item ) # käytä G() - funktiota trans2 = F ( trans1 ) # käytä F()-funktiota kohde . append ( trans2 ) # liittää muunnetun elementin luetteloon

Toiminnallinen versio näyttää erilaiselta:

# funktionaalinen tyyli # FP-kielissä on usein compose() sisäänrakennettu compose2 = lambda A , B : lambda x : A ( B ( x )) target = map ( compose2 ( F , G ), source_list )

Toisin kuin pakottava tyyli, joka kuvaa tavoitteen saavuttamiseen johtavia vaiheita, toiminnallinen tyyli kuvaa matemaattista suhdetta datan ja tavoitteen välillä.

Tarkemmin sanottuna toiminnallisen tyylin kehityksessä on neljä vaihetta, laskevassa järjestyksessä tietojen roolin mukaan ohjelmissa:

Ensimmäisessä tapauksessa koko ohjelman rakenne määräytyy tietorakenteen mukaan, jälkimmäisessä tapauksessa dataa sellaisenaan ei ole lähdekoodissa ollenkaan, ne ovat vain implisiittisiä syötteessä. Jotkut kielet tukevat useita tyylejä: esimerkiksi Haskell antaa sinun kirjoittaa sekä aplikatiivisilla, kombinatorisilla että pisteettömillä tyyleillä.

Ominaisuudet

Funktionaalisen ohjelmoinnin pääominaisuus, joka määrittää sekä tämän paradigman edut että haitat, on, että se toteuttaa tilattoman laskentamallin. Jos pakottavalla ohjelmalla on missä tahansa suoritusvaiheessa tila, eli joukko kaikkien muuttujien arvoja, ja se tuottaa sivuvaikutuksia, niin puhtaasti toiminnallisella ohjelmalla ei ole tilaa kokonaan tai osittain eikä se tuota sivua. tehosteita. Se, mitä pakollisilla kielillä tehdään antamalla muuttujille arvoja, saavutetaan toiminnallisissa kielissä välittämällä lausekkeita funktioparametreille. Välitön seuraus on, että puhtaasti toimiva ohjelma ei voi muuttaa olemassa olevaa dataa, vaan se voi vain luoda uusia kopioimalla tai laajentamalla vanhoja. Tämän seurauksena on syklien hylkääminen rekursion hyväksi.

Vahvuudet

Koodin luotettavuuden parantaminen

Tilattoman laskennan houkutteleva puoli on koodin lisääntynyt luotettavuus, joka johtuu selkeästä rakenteesta ja sivuvaikutusten jäljittämisen tarpeesta. Mikä tahansa toiminto toimii vain paikallisten tietojen kanssa ja toimii niiden kanssa aina samalla tavalla riippumatta siitä, missä, miten ja missä olosuhteissa sitä kutsutaan. Tietojen mutaatioiden mahdottomuus käytettäessä niitä ohjelman eri paikoissa eliminoi vaikeasti havaittavien virheiden esiintymisen (kuten esimerkiksi pakottavan ohjelman globaalille muuttujalle vahingossa määritetyn virheellisen arvon).

Yksikkötestauksen organisoinnin helppous

Koska funktionaalisen ohjelmoinnin funktio ei voi tuottaa sivuvaikutuksia, objekteja ei voi muuttaa sekä soveltamisalan sisällä että sen ulkopuolella (toisin kuin pakollisissa ohjelmissa, joissa yksi funktio voi asettaa jonkin ulkoisen muuttujan, jonka toinen funktio lukee). Ainoa vaikutus funktion arvioinnissa on sen palauttama tulos, ja ainoa tulokseen vaikuttava tekijä on argumenttien arvo.

Siten on mahdollista testata ohjelman jokaista funktiota yksinkertaisesti arvioimalla se eri argumenttiarvoista. Tässä tapauksessa sinun ei tarvitse huolehtia toimintojen kutsumisesta oikeassa järjestyksessä tai ulkoisen tilan oikeasta muodostumisesta. Jos jokin ohjelman toiminto läpäisee yksikkötestit, voit olla varma koko ohjelman laadusta. Pakollisissa ohjelmissa funktion palautusarvon tarkistaminen ei riitä: funktio voi muuttaa ulkoista tilaa, joka on myös tarkistettava, mikä ei ole välttämätöntä toiminnallisissa ohjelmissa [20] .

Kääntäjän optimointiasetukset

Perinteisesti mainittu funktionaalisen ohjelmoinnin positiivinen piirre on, että se mahdollistaa ohjelman kuvaamisen niin sanotussa "deklatiivisessa" muodossa, kun monien tuloksen laskemiseen tarvittavien toimintojen suorittamisjärjestystä ei ole erikseen määritelty, vaan se muodostuu automaattisesti funktioiden laskentaprosessi. Tämä seikka, samoin kuin tilojen puuttuminen, mahdollistaa melko monimutkaisten automaattisten optimointimenetelmien soveltamisen toiminnallisiin ohjelmiin.

Samanaikaisuusominaisuudet

Toinen toiminnallisten ohjelmien etu on, että ne tarjoavat laajimmat mahdollisuudet automaattiseen laskelmien rinnakkaisuun . Koska sivuvaikutusten puuttuminen on taattu, kaikissa funktiokutsuissa on aina sallittua arvioida kaksi eri parametria rinnakkain - niiden arviointijärjestys ei voi vaikuttaa kutsun tulokseen.

Paikallisen koodin luettavuus

Kun analysoidaan pakottavan ohjelman koodia, on tärkeää tietää "missä olemme nyt". Ilman ymmärrystä ympäristöstä on vaikeaa tehdä muutoksia koodiin, joten ennen muutosten tekemistä on ensin ymmärrettävä suorituksen yleinen konteksti tai ainakin muokatun moduulin sisällä. Toisaalta toiminnallisessa ohjelmoinnissa koodia voidaan lukea ja muokata paikallisesti ilman pelkoa, että tämä johtaa odottamattomiin seurauksiin. Näin eri käyttöoikeustasoilla olevat osallistujat voivat työskennellä yhdessä ohjelman parissa ilman lisäkustannuksia koodin modulaarisuuden varmistamisesta.

Haitat

Toiminnallisen ohjelmoinnin haitat johtuvat samoista ominaisuuksista. Tehtävien puuttuminen ja niiden korvaaminen uuden tiedon luomisella johtavat jatkuvaan muistin varaamiseen ja automaattiseen vapauttamiseen, joten toiminnallisen ohjelman suoritusjärjestelmässä se on pakollinenroskakorista tulee komponentti . Ei-tiukka laskentamalli johtaa arvaamattomaan funktiokutsujen järjestykseen, mikä aiheuttaa ongelmia I/O:ssa, jossa toimintojen järjestys on tärkeä. Ilmeisesti myös syöttöfunktiot luonnollisessa muodossaan (esimerkiksi tavallisesta Cgetchar() - kirjastosta ) eivät ole puhtaita, koska ne pystyvät palauttamaan eri arvoja samoille argumenteille, ja tämän poistamiseksi tarvitaan tiettyjä temppuja.

Funktionaalisten ohjelmien puutteiden voittamiseksi jopa ensimmäiset toiminnalliset ohjelmointikielet sisälsivät puhtaasti toiminnallisten työkalujen lisäksi myös pakollisen ohjelmoinnin mekanismeja (tehtävä, silmukka, "implisiittinen PROGN" olivat jo Lispissä). Tällaisten työkalujen käyttäminen ratkaisee joitain käytännön ongelmia, mutta tarkoittaa siirtymistä pois toiminnallisen ohjelmoinnin ideoista (ja eduista) ja välttämättömien ohjelmien kirjoittamista toiminnallisilla kielillä. Puhtaissa funktionaalisissa kielissä nämä ongelmat ratkaistaan ​​muilla tavoilla, esimerkiksi Haskellissa I/O on toteutettu käyttämällä  kategorioteoriasta lainattua käsitettä monadeja .

Muistiinpanot

  1. A. Field, P. Harrison Funktionaalinen ohjelmointi: Per. englannista. - M .: Mir, 1993. - 637 s., ill. ISBN 5-03-001870-0 . Sivu 120 [Luku 6: Matemaattiset perusteet: λ-laskenta].
  2. 1 2 Paul Hudak Funktionaalisten ohjelmointikielten käsitys, kehitys ja sovellus  (englanti)  // Association for Computing Machinery Computing Surveys : Journal. - 1989. - syyskuu ( osa 21 , nro 3 ) . - s. 359-411 . - doi : 10.1145/72551.72554 . Arkistoitu alkuperäisestä 5. kesäkuuta 2013.
  3. Roger Penrose . Luku 2: Kirkon lambdalaskenta // Kuninkaan uusi mieli. Tietokoneista, ajattelusta ja fysiikan laeista = The Emperors New Mind: Concerning Computers, Minds and The Laws of Physics. - Pääkirjoitus URSS, 2003. - ISBN 5-354-00005-X . + ISBN:n 978-5-382-01266-7 uudelleenjulkaisu ; 2011
  4. McCarthy, John Lispin historia  // Computing Machinery -yhdistyksen SIGPLAN-ohjelmointikielten historia -konferenssi. - 1978. - kesäkuuta. - S. 217-223 . - doi : 10.1145/800025.808387 . Arkistoitu alkuperäisestä 7. kesäkuuta 2008.
  5. J. Harrison, 1997 , Ch. 3. λ-laskenta ohjelmointikielenä.
  6. Muistelmissaan Herbert Simon (1991), Elämäni mallit s. 189-190 ISBN 0-465-04640-1 toteaa, että hänen, Al. Newell ja Cliff Shaw, joita kutsutaan usein tekoälyn isiksi, koska he ovat kirjoittaneet Logic Theorist -ohjelman, joka todistaa automaattisesti Principia Mathematican lauseet . Tämän saavuttamiseksi heidän piti keksiä kieli ja paradigma, joka jälkikäteen katsottuna voidaan nähdä toimivana ohjelmointina.
  7. Ohjelmointikielten historia: IPL (downlink) . Haettu 15. huhtikuuta 2012. Arkistoitu alkuperäisestä 1. marraskuuta 2006. 
  8. XIV. APL-istunto // Ohjelmointikielen historia / Richard L. Wexelbblat. - Academic Press, 1981. - S.  661 -693. — 749 s. — ISBN 0-12-745040-8 .
  9. Jevgeni Kirpitšev. Toiminnallisten kielten elementit  // Toiminnallisen ohjelmoinnin harjoittelu. - 2009. - Joulukuu ( numero 3 ). — ISSN 2075-8456 . Arkistoitu alkuperäisestä 3. syyskuuta 2017.
  10. Lataa PDF: "Funktionaalisen ohjelmoinnin tekniikat, V. A. Potapenko" s. 8 "Korkeamman asteen toiminnot" . Käyttöpäivä: 10. tammikuuta 2009. Arkistoitu alkuperäisestä 30. kesäkuuta 2009.
  11. GCC, funktioiden attribuuttien ilmoittaminen . Haettu 28. elokuuta 2012. Arkistoitu alkuperäisestä 18. elokuuta 2012.
  12. XL Fortran for AIX, V13.1 > Language Reference, Puhtaat menettelyt (Fortran 95)
  13. Tail call -optimointi . Käyttöpäivä: 31. heinäkuuta 2012. Arkistoitu alkuperäisestä 1. elokuuta 2012.
  14. Revised5 Report on the Algorithmic Language Scheme, 3.5. Oikea hännän rekursio . Käyttöpäivä: 31. heinäkuuta 2012. Arkistoitu alkuperäisestä 5. tammikuuta 2007.
  15. Meijer, Erik ; Fokinga, Maarten; Paterson, Ross (1991). Toiminnallinen ohjelmointi banaaneilla, linsseillä, kirjekuorilla ja piikkilangalla (PDF) . Konferenssi toiminnallisista ohjelmointikielistä ja tietokonearkkitehtuurista (FPCA). Springer. s. 124-144. CiteSeerX  10.1.1.41.125 . ISBN  3-540-54396-1 . Arkistoitu (PDF) alkuperäisestä 2017-07-09 . Haettu 2020-03-03 . Käytöstä poistettu parametri |deadlink=( ohje )
  16. Lintu, Richard. Functional Algorithm  Designin helmiä . - Cambrigde : University Press , 2010. - 277 s. - ISBN 978-0-521-51338-8 . Arkistoitu 8. maaliskuuta 2022 Wayback Machinessa
  17. N. A. Roganova Funktionaalinen ohjelmointi: Oppikirja korkeakoulujen opiskelijoille - M .: GINFO, 2002. - 260 s. Sivu 14 s. 3.1. Laiska ja innokas tietojenkäsittely
  18. Laiska arviointi - yleiskatsaus | ScienceDirect-aiheet . www.sciencedirect.com . Haettu: 23.3.2021.
  19. Ahmechet V. "Toimintaohjelmointi kaikille" . Käyttöpäivä: 11. tammikuuta 2009. Arkistoitu alkuperäisestä 2. helmikuuta 2009.

Kirjallisuus

  • Gorodnyaya LV Toiminnallisen ohjelmoinnin perusteet. Luentokurssi - M .: Internet University of Information Technologies, 2004. S. 280. ISBN 5-9556-0008-6
  • Dushkin R. V. Funktionaalinen ohjelmointi Haskellissa. — M.: DMK Press, 2006. S. 608. ISBN 5-94074-335-8
  • Kenttä A., Harrison P. Funktionaalinen ohjelmointi = Functional Programming. — M .: Mir, 1993. — 637 s. — ISBN 5-03-001870-0 .
  • N. A. Roganova Funktionaalinen ohjelmointi: Oppikirja korkeakoulujen opiskelijoille - M .: GINFO, 2002. - 260 s.
  • John Harrison. Toiminnallinen ohjelmointi. Luentokurssi = Functional Programming . – 1997.
  • A. M. Mironov. Toiminnallisten ohjelmien teoria.

Linkit