Syntaktinen sokeri

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

Ohjelmointikielen syntaktinen sokeri on syntaktinen   ominaisuus, joka ei vaikuta ohjelman toimintaan, mutta tekee kielestä käyttäjäystävällisemmän.

Se voi olla mikä tahansa syntaksielementti, joka antaa ohjelmoijalle vaihtoehtoisen tavan kirjoittaa syntaktinen konstruktio jo kielellä, joka on kätevämpi, ytimekkäämpi tai samanlainen kuin muu yleinen kirjoitustapa, tai auttaa kirjoittamaan ohjelmia hyvällä tyylillä.

Määritelmä

Syntaktinen sokeri on mikä tahansa ohjelmointikielessä saatavilla oleva syntaktinen elementti, mekanismi, kuvausmenetelmä, joka kopioi toista kielellä saatavilla olevaa elementtiä tai mekanismia, mutta on kätevämpi käyttää, on tiiviimpi tai näyttää luonnollisemmalta tai tutumpi ( samankaltainen kuin samankaltaiset elementit muilla kielillä) tai se yksinkertaisesti havaitaan paremmin, kun henkilö lukee ohjelmaa. Tärkeintä on, että syntaktinen sokeri voidaan teoriassa aina poistaa kielestä menettämättä sen kykyjä - kaikki, mikä voidaan kirjoittaa syntaktisella sokerilla, voidaan kirjoittaa samalla kielellä ilman sitä. Näin ollen syntaktinen sokeri on tarkoitettu vain helpottamaan ohjelmoijan ohjelman kirjoittamista.

Syntaktisen sokerin käsite on suurelta osin mielivaltainen. Sen käyttö olettaa, että koko kielellä saatavilla olevasta syntaktisten rakenteiden joukosta voidaan erottaa jokin "perusjoukko", joka tarjoaa kielen toiminnallisuuden, sekä syntaktisia lisäkeinoja, jotka voidaan haluttaessa ilmaista perusjoukolla ; jälkimmäinen on tietyn kielen syntaktinen sokeri. Monet mallit ovat kuitenkin keskenään vaihdettavissa, eikä aina ole mahdollista sanoa varmasti, mitkä niistä ovat perus- ja mitkä lisäosia. Esimerkiksi Modula-2 : ssa on neljän tyyppisiä silmukoita : ennakkoehtosilmukka , jälkiehtosilmukka , askelsilmukka ja ehdoton silmukka . Teoreettisesti kolme ensimmäistä sykliä voidaan helposti ilmaista viimeisellä. Ovatko ne sitten syntaktista sokeria? Yleensä he eivät sano niin, vaikka ne muodollisesti kuuluvat yllä olevan määritelmän piiriin.

Joidenkin rakenteiden kohdistaminen syntaktiseen sokeriin on historiallisista syistä moniselitteinen. Esimerkiksi C -kielellä ja sen jälkeläisillä on lisäys- , dekrementti- ja yhdistelmämäärittelyoperaattorit ( ++, --, +=, -=ja muut). Näiden operaattoreiden tuominen kieleen johtui tarpeesta tukea ohjelmien manuaalista optimointia, koska niitä käyttävä koodi voitiin kääntää tehokkaammiksi konekäskyiksi (" ++a" käännettiin yhdeksi INC-käskyksi ja vastaava ilmaisu " a=a+1" koko joukko ohjeita). Koodin optimointitekniikan kehitys on tehnyt tällaisesta manuaalisesta optimoinnista turhaa; nyt kääntäjät luovat saman koodin operaation "pitkälle" ja "lyhyelle" versiolle. Tämän seurauksena lyhennetyt operaattorit ovat muuttuneet syntaktiseksi sokeriksi, vaikka niitä ei alun perin ollutkaan.

"Syntaktinen sokeri" vai "Lexical Garbage"?

Joissakin tapauksissa "syntaktisen sokerin" käsite tulkitaan laajemmin kuin "erilainen tapa kirjoittaa jo olemassa oleville syntaktisille rakenteille". Jack Crenshaw kirjassa Rakennamme kääntäjä! [1] käyttää tätä termiä syntaktisiin elementteihin, joita ei tarvita ohjelman oikeaan kääntämiseen, mutta jotka sisältyvät kieleen vain ohjelmoijan mukavuuden ja ohjelman luettavuuden vuoksi:

Loppujen lopuksi ihmisten pitäisi myös lukea ohjelmia… Sokerimerkit toimivat hyödyllisinä maamerkeinä, jotka auttavat sinua pysymään raiteilla…

