我正在阅读有关Java平台上的ployglot编程的 TheServerSide文章。本文中的一些评论将元编程称为生成代码的能力(也许是在运行中)。
元编程是在运行时即时生成代码的能力,还是在运行时将方法和属性注入到现有对象中的能力(例如某些动态语言(如Python,Ruby和Groovy所允许的))。
我正在阅读有关Java平台上的ployglot编程的 TheServerSide文章。本文中的一些评论将元编程称为生成代码的能力(也许是在运行中)。
元编程是在运行时即时生成代码的能力,还是在运行时将方法和属性注入到现有对象中的能力(例如某些动态语言(如Python,Ruby和Groovy所允许的))。
Answers:
元编程是指程序具有自身知识或可以操纵自身的多种方式。
在像C#这样的语言中,反射是元编程的一种形式,因为程序可以检查有关其自身的信息。例如,返回对象的所有属性的列表。
在诸如ActionScript之类的语言中,您可以在运行时评估函数以创建新程序,例如eval(“ x” + i)。DoSomething()在i为1时会影响名为x1的对象,而在i为2时会影响x2的对象。
最后,元编程的另一种常见形式是程序可以以非平凡的方式更改自身。LISP以这一点而闻名,这是Paul Graham在十年前所倡导的。我将不得不查阅他的一些具体论文。但是想法是程序将根据其状态更改程序的另一部分。这提供了一定程度的灵活性,可以在运行时进行决策,这在当今大多数流行语言中都是非常困难的。
还值得注意的是,在进行直接汇编编程的好时光中,在运行时更改自身的程序是必要且非常普遍的。
保罗·格雷厄姆(Paul Graham)的论文《使Lisp与众不同的原因》:
许多语言都有一个称为宏的东西。但是Lisp宏是唯一的。信不信由你,他们所做的事与括号有关。Lisp的设计人员并没有将所有括号都用在该语言中只是为了有所不同。对于Blub程序员而言,Lisp代码看起来很奇怪。但是那些括号在那里是有原因的。它们是Lisp和其他语言之间根本不同的外在证据。
Lisp代码由Lisp数据对象组成。从源文件包含字符的意义上讲,字符串并不是该语言支持的数据类型之一。解析器读取后,Lisp代码由您可以遍历的数据结构组成。
如果您了解编译器是如何工作的,那么实际发生的并不是Lisp具有一种奇怪的语法,而是Lisp没有语法。您在解析树中编写程序,这些树在解析其他语言时在编译器中生成。但是您的程序完全可以访问这些分析树。您可以编写操纵它们的程序。在Lisp中,这些程序称为宏。它们是编写程序的程序。
编写程序的程序?您什么时候想这样做?如果您认为在Cobol中,则不会经常出现。一直以来,如果您考虑使用Lisp。如果我可以举一个强大的宏示例并在此处说,那将很方便!那个怎么样?但是,如果我这样做了,那对不了解Lisp的人来说就像是胡言乱语。这里没有空间来解释您需要了解的所有内容以了解其含义。在Ansi Common Lisp中,我试图尽可能快地移动内容,即使如此,直到160页,我才开始使用宏。
但是我想我可以提出一种可能令人信服的论点。Viaweb编辑器的源代码大概是20-25%的宏。宏比普通的Lisp函数更难编写,并且在不需要它们时使用宏被认为是不好的样式。因此该代码中的每个宏都存在,因为必须存在。这意味着该程序中至少有20%至25%的代码正在执行您用其他任何语言都无法轻松完成的工作。无论对Blub程序员持怀疑态度,可能是关于我对Lisp神秘力量的主张,这应该使他感到好奇。我们并不是出于娱乐目的而编写此代码。我们是一家小型的初创公司,我们竭尽全力进行编程,以在我们和竞争对手之间设置技术壁垒。
一个可疑的人可能会开始怀疑这里是否存在某种关联。我们的代码很大一部分正在做其他语言很难做到的事情。最终的软件完成了竞争对手软件无法完成的工作。也许有某种联系。我鼓励您遵循该主题。那个old着拐杖走路的老人可能比目睹更多。
in order to put technical barriers between us and our competitors
,这是正确的。
好问题。非常抱歉,目前没有任何答案能够真正正确回答您的问题。也许我可以帮忙...
元编程的定义确实非常简单:它意味着可以操纵程序的程序。
您接受的答案是说可以自我操纵的程序。这些确实是元程序,但它们是所有元程序的子集。
所有:
是元程序。因此,GCC编译器是一个元程序,CPython解释器是一个元程序,Mathematica计算机代数系统是一个元程序,Coq定理证明者是一个元程序,依此类推。
其他答案断言元程序是生成其他程序的程序。这些确实是元程序,但同样,它们是所有元程序的子集。的傅立叶变换在西方最快(FFTW)库是这样的元程序的一个例子。源代码主要用OCaml编写,它生成C代码(称为小码),这些C代码组合在一起以创建针对特定机器优化的高性能快速傅里叶变换例程。该库实际上用于在Matlab中提供FFT例程。自从FORTRAN成立以来,人们一直在编写程序来生成数值方法。
1950年代后期,集成了对元编程的支持的第一种编程语言是LISt Processor(LISP)语言。LISP 1.5包含许多使元编程更容易的功能。首先,LISP的核心数据类型是嵌套列表,即像树这样的树(a (b c) d)
,这意味着任何LISP代码都可以本地表示为数据结构。这称为谐音。其次,可以使用QUOTE将LISP代码轻松转换为数据。例如,加(+ 1 2 3)
1 + 2 + 3并(QUOTE (+ 1 2 3))
创建一个表达式,该表达式在求值时加1 + 2 + 3。第三,LISP提供了一个元循环评估器,使您可以使用主机解释器或编译器在运行时评估LISP代码,包括在运行时生成的LISP代码。LISP的后代包括Scheme和Clojure。在所有这些语言中,元编程通常以修改自身的程序的形式(通常使用宏)看到。
在1970年代,罗宾·米尔纳(Robin Milner)开发了一种元语言(ML),该语言演变成ML系列编程语言,其中包括Standard ML和OCaml,并深受Haskell和F#的影响。这些语言使表达其他语言变得容易。在这些语言中,元程序最常以词法分析器,解析器,解释器和编译器的形式出现。
1994年,Erwin Unruh发现C ++模板系统是Turing完整的,可用于在编译时执行任意程序。C ++模板元编程将元编程带给了未受洗的群众,后者无休止地将其用于许多不同的事情,包括在Blitz ++库中生成数值方法。