Nyelvorientált programozás (LOP) ( English Language Oriented Programming ), szintén Divergens fejlesztés ( angol középső fejlesztés ), szintén metanyelvi absztrakció , továbbá Domain-specifikus nyelvre épülő fejlesztés ( angol DSL - Based Development ) [1] - programozási paradigma , amely abból áll, hogy a szoftverfejlesztési folyamatot felosztják a domain -specifikus nyelvek (DSL) fejlesztési szakaszára, és ezek segítségével leírják a probléma tényleges megoldását. A szakaszok végrehajthatók szekvenciálisan vagy párhuzamosan, egyszer vagy rekurzívan [2] [1] ; A DSL-ek az alapnyelvtől függetlenül vagy attól függetlenül is megvalósíthatók, és egy vagy több implementációjuk van.
A LOP a bonyolultságok szétválasztására készült: a kód géporientált része (alacsony szintű funkcionalitás) és az emberközpontú része (az alkalmazott probléma tényleges megoldása) egymástól függetlenül fejlődik, ami kiküszöböli a kód exponenciális növekedését. a teljes projekt kidolgozásának összetettsége, és megoldja a komplexitás problémáját, mint alapvető programozási problémát [2] , amelyet Frederick Brooks a „ Nincs ezüstgolyó” című híres esszéjében írt le , ami miatt lehetetlen növelni a programozók termelékenységét. akár egy nagyságrenddel is pusztán a munkaeszközök javításával. A legtöbb egyéb előny közvetlenül ebből következik .
A nyelvi specializáció szűkítésének érdemeiről már az 1980- as évek közepén szó esett [3] , a nyelvi szint emelésének érdemeiről pedig jóval korábban [4] , de önállóan kialakult a DSL-orientált fejlesztés. módszertanát csak az 1990 -es évek közepére .
A DSL-ek használata az általános célú nyelvek helyett nagymértékben növeli a kódabsztrakció szintjét, ami lehetővé teszi a gyors és hatékony fejlesztést, valamint könnyen érthető és karbantartható programok létrehozását; valamint lehetővé teszi vagy jelentősen leegyszerűsíti számos, a programok manipulálásával kapcsolatos probléma megoldását (programok generálása, a programok egy bizonyos tulajdonságának vizsgálata - helyesség, hatékonyság stb.) [3] [1] [5] [ 6] . Másrészt egy új nyelv kidolgozása és hatékony megvalósítása az elméleti és alkalmazott informatika nem triviális problémája .
A programtervezés egyéb megközelítései közül a LOP kiemelkedik azzal, hogy sokkal agresszívebben összpontosítja a számítógépet az emberhez. A LOP kutatói körében az a vélemény alakult ki, hogy a tudományintenzív feladatokban egy jól megtervezett és megvalósított DSL sokkal kényelmesebbé és hatékonyabbá teszi az ember-számítógép kommunikációt, mint egy grafikus felhasználói felület . A leggyakrabban idézett példák a következő népszerű domain-specifikus nyelvek :
satöbbi.
A LOP előnyei akkor is megjelennek, ha a DSL-t nem tömeges felhasználásra, hanem egyetlen feladat megoldására fejlesztették ki. Például a FermaT programok automatikus ekvivalens konvertálására szolgáló rendszer kifejlesztésekor a Lisp -beli „lapos” programozásról a rekurzív LOP-ra való átállás (a WSL Lisp -en, a MetaWSL pedig rajta volt, és a célfunkció már be volt kapcsolva ez) nemcsak lehetővé tette a kód teljes mennyiségének 100-ról 16 ezer sorra való csökkentését, de ugyanakkor növelte a kód összes fő minőségi jellemzőjét , sőt lehetővé tette olyan problémák megoldását is, amelyeket másként nem lehetne megoldani [2] .
A munkaerőköltségek növekedésének egyszerűsített összehasonlítása a hagyományos és a nyelvorientált megközelítések alkalmazásával lehetővé teszi az [1] grafikont . Mint látható, a LOP csak a célrendszer funkcionalitásának egy bizonyos volumen- és összetettségi küszöbétől kiindulva célszerű.
A legtöbb LOP-kutató a funkcionális nyelvekre és metanyelvekre támaszkodik , ami magas belépési küszöbhöz vezet a fejlesztők számára. Martin Ward felhívja a figyelmet a DSL bevezetésének lehetőségére a hagyományos nyelveken, de csak a végleges fejlesztés után.
A fősodorban gyakran alkalmazzák a tolmács beágyazását egy általános célú nyelvbe (lásd a Megközelítést ), bár ez nemcsak a LOP elveire való hivatkozás nélkül történik, hanem gyakran anélkül, hogy felismernék az alkalmazás tényét. Leggyakrabban beágyazott: reguláris kifejezési nyelv ( PCRE interpreter ), Lua , SQL , XML . Egy vizuális programozási eszköztárat is kifejlesztettek a LOP egyes ötleteinek általános felhasználására.
Sok kutató úgy látja, hogy a LOP célja teljesen elmosni a határokat a matematikai modell és annak számítógépen való megvalósítása között, és lehetővé teszi a szoftverfejlesztést olyan témaspecialisták által, akik nem rendelkeznek specifikus programozási ismeretekkel [1] [6] :
-- проверка вхождения точки в регион:
inRegion :: Point -> Region -> Bool
p ‘inRegion‘ r = r p
...
A tartomány szemantikájának pontos rögzítésével még a nem programozók is képesek megérteni a kód nagy részét. A Naval Surface Warfare Center megbízásából végzett kísérletben a Haskellt teljesen ismeretlen emberek menet közben felfogták az alapfogalmakat. Néhányan hitetlenségüket fejezték ki azzal kapcsolatban, hogy ez a kód valóban végrehajtható.
(Valójában ennek az utolsó mondatnak a szövegben való jelenléte ellenére a mű első vázlatának egyik lektora elégedetlenségét fejezte ki amiatt, hogy „a műről azt állítják, hogy mind a szintaktikai, mind a szemantikai diskurzus, de tartalma főként a szintaxissal foglalkozik (mint például a definíció inRegion), és nem tesznek különbséget a matematika és a programozás között . Valójában azonban ez a definíció inRegionteljesen szemantikai. Ráadásul az egyenletalapú érvelés [7] ... lehetővé teszi a határvonal a matematika és a programozás között: a programok specifikációnak tekinthetők. Ez azért különleges, mert kiterjeszti a formális módszerek alkalmazását.)
A megközelítés azon az elgondoláson alapszik, hogy egy speciálisan egy adott feladatra tervezett nyelv nyilvánvalóan magasabb kódminőségi mutatókat ad , mint bármely általános célú nyelv [1] [6] , és hogy összetett ipari problémák megoldására hatékonyabb lesz feltalálni. könnyebben érthető (emberorientált [8] vagy pontosan beágyazó tantárgyi ismereteket [2] [1] ) nyelv, ahelyett, hogy leküzdeni a meglévő, akár az iparban gyökerező [4] használatának nehézségeit .
A legtöbb kutató úgy beszél a LOP-ról, mint a teljes szoftverfejlesztő ipar átmenetéről a 4. és 5. generációs szövegalapú nyelvek használatára [8] , de vannak, akik a vizuális nyelvek használatára helyezik a hangsúlyt [9] [10 ] ] .
A megközelítés fő problémája az, hogy megtalálja a módját a feltalált DSL implementációjának gyors elkészítésének , hogy megkezdődjön a probléma tényleges megoldásának kidolgozása, valamint a DSL jó számítási teljesítményének biztosítása .
A tartományspecifikus nyelveket, mint általában minden programozási nyelvet, az ábécé , a nyelvtan , a szemantika és a pszicholingvisztika határozza meg , azonban a DSL megvalósítási módjától függően ezeknek a szinteknek a szerepe és kapcsolata elmosódhat és/vagy öröklődik végrehajtásának nyelve.
A különböző szerzők a tartományspecifikus nyelvek fejlesztésének különböző módjait hangsúlyozzák:
A makróeszközök használatakor viszont különbséget kell tenni a sablon metaprogramozás és a többlépcsős statikus értelmezés között [13] [17] [18] [5] .
A harmadik és a negyedik módszer alapvető előnye az első kettőhöz képest - a DSL nem helyettesíti, hanem kiterjeszti az általános célú nyelvet [14] [1] [19] [20] , újrafelhasználva a teljes alapnyelvi eszközkészletet, kezdve az elemzővel , ami miatt:
Sok szerző bizonyos kezdetben hiányzó tulajdonságok hatékony (értelmezés nélküli) nyelvbe ágyazására összpontosít bizonyos feladatokhoz való alkalmazkodás érdekében [15] [16] , amely később a tiszta DSL beágyazás alapjául szolgálhat [21] . Jelentős figyelmet fordítanak a folytatások használatára a nem determinisztikus szemantikával rendelkező DSL-ek fejlesztéséhez ( Steel , Wend , Felleisen , Ramsey , Reppy és mások).
A LOP egyik fontos alfaja a felhasználói programozás , amely lehetővé teszi számos olyan ember számára, akiknek fogalmuk sincs a számítástechnikáról, hogy hatékonyan oldjanak meg számos alkalmazott problémát. A LOP ezen alkalmazásának olyan nagy szerepe van, hogy a gyakorlatban a világ talán legelterjedtebb programozási nyelve a táblázatkezelő eszközök ( eng. tablesheets ) [6] .
A " metaprogramozás " (MP) kifejezés értelmezésétől és a DSL megvalósítási módjától függően vagy a LOP az MT kvintesszenciája, vagy az MT a LOP megvalósításának egyik módja. Ez utóbbi lehetőség leginkább abban az esetben alkalmazható, ha a DSL-t egy általános célú nyelvbe ágyazzák be az utóbbi makró részhalmazán keresztül [13] . A DSL vizuális fejlesztő eszközök [9] [10] használatakor ezek a definíciók szinonimák, mert Maga a vizuális programozás az MT legegyszerűbb formája. Ha az MT -t a LOP önalkalmazásának tekintjük :
Független fordítók fejlesztésére széles körben használják a lexer és elemző generátorokat a cél DSL nyelvtanának BNF és reguláris kifejezések segítségével történő meghatározása alapján :
és mások.
Független DSL fordításakor ritkán natív kódot vagy akár assemblert választanak célplatformnak , célszerűbb (mind a DSL megvalósításának bonyolultságának csökkentése, mind a hordozhatóság növelése érdekében) magasabb szintű platformot használni:
A következő technológiákat használják a DSL beágyazására egy általános célú nyelvbe:
A tiszta beágyazás nem igényel további eszközöket, de meglehetősen szigorú korlátozásokat támaszt az alapnyelv kiválasztásában .
Többlépcsős statikus értelmezés alkalmazásakor a célplatform megegyezik az alapnyelvvel [13] [17] [18] [5] .
A hagyományos programozás keretein belül (az Algoltól örökölt nyelveken ) a LOP egyes ötleteinek felhasználása teszi lehetővé a 2000-es évek első felében kifejlesztett vizuális programozási eszköztárat [9] [10] [27] [ 28] :
A Lisp nyelvi közösségben szinte a létrehozása pillanatától kezdve gyakorolták a makróeszközök használatát, hogy alkalmazkodjanak a probléma tárgykörének követelményeihez. Ezt a megközelítést különösen a The Structure and Interpretation of Computer Programs című könyv ismertette részletesen . Hasonló gondolatokat alkalmaztak időnként a Forth nyelvi közösségben is . Ezek a döntések alapvetően spontán jellegűek voltak, és gyakran ad hoc döntések közé sorolhatók [13] .
Az 1970-es évek második felében feltalálták a Hindley -Milner típusú rendszert , amely az ML nyelv ( a MetaLanguage rövidítése ) alapját képezte . Az ML -t eredetileg DSL - ként tervezték az LCF - tételbizonyító rendszerhez , de hamar világossá vált, hogy jó általános célú alkalmazott nyelv lehet – jobb, mint az eredetileg általános célú nyelveknek tervezett nyelvek. hibakeresés egy speciális összetett problémán [30] [31] . Következésképpen X-M-típusú nyelvek egész családját hozta létre , amelyek népszerűségre tettek szert a nyelvi fejlesztés nyelveiként ( metanyelvek ), és gyakran „ DSL-ként a denotációs szemantika ” -ként definiálják [1] .
1994 -ben Martin Ward [ 32] részletes leírást adott a módszertanról [2] , és javasolta a „ nyelv-orientált programozás ” és a „ divergens fejlesztés ” (vagy „ a középponttól a szélek felé történő fejlesztés ”, középső fejlesztés ) kifejezéseket. megjegyezve, hogy ezt a megközelítést – különféle formákban – korábban is sokszor alkalmazták. A „ divergens fejlesztés ” kifejezés azt hangsúlyozza, hogy a kialakuló rendszerben a középső réteg ( középréteg ) a kifejlesztett DSL, szemben a korábban ismert és ma is széles körben használt „ alulról felfelé irányuló fejlesztés ” módszereivel ( alulról felfelé fejlesztés ). " top down development " ( top down development ) és " konvergáló fejlesztés " ( oside in development ), amely ezeket egyesíti.
Ward azt is javasolta, hogy a LOP rekurzív módon használjuk, fokozatosan növelve a fejlesztés alatt álló rendszer bonyolultságát alulról felfelé; és kombinálja a LOP-t a gyors prototípuskészítéssel úgy, hogy először kifejleszti a legegyszerűbb DSL prototípust (ami nagyon gyorsan kivitelezhető) és a legegyszerűbb megoldást használja, majd a nyelv tesztelése, a hibák azonosítása és a követelmények tisztázása után finomítja a DSL-t, és átírja a megoldást a nyelv új verziója, és így tovább iteratív módon.
Paul Hudak egy tiszta beágyazási módszertjavasolt [1] , amely típusbiztos nyelveket használ(lehetőleg lusta nyelveket, mint a Haskell , de esetleg szigorúakat, mint az ML , bár az utóbbi esetben a megvalósítás kissé körülményesebb és kevésbé természetes ) és egyenletalapú gondolkodás [7] a rendszer rekurzív fejlesztésével felülről lefelé, és újrafelhasználható kód felhalmozásával "DSL DSL fejlesztéshez" formájában.
A tiszta beágyazási módszer adta az "embedded domain-specific language" kifejezést ( eng. Embedded DSL, EDSL ; néha DSEL ) [1] [8] . Számos Haskell feletti EDSL-t fejlesztettek ki pusztán funkcionális stílusú interaktív, valós idejű alkalmazások (Fran, Fruit, FRP és RT-FRP, FAL, Frob, Fvision, Yampa) [33] [19] programozására , amelyek függetlent alkottak. paradigma - funkcionális reaktív programozás (FRP). Ez azt mutatja, hogy a LOP nem egy különálló zárt programozási paradigma, hanem éppen ellenkezőleg, eszközként használható új paradigmák fejlesztésében.
A szabványos ML , az ML alapdialektusa az 1990-es évek eleje óta vita tárgyát képezi a makrofunkciók hiányával kapcsolatban [30] . A kritikusok azzal érveltek, hogy a makrók hiánya hátrány, de az erős gépírók kifogásolták, hogy hiányuk csak előny. Az ML egy másik dialektusában - OCaml - egy kompromisszumos ötletet javasoltak - szintaktikai paraméterezést az elemző kibontásával egy egyéni CamlpX fordítómodulba, amelyen keresztül EDSL-készletet fejlesztettek ki az OCaml számára. Később megjelent egy kiterjesztése a futás közbeni kód generálására - MetaOCaml . Az 1990-es évek végén a típusbiztos makrók ötletét javasolták a típusbiztos DSL-ek hatékony megvalósításának eszközeként [34] . Ezt az ötletet hamarosan MetaML kiterjesztésként [13] [17] [18] valósították meg a Standard ML -hez és Template Haskell [35] a Haskellhez . Az első esetben a makróeszközöket kizárólag többlépcsős statikus értelmezőnek tekintjük; a másodikban ugyanannak a megközelítésnek és a Lisp nyelvből ismert kvázi-idézetnek , valamint a C++ nyelvben elérhetőhöz hasonló sablon alrendszernek tekintik őket .
Az ilyen megközelítések különböző nyelveken való megvalósításának és alkalmazásának lehetőségét vizsgáló tanulmány kimutatta, hogy a C ++ rendkívül kényelmetlen eszköz a beágyazott nyelvek fejlesztéséhez [36] . Ennek ellenére a C++ lehetővé teszi az ilyen irányú megoldások megvalósítását , amelyeket a funkcionális programozás [5] [37] égisze alatt művelnek és hibáztatnak , ami ritka előny a mainstream nyelvek számára [5] .
A 2012 -ben publikált előzetes kutatási adatok azt mutatták, hogy a független DSL használata kényelmesebb, míg az EDSL könnyebben megvalósítható [8] .
Bármely szoftverrendszer komplexitásának növekedését alapvetően korlátozza az a határ, ameddig még fenntartani lehet felette az irányítást: ha a rendszer egy összetevőjének megértéséhez szükséges információ mennyisége meghaladja az ember agyának „kapacitását”. személy, akkor ez az összetevő nem lesz teljesen érthető. Ennek finomítása vagy a hibák kijavítása rendkívül nehézzé válik, és minden javítás várhatóan újabb hibákat vezet be e hiányos ismeretek miatt.
Eredeti szöveg (angol)[ showelrejt] Bármely szoftverrendszer bonyolultságának alapvető korlátja van ahhoz, hogy továbbra is kezelhető legyen: ha több mint "egy agynyi" információra van szükség a rendszer egy összetevőjének megértéséhez, akkor azt az összetevőt nem fogják teljesen megérteni. Rendkívül nehéz lesz fejlesztéseket végrehajtani vagy hibákat kijavítani, és minden javítás valószínűleg további hibákat vezet be a hiányos ismeretek miatt. – Martin Ward, „Language Oriented Programming” [2]A LOP számos előnnyel rendelkezik a hagyományos "lapos" fejlesztéssel szemben [2] :
A nyelvek megvalósítása független fordítók fejlesztésével rutinfeladat, hiszen kiterjedt formai bázis és az arra épülő eszközök halmozódtak fel ( Lex/Yacc , ANTLR , Parsec [22] ). Például a Parsec-en az egyszerű nyelvtannal rendelkező ( pascal Wirth-féle nyelvtanhoz hasonló ) nyelvek értelmezőinek fejlesztése munkaórák alatt történik [38] [39] .
A nyelvorientált programozásnak két fő hátránya van a hagyományos programozáshoz képest, amelyek azonban nem alapvetőek: a nyelvfejlesztők számára magas belépési küszöb (a módszertan előnyeinek többségének feladása árán csökken) és a számítási teljesítmény biztosításának nehézsége. . Mindkét hiányosság csak a tartományspecifikus nyelvek fejlesztői számára releváns; a nyelv használói (alkalmazásspecialisták) nettó előnyhöz jutnak.
KorlátozásokAz új nyelvek fejlesztéséhez jó elméleti háttér, valamint szemantikailag különböző nyelvek és azok kiterjesztései folyékony ismerete szükséges. Martin Ward megjegyzi, hogy egy olyan jó nyelv megtervezése, amely képes kielégíteni a felhasználók igényeit és hosszú életciklussal rendelkezik, összetett feladat, amely magas fokú számítástechnikai műveltséget igényel , és azt javasolja, hogy a programozók folyamatosan gyakorolják a nyelvfejlesztést, hogy elegendő gyakorlati tapasztalatot szerezzenek. Emellett felhívja a figyelmet arra, hogy a LOP célja nem a fejlesztők belépési küszöbének csökkentése, hanem éppen ellenkezőleg, a képzett fejlesztők munkájának felhatalmazása, egyszerűsítése – és ez már a jövőben a belépés csökkenéséhez vezet. küszöbérték a rendszer felhasználói számára, amely a használatához és fejlesztéséhez szükséges.
A DSL általános célú nyelvekbe való beágyazásának módszerei messze nem alkalmazhatók egyetlen nyelven sem, mivel megkövetelik az alapnyelv szemantikájának bizonyos tulajdonságait különféle kombinációkban: alkalmazó hívásmodell , valóban polimorf típusrendszer vagy dinamikus tipizálás (lásd polimorfizmus ), magasabb rendű függvények , folytatások , fejlett makrokiterjesztési alrendszer, reflexivitás , lustaság . Ezek a tulajdonságok kezdetben nem érhetők el (vagy teljes mértékben megvalósíthatók) semmilyen nyelven. Leggyakrabban mindkét módszert és azok kombinációit olyan nyelvek dialektusaiban használják, amelyek tipizálatlan és tipizált lambda-számításon (a szemantika leírásának matematikai modellje) alapulnak, néha nem szabványosított specifikus kiterjesztéssel: Common Lisp , Scheme , Standard ML , MetaML [ 13] , Alice , OCaml , MetaOCaml , Haskell , Sablon Haskell , Nemerle . Ezek a módszerek a Forth nyelvben is alkalmazhatók , bár a Forth fejlesztők viszonylag ritkán használják őket. Mindezek a nyelvek magas belépési küszöbértékkel rendelkeznek. Egyes szerzők megjegyzik a harmadik módszer alkalmazásának lehetőségét a mainstream C++ -ban, de a C++ LOP-hoz való alkalmasságát bírálták [36] .
A vizuális DSL-fejlesztés [9] [10] alacsony belépési korláttal rendelkezik, de feláldoz számos Ward, Hudak és mások által leírt LOP-funkciót:
A „hanyag” DSL megvalósítás számítási teljesítménye alacsony lehet, a jó optimalizálás pedig indokolatlanul költséges lehet. Természetesen egyes DSL-ek céljából adódóan a sebesség nem alapvető fontosságú számukra ( Τ Ε Χ , AutoLisp ). Más esetekben ez mind a megvalósítási módtól, mind a megcélzott fordítási platformtól függ, és sok esetben nagyon jó eredményeket lehet elérni. Waleed Taha például leírja [40] az FRP nyelvi fordító implementációját imperatív C kód generálásának módszerével , amellyel valós idejű alkalmazásokat fejlesztettek ki a 16 bites PIC16C66 mikrokontrollerhez [41] . Hudak rámutat [1] , hogy a Haskell többlépcsős, modulárisan beépített DSL-megvalósításai (lásd a Megközelítést ) rendkívül lassúak, mivel minden egyes absztrakciós réteg 15-70-szeres lassulást ad – de a szuperfordítási technikák alkalmazása miatt, a sebesség három nagyságrenddel visszavehető (400-ról 2800-ra).
Lehetőség van a magasabb szintű logikában használt tervek optimalizálására tervezett DSL fejlesztésére. Például az OL (Operator Language) nyelvet [42] a matematikai algoritmusok platformfüggetlen leírására, valamint a nagy teljesítményigényű matematikai könyvtárak új architektúráira történő portolásának egyszerűsítésére fejlesztették ki (lásd a számtörőt ). A fordítót a processzor architektúrájára vonatkozó adatok (vektorműveletek támogatása, magok száma stb.) paraméterezik, és néha automatikus összehasonlító tesztelést hajt végre a megvalósítási lehetőségek közül a leggyorsabb kiválasztásával. Ennek eredményeként egy szupermagas szintű deklaratív nyelvű program nagyon hatékony (a kézzel írthoz hasonlítható) C kódot generál, amely az algoritmust a leghatékonyabb módon valósítja meg egy adott architektúra esetén. Ilyenkor a bemeneti adatok méretének szigorítása is a hatékonyság összetevőjévé válik - például gyorsfüggvény építhető 8x8-as mátrixok szorzására.
A beágyazható DSL -ek használata olyan nyelveken, amelyekhez léteznek globálisan optimalizáló fordítók (mint például a Stalin Scheme , MLton ), lehetővé teszi a nyelvspecifikus feladatok lebontását a hatékonyság elvesztése nélkül más tervezési megközelítésekhez képest, de korlátozhatja a kifejlesztett DSL . Ez az irány számos tanulmány tárgya.
Mindezek a megoldások magánjellegűek, és mindegyikük alkalmazhatósága minden szinten a kifejlesztett DSL jellegétől függ, vagy fordítva, speciális követelményeket támaszt vele szemben. Így a projekt architektúrájának és a megvalósítás hatékonyságának összefüggése a LOP probléma szerves része. Ez más tervezési megközelítésekre is igaz, de jóval kisebb mértékben.