Esimerkki tällaisesta syntaktisesta sokerista on "if"-lauseessa "ten" tai "while"-lauseessa "do" sekä puolipiste: kääntäjä määrittää yksiselitteisesti ehdon lopun ja paikan, johon lauseke päättyy ilman ne, mutta näiden konstruktien läsnäolo tekee ohjelmasta luettavamman. On selvää, että "syntaktisen sokerin" käsitteen kapea tulkinta on ristiriidassa laajan kanssa: C :ssä tai Pascalissa on mahdotonta kirjoittaa operaattoreita eri tavalla ilman "sitten", "do" ja puolipistettä. Tällaisessa tapauksessa on aiheellista puhua " syntaksijätteestä ". Ottaen huomioon, että ylimääräiset sanat ohjelmointikielessä ovat ylimääräisiä tokeneita, olisi oikeampaa käyttää termiä " leksinen roska " [2] . Toisaalta ei ole täysin oikein kutsua tällaisia ​​kielen "ylimääräisiä" elementtejä "roskaksi", koska todellisuudessa ne voivat vaikuttaa merkittävästi ohjelmoinnin laatuun, koska redundanssin esiintyminen syntaksissa helpottaa kääntäjän työtä. lokalisoidaksesi virheet koodissa. Ajatellaanpa esimerkkiä jossain ehdollisessa BASIC-kaltaisessa kielessä, jossa sana sitten on valinnainen ehdollisessa lauseessa ja puolipiste lauseiden välissä, ja yhtäläisyysmerkki voi merkitä paikasta riippuen sekä loogista yhtäläisyyttä että osoitusta:

jos a > b ja k = 20 f = 10

Tässä "a>b ja k=20" on ehto, ja "f=10" on "se" haara. Jos ohjelmoija kuitenkin jättää pois tai vahingossa poistaa "and"-operaattorin, konstrukti on:

jos a > b k = 20 f = 10

Ohjelma pysyy syntaktisesti oikein, mutta ehto on yksinkertaisesti "a>b", ja "that"-haara on kielen säännöistä riippuen joko "k=20", joka on muuttunut ehdosta tehtävä tai molemmat operaattorit “k=20 f= kymmenen”. Virheen seurauksena ehtoa rikotaan ja muuttujan k arvo tuhoutuu. Koska ohjelma pysyy syntaktisesti oikein, kun looginen virhe esiintyy, kääntäjä ei huomaa virhettä. Palvelusanan "henkinen" pakollinen läsnäolon edellytys ehdon ja operaattorin välillä saa kääntäjän havaitsemaan syntaksivirheen ehdossa. Pakollinen puolipiste operaattoreiden välillä antaa kääntäjälle myös mahdollisuuden havaita virheen – puolipisteen puuttumisen operaattorin "k=20" jälkeen. Siten "sokeri"-merkkien läsnäolo, kuten mikä tahansa redundanssi kielessä yleensä, johtaa siihen, että koodin loogiset virheet muuttuvat syntaktisiksi ja kääntäjä voi havaita ne.

Alkuperä

Sanan syntaktinen sokeri loi Peter  J. Landin vuonna 1964 kuvaamaan yksinkertaisen Algol-kaltaisen kielen pintasyntaksia , joka on semanttisesti määritelty lambda-laskennan aplikatiivisilla ilmaisuilla , mitä seurasi puhtaasti leksikaalinen λ:n korvaaminen sanalla . where

Esimerkkejä

Matriisit C:ssä

C :n taulukot ovat muistissa olevia lohkoja . Matriisielementteihin päästään osoittimen kautta muistilohkon alkuun (eli taulukon alkuun) ja elementin siirtymän kautta aloitusosoitteeseen. Tämä voidaan kirjoittaa käyttämättä taulukoiden erityistä syntaksia ( a - osoitin taulukon alkuun, i - elementtiindeksi): *(a + i), mutta kieli tarjoaa erityisen syntaksin: a[i]. Mielenkiintoista on, että voidaan käyttää myös muotoa i[a], mikä on varsin loogista summausoperaation kommutatiivisuuden vuoksi.

Operaattoreiden uudelleenmäärittely

Operaattorin uudelleenmäärittely , jota monet ohjelmointikielet tukevat, voidaan myös selittää syntaktisen sokerin ansioksi . Periaatteessa mikä tahansa operaatio voidaan kehystää proseduuriksi (funktioksi, menetelmäksi). Operaattorin uudelleenmäärittelyn avulla voit suorittaa ohjelmoijan ulkoisesti luomia operaatioita samalla tavalla kuin kieleen sisäänrakennetut [3] [4] .

