元编程究竟是什么?

我正在阅读TheServerSide上关于Java平台上的ployglot编程的文章。 文章中的一些评论将元编程称为生成代码的能力(也许是即时的)。

元编程能够在运行中生成代码,或者是在运行时将方法和属性注入现有对象的能力(如Python,Ruby和Groovy允许的一些dynamic语言)。

元编程是指程序具有自身知识或可以操纵自己的各种方式。

在像C#这样的语言中,reflection是元编程的一种forms,因为程序可以检查关于它自己的信息。 例如返回一个对象的所有属性的列表。

在ActionScript等语言中,可以在运行时评估函数以创build新程序,如eval(“x”+ i).DoSomething()将影响i为1时x1和i2时x2的对象。

最后,元编程的另一种常见forms是程序能够以非平凡的方式改变自己。 LISP是众所周知的,这是十年前Paul Graham所倡导的。 我将不得不查阅他的一些具体的散文。 但是这个想法是,程序会根据其状态改变程序的另一部分。 这使得在运行时可以灵活地进行决策,这在当今大多数stream行的语言中是非常困难的。

还有一点值得注意的是,在直接assembly编程的好时代,在运行时改变自己的程序是必要的,也是非常普遍的。

从保罗·格雷厄姆的文章“什么使Lisp不同” :

许多语言都有一个叫macros的东西。 但Lispmacros是唯一的。 信不信由你,他们所做的是与括号有关的。 Lisp的devise者并没有把这些括号全部用在语言上, 对Blub程序员来说,Lisp代码看起来很奇怪。 但是那些括号是有原因的。 它们是Lisp和其他语言之间根本区别的外在证据。

Lisp代码是由Lisp数据对象构成的。 而不是一般意义上的源文件包含字符,string是语言支持的数据types之一。 Lisp代码在parsing器读取之后,由可以遍历的数据结构组成。

如果你明白编译器是如何工作的,那么Lisp有一个奇怪的语法,因为Lisp没有语法。 您可以在分析其他语言时在编译器中生成的分析树中编写程序。 但是这些parsing树可以完全访问你的程序。 你可以编写操作它们的程序。 在Lisp中,这些程序被称为macros。 他们是编写程序的程序。

程序写程序? 你什么时候想要这样做? 如果你在Cobol中想,不是很常见。 所有的时间,如果你认为在Lisp。 如果我能举一个强大的macros的例子,那么在这里很方便,并且在那里说! 那个怎么样? 但是如果我这样做了,对于一个不懂Lisp的人来说,看起来就像是胡言乱语; 这里没有空间来解释你需要知道的一切。 在Ansi Common Lisp中,我尝试尽可能快地移动,甚至直到第160页才得到macros。

但是我想我可以给出一个可能令人信服的论点。 Viaweb编辑器的源代码大概是20-25%的macros。 macros比普通的Lisp函数更难编写,在不需要的时候使用它们被认为是不好的风格。 因此,代码中的每个macros都存在,因为它必须是。 这意味着这个程序中至less有20-25%的代码是在做其他任何语言都不能轻易做到的事情。 然而,对Blub程序员可能是对Lisp的神秘力量的怀疑,这应该让他好奇。 我们不是为了自己的娱乐而编写这些代码的。 我们是一个小小的创业公司,为了在我们和我们的竞争对手之间设置技术障碍,我们尽可能地编程。

一个可疑的人可能会开始怀疑这里是否有一些相关性。 我们的代码很大一部分是做其他语言很难做的事情。 由此产生的软件做我们的竞争对手的软件不能做的事情。 也许有某种联系。 我鼓励你遵循这个话题。 那个在拐杖上蹒跚的老人可能比眼睛还有更多的东西。

那么,元编程只是编程,但基本上是“编写代码”

你提到的能力,当一个程序可以观察和修改自己的结构和行为时被称为reflection,这是一种元编程。

dynamictypes的语言,具有强大的运行时reflectionfunction,由这些语言的解释性质成为可能…

静态types语言也有强大的元编程技术,例如C ++ 模板元编程 …

伟大的问题。 我非常抱歉,目前没有任何答案能够正确回答你的问题。 也许我可以帮忙…

元编程的定义非常简单:它意味着操作程序的程序。

你接受的答案是说操纵自己的程序。 那些确实是元程序,但它们是所有元程序的一个子集。

