元编程

元编程是用来产生代码的程序,操纵代码的程序,在运行时创建和修改代码而非编程时,这种程序叫做元程序。而编写这种程序就叫做元编程。比如编译原理中用来生成词法分析器和语法分析器的 lex 和 yacc。

元编程技术在多种编程语言中都可以使用,但更多的还是被应用于动态语言中,因为动态语言提供了更多的在运行时将代码视为数据进行操纵的能力。虽然像 C#和 Java 这样较为静态的语言也提供了反射机制,但是仍然没有诸如 Ruby 这样的更趋动态性的语言那么透明,这是因为静态语言在运行时其代码和数据是分布在两个层次上的。

元编程是指某类[计算机程序]的编写,这类计算机程序编写或者操纵其他程序(或者自身)作为它们的数据,或者在[运行时]完成部分本应在[编译时]完成的工作。很多情况下比手工编写全部代码相比工作效率更高。编写元程序的语言称之为元语言,被操作的语言称之为目标语言。一门语言同时也是自身的元语言的能力称之为反射。

反射是促进元编程的一种很有价值的语言特性。把编程语言自身作为头等对象(如 Lisp 或 Rebol)也很有用。支持泛型编程的语言也使用元编程能力。

元编程通常有两种方式起作用。一种方式是通过应用程序接口(API)来暴露运行时引擎的内部信息。另一种方法是动态执行包含编程命令的字符串。因此,“程序能编写程序”。虽然两种方法都能用,但大多数方法主要靠其中一种。

使用示例一个简单元编程的例子是使用 bash 脚本的产生式编程示例:

#!/bin/bash
# metaprogram
echo '#!/bin/bash' >program
for ((I=1; I<=992; I++)) do
echo "echo $I" >>program
done
chmod +x program

这个脚本(或程序)生成了一个新的 993 行程序来打印 1 至 992。这只是演示用代码来写更多代码,并不是打印数字的最有效方法。然而,一个程序员可以几分钟内编写和执行元程序,却生成了近 1000 行代码。

不是所有的元编程都用产生式编程。如果程序可以在运行时改变(如 Lisp、Python、REBOL、Smalltalk、Ruby、PHP、Perl, Tcl、Lua、Groovy 和 JavaScript),这种技术可以不实际生成源代码就使用元编程。

最常用的元编程工具是编译器,把高级语言转换为汇编语言或机器语言。更灵活的方法是在程序中嵌入解释器直接处理程序数据。有一些实现例如为 Object Pascal 编写的 RemObject's Pascal Script。

另一个很常用的元编程例子是 lex 和 yacc,用来生成词法分析器和语法分析器。Yacc 通常用作编译器的编译器,生成一个把高级语言转换为机器语言的工具。

quine 是一种源代码等于输出的特殊的元程序。

面向语言的程序设计是一种强烈关注元编程的编程风格,通过领域特定语言来实现。