Ominaisuudet

Toinen esimerkki syntaktisesta sokerista on monien nykyaikaisten ohjelmointikielten tukema "ominaisuuksien" käsite. Tämä viittaa julistukseen pseudokenttien luokassa, jotka ulkoisesti käyttäytyvät kuten luokkakentät (joilla on nimi, tyyppi, sallivat määrityksen ja lukemisen), mutta todellisuudessa ne eivät ole. Kääntäjä kääntää jokaisen ominaisuuden pääsyn pääsymenetelmäkutsuksi. Ominaisuudet ovat täysin tarpeettomia (lisälaitteita voidaan kutsua myös suoraan) ja niitä käytetään puhtaasti mukavuuden vuoksi, koska ominaisuuksia käyttävä koodi näyttää hieman yksinkertaisemmalta ja selkeämmältä.

Kritiikki

Kaikki ohjelmoijat eivät pidä syntaktisen sokerin läsnäoloa ohjelmointikielissä ja sen käyttöä ohjelmoijien toimesta siunauksena. Niklaus Wirthin näkemys on tiedossa , jonka osa ohjelmointiyhteisöä jakaa: sen mukaan mikä tahansa kielen laajennus, joka ei johdu välttämättömyydestä, pahentaa sitä, koska se johtaa kääntäjän monimutkaisuuteen ja vastaavasti sen luotettavuuden ja suorituskyvyn heikkenemiseen. Samaan aikaan kielen oppimisen monimutkaisuus ja ohjelmien ylläpidon monimutkaisuus lisääntyvät. Lisäksi jo se, että syntaktisia lisätyökaluja on olemassa, on usein provosoivaa roolia: se rohkaisee ohjelmoijaa turvautumaan erilaisiin syntaktisiin temppuihin sen sijaan, että analysoiisi ongelmaa syvemmälle ja toteuttaisi tehokkaampia algoritmeja. Nämä näkemykset näkyvät Oberon -perheen kielissä , jotka ovat hyvin yksinkertaisia ​​ja käytännössä vailla syntaktista sokeria.

Tunnettu on Alan Perlisin aforismi : "Syntaktinen sokeri aiheuttaa puolipistesyöpää" . Puolipiste ( ), joka on pakollinen osa suosituimmista ohjelmointikielistä, vaikka se olisikin hyödytön uudessa kielessä, jätetään valinnaiseksi elementiksi, koska useimmilla ohjelmoijilla on vahva tapa käyttää sitä. Alkuperäisessä aforismi leikkii englanninkielisten sanojen semicolon ("semicolon") ja colon konsonanssilla , joista jälkimmäinen ei tarkoita vain paksusuolea, vaan myös paksusuolea ( paksusuolen syöpä  - "paksusuolisyöpä"). ;

Useimmiten kritiikki kohdistuu yksittäisiin, usein kohdatuihin syntaktisten sokerien tyyppeihin: uudelleenmäärittelytoimintoihin, ominaisuuksiin, monimutkaisiin operaatioihin (kuten ternäärinen ehdollinen operaatio ). Kriitikoiden väitteet kiteytyvät pohjimmiltaan siihen tosiasiaan, että tällaiset työkalut eivät itse asiassa tee ohjelmasta yksinkertaisempaa, selkeämpää, tehokkaampaa tai lyhyempää, mutta ne johtavat ylimääräiseen resurssien tuhlaukseen ja vaikeuttavat käsitystä, ja siis ohjelman ylläpito.

Syntaksisuola