所有:

  • parsing器
  • 域特定语言(DSL)
  • embedded式域特定语言(EDSL)
  • 编译器
  • 口译
  • 定期重写者
  • 定理certificate

是元程序。 所以GCC编译器是元程序, CPython解释器是元程序, Mathematica计算机代数系统是元程序, Coq定理certificate器是元程序等等。

其他答案已经断言元程序是生成其他程序的程序。 这些确实是元程序,但它们又是所有元程序的一个子集。 西方最快的傅里叶变换 (FFTW)库就是这样一个元程序的一个例子。 源代码主要是在OCaml中编写的,它生成一些C代码(称为小代码),这些代码组合在一起以创build针对特定机器优化的高性能快速傅里叶变换例程。 该库实际上用于在Matlab中提供FFT例程。 自从FORTRAN诞生以来,人们一直在编写数十年的数值计算方法。

集成对元编程支持的第一种编程语言是LISt处理器(LISP)语言在20世纪50年代后期。 LISP 1.5包含了一些使元编程更容易的function。 首先,LISP的核心数据types是嵌套列表,即像(a (bc) d)这样的树,这意味着任何LISP代码可以本地表示为数据结构。 这被称为homoiconicity。 其次,可以使用QUOTE轻松地将LISP代码转换为数据。 例如(+ 1 2 3)添加1 + 2 + 3,并且(QUOTE (+ 1 2 3))创build一个expression式,在评估时添加1 + 2 + 3。 第三,LISP提供了一个元循环评估器,允许您使用宿主解释器或编译器在运行时评估LISP代码,包括运行时生成的LISP代码。 LISP的后代包括Scheme和Clojure 。 在所有这些语言中,元编程是最常见的程序forms,通常使用macros来自我修改。

在二十世纪七十年代,Robin Milner开发了一个MetaLanguage (ML),演变成ML系列编程语言,其中包括Standard ML和OCaml,并强烈影响Haskell和F# 。 这些语言可以很容易地expression其他语言。 在这些语言中,元语言最常见的forms是词法分析器,parsing器,解释器和编译器。

1994年, Erwin Unruh发现C ++模板系统是图灵完备的,可以在编译时用来执行任意程序 。 C ++模板元编程为未经洗刷的群体带来元编程(b),他们使用它来做许多不同的事情,包括在Blitz ++库中生成数值方法。

这只是我个人的意见,这可能是元编程最自由的定义。

我认为它包括:

  1. 编译代码生成或运行时代码生成(或两者)
  2. 面向方面的思维或面向方面的编程
  3. 干思考

我想你可以通过以下任何一种方式来达到目的:

  1. reflection
  2. DSL(域特定语言)
  3. 属性(.NET)或注释(Java)
  4. generics(.NET / Java)
  5. 模板(C ++)
  6. method_missing(Ruby)
  7. closures/头等function/代表
  8. AOP – 面向方面的编程

元编程正在编写一个输出另一个程序的程序。 这是像Lisp这样的语言真正擅长的。 在支持真正的macros(不是C ++macros,而是可以操纵他们输出的代码的语言)的语言(如Ruby,Lisp,Scheme等)中执行语言要比使用Java语言更容易。

一个实现是创build一个“领域特定语言”,这是一种增强编程语言以完成特定任务的方式。 如果做得正确,它可以是非常强大的。 Ruby on Rails就是这种编程的一个很好的例子。

如果您有兴趣探索这种方法,请查看计算机程序的结构和解释,这是涵盖这个主题的开创性的书籍之一。

元编程是指编写或操作其他程序(或自身)作为其数据的计算机程序,或者是在运行时执行部分工作的计算机程序,否则将在编译时完成。 在许多情况下,这允许程序员在与手动编写所有代码相同的时间内完成更多的工作,或者为程序提供更大的灵活性,以便在不重新编译的情况下有效处理新的情况。 ( 来源 )

基本上,它是编写代码,输出更多的代码,这是运行来完成一些目标。 这通常在相同的语言(使用JavaScript创build一个JavaScriptstring,然后eval它)或发出另一种语言(使用.NET创build一个Windowsbatch file)完成。

维基百科在这个话题上有一篇不错的文章。 一个人不必做运行时修改的东西来限定元编程。 例如,许多人在编译时使用C ++模板进行元编程。