Метапрограмиране

от Уикипедия, свободната енциклопедия
Направо към навигацията Направо към търсенето

Метапрограмиране[редактиране | редактиране на кода]

Метапрограмирането представлява писане на компютърни програми с възможност програмите да се третират като техни данни. Това означава, че една програма може да бъде написана да чете, генерира, анализира или трансформира други програми, може дори да променя сама себе си по време на изпънение.[1][2].

В някои случаи това позволява на програмистите да намалят броят на редовете код, за да изпълнят решението (оттук се намалява и на времето за писане на код), или дава на програмите по-голяма гъвкавост за по-ефикасно справяне с нови ситуации, без прекомпилиране.

Езикът, на който се пише метапрограмата, се нарича метаезик. Езикът на програмите, които биват манипулирани, се нарича обектен език. Способността на програмния език да бъде свой собствен метаезик се нарича рефлексия или рефлексивност.

Рефлексията е ценна за езика функция, която се прилага, за да се улесни метапрограмирането. Наличието на програмния език като first-class data type (както в Lisp, Prolog, SNOBOL, или REBOL) също е много полезно; това е известно като homoiconicity. Общото програмиране извиква функцията на метапрограмирането, за тези програмни езици, които го поддържат.

Метапрограмирането обикновено работи по един от следните три начина. Първият начин представлява излагане на съставните части на рънтайм енджина на програмния код, чрез използване на приложно-програмни интерфейси. Вторият подход представлява динамично изпълнение на изрази, които съдържат в себе си програмни команди, често съставени от низове или от други методи, използващи аргументи или контекст[3]. По този начин, „програмите могат да пишат програми.“ Въпреки, че и двата подхода могат да се използват в един и същ програмен език, при повечето езици се наблюдава тенденцията да клонят или към единия, или към другия.

Третият подход е излизане изцяло извън рамките на програмния език. Системите за трансформиране на програми с общо предназначение, каквито са например компилаторите, представляват директни имплементации на метапрограмирането. Това дава възможност метапрограмирането да бъде прилагано на почти всеки програмен език, без значение дали този език притежава свои собствени метапрограмни способности.

По този начин метапрограмирането е идентично с езика за програмиране домакин, и съществуващите Lisp съчетания могат директно да се използват повторно за метапрограмиране. Този подход е приложен и в други езици, чрез включване на интерпретатор в програмата, който работи директно с нейните данни. Има приложения от този вид за някой често срещани езици от високо ниво, като RemObjects’ Pascal Script за Object Pascal. Един от стиловете на метапрограмирането е да се използват domain-specific languages (DSLs). Доста често срещан пример за използване на DSLs включва генеративно метапрограмиране: lex и yacc – два инструмента, използвани за генериране на lexical analyzers и parsers, позволяващи на потребителите да се пише на езика, с помощта на регулярни изрази, context-free grammars и вграждане на сложни алгоритми, необходими за ефективното анализиране на езика.

Примери[редактиране | редактиране на кода]

Прост пример за метапрограма:

#!/bin/sh
# metaprogram
echo '#!/bin/sh' >program
for I in $(seq 992)
do
        echo "echo $I" >> program
done
chmod +x program

Този код (или програма) генерира програма на 993 реда, която принтира числата от 1 до 992. Това е само пример, който показва как може да се използва код за писане на още повече код; това не в най-ефективният начин да принтиращ списък от числа. Въпреки това, един програмист може да напише тази метапрограма за по-малко от минута, като по този начин ще генерира точно 1000 ред код, за абсолютно същото време.

Quine е специален вид метапрограма, която произвежда свой собствен сорс код като изход.

Не цялото метапрограмиране обхваща генеративното програмиране. Ако програмите могат да се приспособят с времето или частично да се компилират (както в C, C#ForthFrinkGroovy, JavaScriptLispLuaPerlPHPPythonREBOLRubySmalltalk, и Tcl), то тогава технически метапрограмирането може да се изпълни без да се генерира програмен код.

Lisp е може би най-чистият език с метапрограмирани възможности, както поради своето историческо предимство, така и заради простотата и силата на своето метапраграмиране. В Lisp метапрограмирането, затварящият цитат оператор (обикновено запетая) въвежда код, който се оценява по-скоро по време на дефиниране на програмата, отколкото по време на нейното изпълнение.

Бележки[редактиране | редактиране на кода]

  1. Course on Program Analysis and Transformation. By Prof. Harald Sondergaard. Course on Program Analysis and Transformation. // Посетен на 18 септември 2014.
  2. Czarnecki, Krzysztof, Eisenecker, Ulrich W.. Generative Programming. 2000. ISBN 0-201-30977-7.
  3. например, instance_eval in Ruby takes a string or an anonymous function. Rdoc for Class: BasicObject (Ruby 1.9.3) – instance_eval. // Посетен на 30 декември 2011.

    

Външни препратки[редактиране | редактиране на кода]

Криейтив Комънс - Признание - Споделяне на споделеното Лиценз за свободна документация на ГНУ Тази страница частично или изцяло представлява превод на страницата „Metaprogramming“ в Уикипедия на английски. Оригиналният текст, както и този превод, са защитени от Лиценза „Криейтив Комънс - Признание - Споделяне на споделеното“, а за съдържание, създадено преди юни 2009 година — от Лиценза за свободна документация на ГНУ. Прегледайте историята на редакциите на оригиналната страница, както и на преводната страница. Вижте източниците на оригиналната статия, състоянието ѝ при превода, и списъка на съавторите.