Viitteellinen avoimuus

Viite läpinäkyvyys on ominaisuus ilmaisuja on ohjelmointikieli , joka on ilmaisu voidaan korvata sen arvo muuttamatta käyttäytymistä ohjelman .

Määritelmä

Jos kaikki lausekkeeseen liittyvät toiminnot ovat puhtaita , toisin sanoen jos niillä on aina samat palautusarvot samoille argumenteille ja jos niillä ei ole sivuvaikutuksia , lauseke on viitteellisesti läpinäkyvä. Mutta päinvastoin on väärä: viitteellisesti läpinäkyvä lauseke voi tarkoittaa epäpuhtaita toimintoja.

Viittaava läpinäkyvyys on toiminnallisen ohjelmoinnin kulmakivi . Se mahdollistaa erityisesti viitteellisesti läpinäkyvien toimintojen muistamisen (toisin sanoen aiemmin laskettujen arvojen muistamisen).

Esimerkkejä ja vasta-esimerkkejä

Aritmeettiset operaatiot ovat viitteellisesti läpinäkyviä: voimme siis korvata 4*3sen arvon 12tai merkillä 2*6tai 3*4. Termin matemaattisessa merkityksessä olevat funktiot ovat viitteellisesti läpinäkyviä: näin on esimerkiksi funktiona, sin(x)joka on referenssiltään läpinäkyvä, koska se palauttaa aina saman tuloksen xtietylle ja sillä ei ole sivuvaikutuksia.

Sitä vastoin ilmaisu x++on C-kielen ei ole viitteellisesti läpinäkyvä, koska se muuttaa arvon x. Sama pätee siihen, today() kuka ei ole viitteellisesti läpinäkyvä, koska jos arvioimme sen tänään, emme saa samaa tulosta kuin jos suoritamme sen huomenna.

Kontrasti välttämättömän ohjelmoinnin kanssa

Jos lausekkeen korvaaminen sen arvolla on kelvollinen vain tietyissä ohjelman kohdissa, lauseke ei ole viitteellisesti läpinäkyvä. Määritelmä ja sen pistejärjestys  (in) ovat imperatiivisen ohjelmoinnin teoreettinen perusta ja ovi imperatiivisten ohjelmointikielien semantiikassa.

Koska viitteellisesti läpinäkyvä lauseke voidaan kuitenkin aina korvata sen arvolla tai saman arvon tuottavalla lausekkeella, ei ole tarvetta määritellä sekvenssipisteitä tai säilyttää arvioinnin järjestystä. Kutsumme puhtaasti toiminnallista ohjelmointia ohjelmointiparadigmaksi, joka on vapaa teloitusten kiinteän aikataulutuksen huolista.

Viitteellisesti läpinäkyvän koodin kirjoittamisen etuna on, että staattinen koodianalyysi on helpompaa ja automaattiset koodinparannusmuunnokset ovat mahdollisia. Esimerkiksi C-ohjelmoinnissa toiminnon sisällyttäminen silmukkaan on hinnalla suorituskyvyssä, kun taas funktio voidaan siirtää silmukasta muuttamatta ohjelman tuloksia. Siirtämällä tätä toimintoa ohjelmoija voi menettää koodin luettavuuden . Mutta jos kääntäjä pystyy määrittämään funktion kutsun viitteellisen läpinäkyvyyden, se suorittaa automaattisesti tämän siirron ja tuottaa siten tehokkaamman koodin.

Viittaavaa läpinäkyvyyttä vaativat kielet vaikeuttavat luonnostaan ​​vaiheiden sarjana ilmaistavien toimintojen kirjoittamista. Tällaiset kielet voivat sisältää mekanismeja näiden tehtävien helpottamiseksi säilyttäen samalla niiden puhtaasti toiminnallisen laadun, kuten monadit ja tarkat lausekieliopit .

