Metaprogramiranje
Metaprogramiranje je pisanje računarskih programa sa mogućnošću da se tretiraju programi kao njihovi podaci. To znači da program bude dizajniran za čitanje, generisanje, analizu ili transformaciju drugih programa, pa čak i da se izmeni dok radi.[1][2] U nekim slučajevima, ovo omogućava programerima da se smanji broj linija koda da izraze rešenje (samim tim smanjuje vreme potrebno za razvoj) ili daje programima veću fleksibilnost da efikasno upravljaju novim situacijama bez rekompajliranja.
Jezik u kojem je metaprogram napisan se zove metajezik. Jezik programa koji se manipuliše se zove objektni jezik. Sposobnost programskog jezika da bude svoj metajezik zove se refleksija ili refleksivnost
Refleksija je vredna karakteristika jezika kako bi se olakšalo metaprogramiranjeg. Imajući programski jezik sam kao prve klase tipa podataka (kao u Lisp, Prolog, SNOBOL, REBOL, ili Io) je takođe veoma korisno; ovo je poznato kao homoikoničnost. Generičko programiranje poziva metaprogramski objekat u jeziku, na tim jezicima koji ga podržavaju.
Metaprogramiranje obično radi u jednom od tri načina. Prvi način je da razotkrije unutrašnjost run-time motora u kodu programiranja kroz aplikacioni programski interfejs (API). Drugi pristup je dinamičan izvršenju izraza koji sadrži programske komande, često sastavljene od žica, ali mogu biti i od drugih metoda koje koriste argumente ili kontekst.[3] Tako, "programi mogu pisati programe." Iako oba pristupa mogu da se koriste na istom jeziku, većina jezika imaju tendenciju da se oslone ka jednoj ili drugoj.
Treći način je da istupi iz jezika u potpunosti. Opšti cilj program transformacije sistema, kao što su prevodioci, koji prihvataju opise jezika i mogu da obavljaju proizvoljne transformacije na tim jezicima, su direktni implementatori opšteg metaprogramiranja. Ovo omogućava da se metaprogramiranje primenjuje u gotovo svakom ciljnom jeziku bez obzira da li je ciljani jezik bilo kog metaprogramiranja njegova sposobnost.
Pristupi
urediU statički tipiziranom funkcionalnom jeziku
uredi- Upotreba sistema zavisnih tipova omogućava dokazivanje da generisan kod nikada nije ispravan.[4]
Šablon metaprogramiranja
uredi- C preprocesorski makroi (
#define
) - C++ šabloni (funkcionalnosti poput
template
iconstexpr
)
Priređeno metaprogramiranje
uredi- MetaML
- MetaOCaml
Makro sistemi
uredi- Šema higijenskih makroa
- MacroML
- Template Haskell
IBM/360 asembler
urediIBM / 360 i derivati imali su moćne makro objekte koji su se često koristili za generisanje kompletnih programa ili delove programa (za različite operativne sisteme na primer). Makroi su opremljeni sa CICS sistemom za obradu transakcija koji ima makroa koji generiše COBOL izjave kao korak unapred za preradu.
Primeri
urediJednostavan primer metaprograma je Juniks ljuska skripta, koja je primer generativnog programiranja:
#!/bin/sh
# метапрограм
echo '#!/bin/sh' >program
for I in $(seq 992)
do
echo "echo $I" >> program
done
chmod +x program
Ova skripta generiše nov program koji sadrži 993 linije koja ispisuju brojeve od 1 do 992, i predstavlja jednostavan generator koda. Zavisno od složenosti programskog jezika ili okruženja, generator koda može biti više ili manje integrisan u proces kompilacije programa.
Kvajn je posebna vrsta metaprograma koji proizvodi sopstveni izvorni kod kao svoj izlaz.
Ne uključuju svi metaprogrami generativno programiranje. Ako su programi modifikovani u toku rada ili ako je postepena kompilacija na raspolaganju kao u C#, Fort, Frink, Gruvi, Javaskript, Lisp, Lua, Perl, PHP, Pajton, REBOL, Rubi, Smalltalk, i Tcl), a zatim tehnike mogu biti od koristi za obavljanje metaprogramiranja bez stvarnog generisanja izvornog koda.
Lisp je verovatno suštinski jezik sa objektima metaprogramiranja, kako zbog svog istorijskog prvenstva i zbog jednostavnosti i moći njenog metaprogramiranja. U Lisp metaprogramiranju je pod znacima navoda operater (obično zarez) uvodi kod koji se ocenjuje u programu vreme definicije nego vreme izvršavanja; pogledajte samo-evaluaciju oblika i citiranje u Lisp-u. Metaprogramski jezik je identičan domaćin u programskom jeziku, a postojeće Lisp rutine mogu direktno koristiti za metaprogramiranje, po želji.
Ovaj pristup je implementiran u drugim jezicima koji su uključeni od strane tumača u programu, koji radi direktno sa podacima programa. Postoje implementacije ove vrste za neke uobičajene jezike na visokom nivou, kao što su RemObjects’ Skriptni Paskal za Objektni Paskal.
Jedan stil metaprogramiranja je da zaposli oblasno specifičan jezik (DSLs). Prilično uobičajen primer korišćenja DSLs uključuje generativno metaprogramiranje: lex i yacc, dva alata koji se koriste za proizvodnju leksičkih analizatora i raščlanjivanje, neka korisnik opiše jezik pomoću regularnih izraza i kontekstno slobodne gramatike, i ugraditi složene algoritme potrebne za efikasno analiziranje jezika.
Implementacija
urediVidi još
urediReference
uredi- ^ Course on Program Analysis and Transformation.
- ^ Czarnecki, Krzysztof; Eisenecker, Ulrich W. (2000). Generative Programming. ISBN 978-0-201-30977-5.
- ^ for example, instance_eval in Ruby takes a string or an anonymous function.
- ^ Chlipala, Adam (2010). „Ur: statically-typed metaprogramming with type-level record computation” (PDF). ACM SIGPLAN Notices. PLDI '10. 45 (6): 122—133. doi:10.1145/1809028.1806612. Pristupljeno 29. 8. 2012.
Literatura
uredi- Czarnecki, Krzysztof; Eisenecker, Ulrich W. (2000). Generative Programming. ISBN 978-0-201-30977-5.
Spoljašnje veze
uredi- c2.com Wiki: Metaprogramming article
- Meta Programming
- Code generation Vs Metaprogramming Arhivirano na veb-sajtu Wayback Machine (16. septembar 2020)
- "Solenoid": Prvi metaprogramski okvor za eXist-db
- The Art of Enterprise Metaprogramming