Toisin kuin "syntaktinen sokeri", käsite " syntactic salt " ( englanniksi  syntactic salt ) [5] ohjelmoijien ammattikielessä viittaa teknisesti hyödyttömiin ohjelmointikielessä oleviin konstrukteihin, joita kielen säännöt edellyttävät suorittaessaan mahdollisesti vaarallista toimintaa. Toiminnot. Ne tuodaan kieleen vain siten, että ohjelmoija niitä käyttämällä vahvistaa, että kyseenalainen teko on hänen tietoisesti tehty, eikä se ole vahingossa tapahtunut virhe tai väärinkäsityksen tulos. Kuten "syntaktinen sokeri", "syntaktinen suola" ei laajenna kielen ominaisuuksia, eikä kääntäjä tarvitse sitä kääntääkseen ohjelman oikein; se on tarkoitettu yksinomaan ihmisille, jotka käyttävät tätä kieltä. Klassinen esimerkki tunnetusta ja laajalti käytetystä "syntaktisesta suolasta" ovat sisäänrakennetut tietotyyppien muunnoskomennot, jotka löytyvät melkein mistä tahansa staattisesti kirjoitetusta kielestä. Muodollisesti nämä komennot ovat tarpeettomia (kuten klassinen C osoittaa, jossa mikä tahansa tyyppimuunnos on sallittu ja tapahtuu automaattisesti), mutta kielillä, joissa niiden käyttö on pakollista, ohjelmoijan on pakko kiinnittää huomiota joka kerta, kun hän suorittaa mahdollisesti vaarallinen tyyppinen sekoitus, joka usein viittaa loogiseen virheeseen ohjelmassa. Ohjelmointikielen tarkkuudesta riippuen "syntaksisuolan" käyttö voi olla pakollista tai valinnaista. Ensimmäisessä tapauksessa kääntäjä näkee sen puuttumisen syntaksivirheenä, toisessa tapauksessa se antaa käännöksen aikana varoituksen, jonka ohjelmoija voi jättää huomiotta.

Toisin kuin "syntaktinen sokeri", joka laajentaa ohjelmoijan sananvapautta, "syntaktinen suola" kaventaa sitä vaatien "ilman syytä" kirjoittaa pitkiä rakenteita. Jargon File sanoo " syntaksisuola on huono, koska se nostaa hakkerin verenpainetta." Itse asiassa, kun kirjoitetaan pieniä yhden henkilön luomia ja ylläpitämiä ohjelmia, varotoimenpiteet voivat tuntua tarpeettomilta, mutta suurten ohjelmoijaryhmien tukemien suurten ohjelmistojärjestelmien teollisessa kehittämisessä, usein ei myöskään korkeimman pätevyyden omaavia, "syntaktinen suola" auttaa olla tekemättä virheitä kehityksessä ja ymmärtää muiden kehittäjien kirjoittamaa koodia tehokkaammin.

Esimerkkejä:

  • Delphin direktiivi osoittaa overridenimenomaisesti , että sillä merkitty menetelmä korvaa emoluokan virtuaalisen menetelmän. Tämän käskyn olemassaolo edellyttää kääntäjän tarkistavan, että ohitettujen ja ohitettujen menetelmien allekirjoitukset täsmäävät, joten jos perusluokissa tehdään muutos, ohjelmoijan on pakko tehdä samat muutokset jälkeläisluokissa, muuten ohjelma ei käänny.
On huomionarvoista, että C++ :ssa virtuaalimenetelmä korvattiin alun perin allekirjoitusten osuessa, mutta C++11-standardiin lisättiin direktiivi override, joka toimii samalla tavalla kuin Delphissä. Sen käyttö on valinnaista, mutta suositeltavaa turvallisuussyistä.
  • Toiminto C++reinterpret_cast : ssa tarjoaa vaarallisen tyyppimuunnoksen. Toiminto ei tuota koodia, se sallii ohjelmoijan vain ohittaa tyyppitarkistuksen. Sen ainoa käyttötarkoitus on suora osoitus siitä, että vaarallista tyyppimuunnosa on käytetty tarkoituksella.
  • Avainsana unsaferuosteessa funktioiden allekirjoituksissa ja ennen koodilohkoja.

Muistiinpanot

  1. Jack Crenshaw, "Let's Build a Compiler!", Syntactic Sugar -osio (downlink) . Haettu 21. huhtikuuta 2013. Arkistoitu alkuperäisestä 10. kesäkuuta 2015. 
  2. Syntaktinen sokeri . Haettu 25. tammikuuta 2015. Arkistoitu alkuperäisestä 22. toukokuuta 2015.
  3. Landin, 1964 .
  4. Abelson, Sussman, Sussman, 1996 , luku 1, alaviite 11.
  5. syntaktinen suola . Haettu 24. toukokuuta 2011. Arkistoitu alkuperäisestä 12. kesäkuuta 2003.

Kirjallisuus

  • Landin, Peter J. Ilmaisujen mekaaninen arviointi  . - Computer Journal, 1964. - Voi. 6 , ei. 4 . — s. 308–320 . - doi : 10.1093/comjnl/6.4.308 .
  • Abelson, Harold, Sussman, Gerald Jay, Sussman, Julie. Tietokoneohjelmien rakenne ja tulkinta. - MIT Press, 1996. - ISBN 0-262-51087-1 .
  • Benjamin Pierce. Tyypit ja ohjelmointikielet . - MIT Press, 2002. - S.  119-121 . — 645 s. — ISBN 0-262-16209-1 .

Linkit