Vaikka matematiikassa kaikki funktiosovellukset ovat viitteellisesti läpinäkyviä, pakollisessa ohjelmoinnissa näin ei ole aina. Esimerkiksi toiminnossa, jossa ei ole parametreja ja joka palauttaa näppäimistölle syötetyn merkkijonon , paluuarvo riippuu syötetystä arvosta, joten useita funktion kutsuja, joilla on samat parametrit (tyhjä luettelo), voivat palata erilaisiin tuloksiin.

Kutsu funktiolle, joka käyttää globaalia muuttujaa tai dynaamisen tai leksisen laajuuden omaavaa muuttujaa tulosten laskemiseen, ei ole viitteellisesti läpinäkyvä. Koska tätä muuttujaa ei välitetä parametrina, mutta se voi olla vioittunut, seuraavien funktiokutsujen tulokset voivat poiketa toisistaan, vaikka parametrit olisivat samat. Puhtaissa toiminnallisissa kielissä määritys ei ole sallittua, mutta monadien käyttö sallii puhtaan toiminnallisen ohjelmoinnin samalla kun mekanismi muistuttaa läheisesti globaaleja muuttujia.

Viittaavan läpinäkyvyyden merkitys on, että se antaa ohjelmoijan tai kääntäjän perustella ohjelman käyttäytymistä. Se voi auttaa osoittamaan, että se on oikea, löytää virheitä, joita ei löydy testaamalla, yksinkertaistaa algoritmia , auttaa modifioimaan koodia rikkomatta sitä, optimoimaan koodin muistin avulla tai poistamaan yleiset alilausekkeet.

Jotkut toiminnalliset ohjelmointikielet (kuten Haskell ) pakottavat viitteellisen läpinäkyvyyden kaikille toiminnoille.

Komennon ja pyynnön erottamisen periaate

Vaikka Eiffel perustuu pakottavaan ohjelmointiin, se asettaa tiukan erotuksen komentojen välillä, jotka voivat tuottaa sivuvaikutuksia, ja pyyntöjen, joiden on oltava viitteellisesti avoimia. Kyselyt palauttavat tuloksen, mutta eivät muuta ympäristöä. Kutsumme tätä sääntöä komento-kysely-erotuksen periaatteeksi, joka mahdollistaa tyylin, joka erottaa selvästi suhteellisesti läpinäkyvät osat muista. Esimerkiksi luetteloiden käsittelyssä:

my_list.finish -- Déplace le curseur à la fin de la liste value := my_list.item -- Obtient la valeur à la position du curseur : référentiellement transparent

Se vaikuttaa jopa välttämättömiin ominaisuuksiin, kuten tuloihin:

my_file.read_integer -- obtient le prochain entier; effet de bord, mais pas de valeur de retour value := my_file.last_integer -- obtient le dernier entier lu: réferentiellement transparent

Soita useita kertoja peräkkäin last_integerantaa saman tuloksen joka kerta.

Toinen esimerkki

Tarkastellaan kahta toimintoa, joista toinen rqon viitteellisesti läpinäkymätön, ja toinen on rtviitteellisesti läpinäkyvä:

globalValue = 0; integer function rq(integer x) begin globalValue = globalValue + 1; return x + globalValue; end integer function rt(integer x) begin return x + 1; end

rtSanominen, että se on viitteellisesti läpinäkyvä, tarkoittaa, että n: lle annettu rt( n ) tuottaa aina saman arvon. Esimerkiksi, rt(6) = 7, rt(4) = 5ja niin edelleen. Mutta tämä ei ole totta, rqkoska se käyttää globaalia muuttujaa, jota se muuttaa.

Katso myös

Viitteet

  1. Pohjimmiltaan, kun käytät monadia StateHaskellissa ja sovellat sitä Intsaadaksesi Stat Int, se on kuin globaalin tyyppinen muuttuja Int, ei yhtä vähemmän eikä enempää. Siksi meillä on milloin tahansa tyypin ansiosta täydellinen ja staattinen tieto käyttämistämme globaaleista muuttujista.