如果可以生成某些东西,那么那是数据,而不是代码。
由于您稍后在代码中规定数据是数据,因此您的主张简化为“如果可以生成某些内容,则该内容不是代码”。那么,您会说C编译器生成的汇编代码不是代码吗?如果碰巧恰好与我手工编写的汇编代码相符怎么办?如果您愿意的话,欢迎您去那里,但我不会和您一起去。
让我们从“代码”的定义开始。在不太技术的情况下,出于讨论目的,一个很好的定义是“用于执行计算的机器可操作指令”。
鉴于此,对源代码生成的整个想法不是一种误解吗?
好吧,是的,您的初始主张是无法生成代码,但我拒绝该主张。如果您接受我对“代码”的定义,那么代码生成一般就不会有概念上的问题。
也就是说,如果有某个东西的代码生成器,那么为什么不将该东西变成一个可以接收所需参数并执行“将要生成的”代码将要执行的正确操作的适当函数呢?
嗯,这是一个完全不同的问题,是关于采用代码生成的原因,而不是其本质。您正在提出一种替代方案,而不是编写或使用代码生成器,而是编写一种直接计算结果的函数。但是用什么语言呢?任何人都直接用机器代码编写的日子已经一去不复返了,如果您用任何其他语言编写代码,那么您将依靠编译器和/或汇编器形式的代码生成器来生成实际运行的程序。
那么,为什么您更喜欢用Java或C或Lisp或其他语言编写?甚至汇编程序?我断言,这至少部分是因为这些语言为数据和操作提供了抽象,从而使表达要执行的计算的细节变得更加容易。
大多数高级代码生成器也是如此。典型的案例可能是扫描器和解析器生成器,例如lex
和yacc
。是的,您可以直接使用C或您选择的其他某种编程语言(甚至包括原始机器代码)编写扫描器和解析器,有时也可以。但是对于任何非常复杂的问题,使用高级的专用语言(例如lex或yacc)会使手写代码更易于编写,阅读和维护。通常也要小得多。
您还应该考虑“代码生成器”的确切含义。我认为C预处理和C ++模板的实例化是代码生成中的练习。你反对这些吗?如果没有,那么我认为您需要执行一些心理体操工作,以合理地接受这些内容,但拒绝其他形式的代码生成。
如果这样做是出于性能原因,那么这听起来像是编译器的缺点。
为什么?您基本上认为,应该有一个通用程序,用户向其提供数据,有些程序被归类为“指令”,而另一些程序被归类为“输入”,然后该程序将继续执行计算并发出更多的数据,我们称之为“输出”。(从某种角度来看,可以将这样的通用程序称为“操作系统”。)但是为什么您认为编译器在优化通用程序方面应该与在优化更专业的程序方面一样有效。程序?这两个程序具有不同的特性和不同的功能。
如果要完成两种语言之间的桥梁,那么这听起来像缺少接口库。
您说好像拥有通用度接口库一定是一件好事。也许可以,但是在许多情况下,这样的库很大,难以编写和维护,甚至可能很慢。如果实际上不存在这种野兽可以解决眼前的特定问题,那么当代码生成方法可以更快,更轻松地解决问题时,您是谁坚持要创建一个野兽呢?
我在这里想念什么吗?
我认为有几件事。
我知道代码也是数据。我不明白的是,为什么要生成源代码?为什么不使其成为可以接受参数并对其执行操作的函数呢?
代码生成器将用一种语言编写的代码转换为使用另一种通常是较低级语言的代码。然后,您要问的是,人们为什么要使用多种语言编写程序,尤其是为什么他们可能想要混合主观不同级别的语言。
但是我已经谈到了。一个人为特定任务选择一种语言,部分是基于该任务的清晰度和表现力。由于较小的代码平均具有较少的错误并且更易于维护,因此至少在大规模工作中也倾向于使用高级语言。但是,复杂的程序涉及许多任务,通常可以用一种语言更有效地解决其中的一些任务,而用另一种语言更有效或更简洁地解决其他任务。使用正确的工具完成工作有时意味着使用代码生成。