Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Metaprogramming
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{Short description|Programming paradigm}} {{About|the computer programming technique|the management technique|Charles Simonyi}} {{Multiple issues| {{More citations needed|date=August 2011}} {{Tone|date=February 2017}} }} '''Metaprogramming''' is a [[computer programming]] technique in which [[computer program]]s have the ability to treat other programs as their [[data]]. It means that a program can be designed to read, generate, analyse, or transform other programs, and even modify itself, while running.<ref>{{cite web |last1=Sondergaard |first1=Harald |date=2013 |url=https://handbook.unimelb.edu.au/view/2013/COMP90053 |title=Course on Program Analysis and Transformation |access-date=18 September 2014}}</ref><ref>{{cite book |last1=Czarnecki |first1=Krzysztof |author-link1=Krzysztof Czarnecki |last2=Eisenecker |first2=Ulrich W. |date=2000 |title=Generative Programming |publisher=Addison Wesley |isbn=0-201-30977-7}}</ref> In some cases, this allows programmers to minimize the number of lines of code to express a solution, in turn reducing development time.<ref>{{cite web|last1=Walker|first1=Max|title=The Art of Metaprogrmming in Java|url=https://newcircle.com/s/post/1267/the_art_of_metaprogramming_in_java_video_jaxconf|website=New Circle|access-date=28 January 2014}}</ref> It also allows programs more flexibility to efficiently handle new situations with no recompiling. Metaprogramming can be used to move computations from [[Runtime (program lifecycle phase)|runtime]] to [[compile time]], to generate code using [[Compile-time function execution|compile time computations]], and to enable [[self-modifying code]]. The ability of a [[programming language]] to be its own [[metalanguage]] allows [[reflective programming]], and is termed ''reflection''.<ref>{{cite web|last1=Krauss|first1=Aaron|title=Programming Concepts: Type Introspection and Reflection|url=https://thesocietea.org/2016/02/programming-concepts-type-introspection-and-reflection/|archive-url=https://web.archive.org/web/20160310192057/https://thesocietea.org/2016/02/programming-concepts-type-introspection-and-reflection/ |access-date=10 March 2016|archive-date=10 March 2016 }}</ref> Reflection is a valuable language feature to facilitate metaprogramming. Metaprogramming was popular in the 1970s and 1980s using list processing languages such as [[Lisp (programming language)|Lisp]]. [[Lisp machine]] hardware gained some notice in the 1980s, and enabled applications that could process code. They were often used for [[artificial intelligence]] applications. == Approaches == Metaprogramming enables developers to write programs and develop code that falls under the [[generic programming]] [[paradigm]]. Having the programming language itself as a [[First-class object|first-class data type]] (as in [[Lisp (programming language)|Lisp]], [[Prolog]], [[SNOBOL]], or [[Rebol]]) is also very useful; this is known as ''[[homoiconicity]]''. [[Generic programming]] invokes a metaprogramming facility within a language by allowing one to write code without the concern of specifying data types since they can be supplied as [[parameter (computer programming)|parameters]] when used. Metaprogramming usually works in one of three ways.<ref>{{cite web|last1=Joshi|first1=Prateek|title=What Is Metaprogramming? β Part 2/2|url=https://prateekvjoshi.com/2014/04/05/what-is-metaprogramming-part-22/|website=Perpetual Enigma|date=5 April 2014|access-date=14 August 2014}}</ref> # The first approach is to expose the internals of the [[runtime system]] (engine) to the programming code through [[application programming interface]]s (APIs) like that for the [[.NET]] [[Common Intermediate Language]] (CIL) emitter. # The second approach is [[Out-of-order execution|dynamic execution]] of expressions that contain programming commands, often composed from strings, but can also be from other methods using arguments or context, like [[JavaScript]].<ref>for example, instance_eval in [[Ruby (programming language)|Ruby]] takes a string or an anonymous function. {{cite web |url=https://docs.ruby-lang.org/en/master/BasicObject.html#method-i-instance_eval |title=Class BasicObject Ruby 3.5}}</ref> Thus, "programs can write programs." Although both approaches can be used in the same language, most languages tend to lean toward one or the other. # The third approach is to step outside the language entirely. General purpose [[program transformation]] systems such as [[compiler]]s, which accept language descriptions and carry out arbitrary transformations on those languages, are direct implementations of general metaprogramming. This allows metaprogramming to be applied to virtually any target language without regard to whether that target language has any metaprogramming abilities of its own. One can see this at work with [[Scheme (programming language)|Scheme]] and how it allows tackling some limits faced in [[C (programming language)|C]] by using constructs that are part of the Scheme language to extend C.<ref>{{cite web|title=Art of Metaprogramming|website=[[IBM]] |url=http://www.ibm.com/developerworks/library/l-metaprog1/}}</ref> [[Lisp (programming language)|Lisp]] is probably the quintessential language with metaprogramming facilities, both because of its historical precedence and because of the simplicity and power of its metaprogramming. In Lisp metaprogramming, the unquote operator (typically a comma) introduces code that is [[Lisp (programming language)#Self-evaluating forms and quoting|evaluated at program definition time]] rather than at run time. The metaprogramming language is thus identical to the host programming language, and existing Lisp routines can be directly reused for metaprogramming if desired. This approach has been implemented in other languages by incorporating an interpreter in the program, which works directly with the program's data. There are implementations of this kind for some common high-level languages, such as [[RemObjects]]β [[Pascal Script]] for [[Object Pascal]]. == Usages == === Code generation === A simple example of a metaprogram is this [[Unix shell|POSIX Shell]] [[script (computer programming)|script]], which is an example of [[generative programming]]: <syntaxhighlight lang="bash"> #!/bin/sh # metaprogram echo '#!/bin/sh' > program for i in $(seq 992) do echo "echo $i" >> program done chmod +x program </syntaxhighlight> This script (or program) generates a new 993-line program that prints out the numbers 1β992. This is only an illustration of how to use code to write more code; it is not the most efficient way to print out a list of numbers. Nonetheless, a programmer can write and execute this metaprogram in less than a minute, and will have generated over 1000 lines of code in that amount of time. A [[Quine (computing)|quine]] is a special kind of metaprogram that produces its own source code as its output. Quines are generally of recreational or theoretical interest only. Not all metaprogramming involves generative programming. If programs are modifiable at runtime, or if incremental compiling is available (such as in [[C Sharp (programming language)|C#]], [[Forth (programming language)|Forth]], [[Frink (programming language)|Frink]], [[Groovy (programming language)|Groovy]], [[JavaScript]], [[Lisp (programming language)|Lisp]], [[Elixir (programming language)|Elixir]], [[Lua (programming language)|Lua]], [[Nim (programming language)|Nim]], [[Perl]], [[PHP]], [[Python (programming language)|Python]], [[Rebol]], [[Ruby (programming language)|Ruby]], [[Rust (programming language)|Rust]], [[R (programming language)|R]], [[SAS (software)|SAS]], [[Smalltalk]], and [[Tcl]]), then techniques can be used to perform metaprogramming without generating source code. One style of generative approach is to employ [[domain-specific language]]s (DSLs). A fairly common example of using DSLs involves generative metaprogramming: [[Lex programming tool|lex]] and [[yacc]], two tools used to generate [[lexical analysis|lexical analyser]]s and [[parsing|parser]]s, let the user describe the language using [[regular expression]]s and [[context-free grammar]]s, and embed the complex algorithms required to efficiently parse the language. === Code instrumentation === One usage of metaprogramming is to instrument programs in order to do [[dynamic program analysis]]. == Challenges == Some argue that there is a sharp learning curve to make complete use of metaprogramming features.<ref name="challenges">{{cite web |last1=Bicking|first1=Ian|title=The challenge of metaprogramming|url=http://www.ianbicking.org/the-challenge-of-metaprogramming.html|website=IanBicking.org|access-date=21 September 2016}}</ref> Since metaprogramming gives more flexibility and configurability at runtime, misuse or incorrect use of metaprogramming can result in unwarranted and unexpected errors that can be extremely difficult to debug to an average developer. It can introduce risks in the system and make it more vulnerable if not used with care. Some of the common problems, which can occur due to wrong use of metaprogramming are inability of the compiler to identify missing configuration parameters, invalid or incorrect data can result in unknown exception or different results.<ref>{{cite web|last1=Terry|first1=Matt|title=Beware of Metaprogramming|url=https://medium.com/@macterry/beware-of-metaprogramming-3afdc931cadf#.6a4hskoxk|website=Medium.com|date=21 August 2013|publisher=Medium Corporation|access-date=21 August 2014}}</ref> Due to this, some believe<ref name="challenges"/> that only high-skilled developers should work on developing features which exercise metaprogramming in a language or platform and average developers must learn how to use these features as part of convention. == Uses in programming languages == === Macro systems === {{main|Macro (computer science)}} * [[Lisp (programming language)|Lisp]], most dialects ** [[Clojure (programming language)|Clojure]] ** [[Common Lisp]] ** [[Racket (programming language)|Racket]] ** [[Scheme (programming language)|Scheme]] [[hygienic macro]]s * [[MacroML]] * [[Template Haskell]] * [[Scala (programming language)|Scala]] * [[Nim (programming language)|Nim]] * [[Rust (programming language)|Rust]] * [[Haxe]] * [[Julia (programming language)|Julia]] * [[Elixir (programming language)|Elixir]] === Macro assemblers === {{main|Macro assembler}} The [[IBM/360]] and derivatives had powerful [[macro assembler]] facilities that were often used to generate complete [[assembly language]] programs {{Citation needed|date=August 2011}} or sections of programs (for different operating systems for instance). Macros provided with [[CICS]] [[transaction processing]] system had assembler macros that generated [[COBOL]] statements as a pre-processing step. Other assemblers, such as [[MASM]], also support macros. === Metaclasses === {{main|Metaclass}} [[Metaclass]]es are provided by the following programming languages: * [[Common Lisp]]<ref>Through [[Common Lisp Object System]]'s "Meta Object Protocol"</ref> * [[Python (programming language)|Python]] * [[NIL (programming language)|NIL]] * [[Groovy (programming language)|Groovy]] * [[Ruby (programming language)|Ruby]] * [[Smalltalk]] * [[Lua (programming language)|Lua]] === Template metaprogramming === {{main|Template metaprogramming}} * [[X Macro|C "X Macros"]] * [[C++ Templates]]<ref>{{Cite web |title=C++ Template Metaprogramming |url=http://aszt.inf.elte.hu/~gsd/halado_cpp/ch06s04.html |access-date=2022-07-23 |website=aszt.inf.elte.hu}}</ref> * [[D (programming language)|D]] * [[Common Lisp]], [[Scheme (programming language)|Scheme]] and most Lisp dialects by using the quasiquote ("backquote") operator.<ref>[[Lisp (programming language)]] "Self-evaluating forms and quoting", quasi-quote operator.</ref> * [[Nim (programming language)|Nim]] === Staged metaprogramming === {{main|Multi-stage programming}} * MetaML * [[OCaml#MetaOCaml|MetaOCaml]] * [[Scala (programming language)|Scala]] [https://docs.scala-lang.org/scala3/reference/metaprogramming.html natively] or using the Lightweight Modular Staging Framework<ref>{{Cite web|url=https://scala-lms.github.io/|title=LMS: Program Generation and Embedded Compilers in Scala|website=scala-lms.github.io|language=en|access-date=2017-12-06}}</ref><ref>{{Cite journal|last1=Rompf|first1=Tiark|last2=Odersky|first2=Martin|date=June 2012|title=Lightweight Modular Staging: A Pragmatic Approach to Runtime Code Generation and Compiled DSLs|journal=Communications of the ACM|volume=55|issue=6|pages=121β130|doi=10.1145/2184319.2184345|s2cid=52898203|issn=0001-0782|url=http://infoscience.epfl.ch/record/178274}}</ref> * [http://terralang.org Terra] === Dependent types === {{main|Dependent type}} Use of [[dependent type]]s allows proving that generated code is never invalid.<ref>{{cite journal|last=Chlipala|first=Adam|title=Ur: statically-typed metaprogramming with type-level record computation|journal=ACM SIGPLAN Notices|date=June 2010|volume=45|series=PLDI '10|issue=6|pages=122β133|doi=10.1145/1809028.1806612|url=http://adam.chlipala.net/papers/UrPLDI10/UrPLDI10.pdf|access-date=29 August 2012}}</ref> However, this approach is leading-edge and rarely found outside of research programming languages. == Implementations == The list of notable metaprogramming systems is maintained at [[List of program transformation systems]]. ==See also== <!-- No programming languages, please --> {{div col|colwidth=30em}} *[[Aspect weaver]] *[[Comparison of code generation tools]] *[[Compile-time function execution]] *[[Genetic programming]] *[[Homoiconicity]] *[[Inferential programming]] *[[Instruction set simulator]] *[[Interpreted language]] *[[Machine learning]] *[[Metacompiler]] *[[Metaobject]] *[[Partial evaluation]] *[[Reflective programming]], also compile time reflection *[[Self-interpreter]] *[[Self-modifying code]] *[[Source code generation]] *[[Transcompiler]] (also known as transpilation) *[[Very-large-scale integration]] *[[Halting problem]] {{div col end}} ==References== {{Reflist}} ==External links== *[http://c2.com/cgi/wiki?MetaProgramming c2.com Wiki: Metaprogramming article] *[http://www.program-transformation.org/Transform/MetaProgramming Meta Programming] on the Program Transformation Wiki *[http://www.qcodo.com/wiki/article/background/metaprogramming Code generation Vs Metaprogramming] *[https://web.archive.org/web/20160503055316/http://solenoid.schematronic.org/ "Solenoid"]: The first metaprogramming framework for [http://exist-db.org eXist-db] {{Cleanup|date=April 2025|reason=archive-org link links to unrelated maybe-spam site, unclear if legitimate bit rot or malice}} {{Programming paradigms navbox}} {{Types of programming languages}} [[Category:Metaprogramming| ]] [[Category:Programming paradigms]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:About
(
edit
)
Template:Citation needed
(
edit
)
Template:Cite book
(
edit
)
Template:Cite journal
(
edit
)
Template:Cite web
(
edit
)
Template:Cleanup
(
edit
)
Template:Div col
(
edit
)
Template:Div col end
(
edit
)
Template:Main
(
edit
)
Template:Multiple issues
(
edit
)
Template:Programming paradigms navbox
(
edit
)
Template:Reflist
(
edit
)
Template:Short description
(
edit
)
Template:Types of programming languages
(
edit
)