Metaprogramozás
programozási paradigma From Wikipedia, the free encyclopedia
Remove ads
A metaprogramozás egy programozási módszer, amiben a számítógépes programok adatokként kezelnek programokat. Ez azt jelenti, hogy a program olvas, generál, elemez, transzformál egy másik programot, vagy futás közben módosítja önmagát.[1][2] Bizonyos esetekben ez lehetővé teszi, hogy a forráskód rövidebb legyen, ami lerövidítheti a fejlesztés idejét.[3] Néha ez utóbbi fordítva van, de a program rugalmasabbá válik abban, hogy újrafordítás nélkül is kezeljen új helyzeteket.
Használható arra is, hogy egyes számításokat a futásidőből áttegye fordítási időbe, és saját magát módosító kódot hoz létre. A nyelv, amin metaprogramozást végeznek, metanyelv. A manipulált program nyelve a tárgynyelv. A reflexió a programnyelvnek az a képessége, hogy önmaga metanyelve legyen.[4] A reflexió értékes eszköz a metaprogramozás támogatására.
Remove ads
Megközelítések
A metaprogramozás lehetővé teszi generikus kód fejlesztését. Nagyon hasznos, ha a nyelv képes első osztályú adattípusként kezelni saját magát, mint a Lisp, Prolog, SNOBOL, vagy Rebol nyelvek. A generikus programozás lehetővé teszi, hogy úgy lehessen kódolni, hogy nem specifikáljuk előre, hogy az milyen típusra vonatkozik, mivel azokat paraméterként fogják helyettesíteni használatkor.
Többnyire a következő módok valamelyike áll a metaprogramozás mögött:[5]
- Futásidőben elérhető a futtató környezet belseje a futtatott kódból egy API-n keresztül. Ilyen a .NET IL kibocsátó.
- Programkódot tartalmazó kifejezések dinamikus végrehajtása. A kódot gyakran karakterláncokból állítják össze, de másként is létrehozható paraméterekből és környezetből, mint például JavaScript.[* 1] Így program ír programot.
Habár a legtöbb nyelv mindkét módszert lehetővé teszi, többnyire elmennek az egyik vagy a másik irányba.
A harmadik megközelítés szerint a nyelvet teljesen kívülről nézik.[5] Az általános célú programtranszformációs rendszerek a generikus metaprogramozás közvetlen implementációi, például azok a fordítók, amelyek fogadják a nyelv leírását, és bármely transzformációt elvégeznek ezeken a nyelveken. Ez lehetővé teszi, hogy bármely célnyelvre alkalmazható legyen a metaprogramozás, függetlenül attól, hogy vannak-e eszközök, amelyekkel az adott nyelven metaprogramozást lehet végezni. Ezt láthatjuk működni a Scheme programozási nyelvvel, valamint azzal, hogyan lehet túllépni a C korlátain a Scheme nyelv szerkezeteinek segítségével.[7]
Remove ads
Példák
Egy egyszerű példa ez a shell szkript, ami a generatív programozás egy példája:
#!/bin/sh
# metaprogram
echo '#!/bin/sh' >program
for I in $(seq 992)
do
echo "echo $I" >> program
done
chmod +x program
A szkript egy 993 soros programot hoz létre, ami kiírja a számokat 1-től 992-ig. Ez ugyan nem hatékony módszer, csak bemutatja, hogyan lehet kódot generálni. Viszont a programozó egy perc alatt megírhatja, ezzel ennyi idő alatt 1000 sort generálva.
A quine egy speciális metaprogram, ami önmagát hozza létre. Egyes nyelvekben az üres program érvényes program, ezért ez a legkisebb quine az ilyen nyelveken. Ezek a programok csak tudományos jelentőséggel bírnak. 1994-ben az üres program nyerte el A legrosszabb visszaélés a szabályokkal díjat az International Obfuscated C Code Contest (IOCCC) versenyen.[8]
Nem minden metaprogram használ generikusságot. A futásidejű önmódosítás vagy az inkrementális fordítás lehetősége is felhasználható anélkül, hogy aktuálisan forráskódot generálnának. Ezeket is sok nyelv támogatja, mint C#, Forth, Frink, Groovy, JavaScript, Lisp, Lua, Perl, PHP, Python, REBOL, Ruby, Smalltalk, és Tcl.
A metaprogramozásra a Lisp nyújtja a legtöbb lehetőséget. Az unquote operátor (tipikusan a vessző) által bevezetett programszakasz definiálási időben hajtódik végre. Így a metaprogramozás nyelve ugyanaz, mint a gazdanyelv, és már létező Lisp rutinok közvetlenül használhatók metaprogramozáshoz. Más programnyelvek ezt egy értelmező beépítésével oldják meg, ami közvetlenül a program adatait elemzi. Néhány gyakran használt nyelv számára vannak ilyen implementációk, például a RemObject Pascal Scriptje az Object Pascal számára.
A metaprogramozás egy megközelítése a beágyazott nyelvek (DSL) használata. A lex és a yacc a generikus metaprogramozást szolgálja, és lexikai elemzőket és parsereket generálnak. A felhasználónak csak a megfelelő szabályos kifejezéseket és környezetfüggetlen nyelvtanokat kell megírnia, meg a nyelv hatékony parszolását végző algoritmusokat implementálnia.
Remove ads
Támogatás és kihívások
A metaprogramozás haszna az, hogy felgyorsíthatja a fejlesztést, és növeli azoknak a programozóknak a teljesítményét, akik megtanulták és begyakorolták. Néhány elemzés szerint meredek a tanulási görbe, ameddig a fejlesztő megtanulja a metaprogramozás teljes eszközkészletét, és felgyorsul.[9] Mivel nagyobb hatékonyságot és rugalmasságot ad futásidőben, hibás használata vagy a vele való visszaélés váratlan hibákat eredményezhet mindenféle figyelmeztetés nélkül, amelyeket nehezebb észrevenni és javítani. Ha nem elég körültekintően használják, akkor sérülékenyebbé teszi a rendszert. Ezek egy részét egy megfelelő fordító meg tudná előzni, ha legalább figyelmeztet a hiányzó paraméterekre, az érvénytelen vagy inkorrekt adatokra, amelyek a kívánttól eltérő eredményeket vagy ismeretlen típusú kivételeket okozhatnak.[10] Éppen ezért egyes kritikusok szerint csak képzett és tapasztalt programozóknak lenne szabad megengedni azt, hogy metaprogramozást támogató eszközöket hozzanak létre egy nyelvhez vagy környezethez, és a többi programozónak először egy konvenció részeként kell megtanulnia, hogyan bánjon velük.
Felhasználása különböző nyelvekben
Makrórendszerek
- Scheme higiénikus makrók
- MacroML
- Template Haskell
- Scala makrók
Makró assemblerek
Az IBM/360 és továbbfejlesztései fejlett makró assembler lehetőségekkel bírtak, amelyeket gyakran használtak arra, hogy egész Assembly programokat generáljanak [forrás?] vagy programszakaszokat hozzanak létre például különböző operációs rendszerek számára. A CICS tranzakciófeldolgozó rendszer assembler makrói COBOL utasításokat generáltak előfeldolgozó lépésként.
Más assemblerek, például az MASM, is támogatnak makrókat.
Metaosztályok
Metaosztályokat tartalmaznak a következők:
- Python
- Nil
- Groovy
- Ruby
Template metaprogramozás
- C "X Makrók"
- C++ sablonok
Staged metaprogramozás
- MetaML
- MetaOCaml
Függő típusokkal
- A függő típusok használata kizárja, hogy érvénytelen kód jöjjön létre.[11] Azonban ez a megközelítés bleeding-edge, és ritkán lehet vele találkozni a kutatási célokra készült nyelveken kívül.
Remove ads
Implementációk
- ASF+SDF Meta Environment
- DMS Software Reengineering Toolkit
- Joose (JavaScript)
- JetBrains MPS
- Moose (Perl)
- Nemerle
- Rascal Metaprogramming Language
- Stratego/XT
- Template Haskell
Megjegyzések
Hivatkozások
Fordítás
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads