Templates 在编程语言中实现模板的最佳方法是什么?

Templates 在编程语言中实现模板的最佳方法是什么?,templates,language-design,Templates,Language Design,我正在设计一种高级的、面向对象的、垃圾回收的编程语言,我在如何做模板方面遇到了问题。我计划创建一个VM类型的系统,类似于.NET或JVM(但它将在后台使用LLVM)。问题是,我希望有功能强大的、类似C++的模板,但要有动态链接(这样我就可以替换模板库,而无需重新编译使用它的所有内容)。我希望能够在没有模板定义的情况下编译源文件。应尽量减少JIT时间的代码生成 以下是我正在考虑的选项: 有一个静态链接到每个编译单元的模板库的概念。模板库本质上类似于AST,在实例化模板时填充空格。这样做的问题是,

我正在设计一种高级的、面向对象的、垃圾回收的编程语言,我在如何做模板方面遇到了问题。我计划创建一个VM类型的系统,类似于.NET或JVM(但它将在后台使用LLVM)。问题是,我希望有功能强大的、类似C++的模板,但要有动态链接(这样我就可以替换模板库,而无需重新编译使用它的所有内容)。我希望能够在没有模板定义的情况下编译源文件。应尽量减少JIT时间的代码生成

以下是我正在考虑的选项:

  • 有一个静态链接到每个编译单元的模板库的概念。模板库本质上类似于AST,在实例化模板时填充空格。这样做的问题是,如果两个文件使用不同版本的模板库编译,它们可能不兼容,或者如果模板库有缺陷,则必须重新编译所有文件。C++就是这样做的。
  • 具有在JIT时间链接的模板库。这解决了大多数问题,但要求IR本质上是AST。我希望IR的水平要低得多。这需要更多的JIT工作
  • 具有弱C#-样泛型,仅使用类型作为参数。这是相当有限的,但允许简单的代码生成和动态链接

还有其他我没想到的好方法吗?我倾向于第一种选择,但我真的不喜欢任何一种选择。你认为什么是最好的选择?

我想这取决于你想要的专业化程度,即模板编译器的功能

如果你看C++,编译器可以做各种各样的奇特的事情(比如通过递归生成子类,可能计算分形继承图,也可以计算PI的飞行数)。


如果您想要这种能力,您可能需要一个强大的高级JIT。我想那会很酷的。(只需在运行时包含完整的编译器即可。)

取决于语言的其余部分。。。如果你有操作符重载,值类型等,那么你就真的复杂了(可能错过了很大的优化机会),因为没有去C++路径:使用模板的代码也必须被表示为一个AST到JIT时间,以允许最大化。 < C++模板本质上是一种宏形式,它们允许在复制代码之前减少所有由复制产生的膨胀。
模板类型(至少在C++中)往往是构成所有其他代码基础的最核心类型,因此,如果它们发生变化,假设其他代码仍然与之兼容,那么除了最小的变化之外,所有的变化都不会发生。

您试图实现的几乎是不可能的。您必须为模板定义和使用这些模板的代码保留几乎所有语言的高级表示,并从几乎轻微处理的源代码级别执行JIT编译。如果你同意的话-你必须让编译器的其余部分变得非常简单,你将无法使用任何重量级的LLVM优化。没有其他方法,模板元编程依赖于高级信息的可用性。

想想这些模板将有多强大。您必须记住,拥有一种及时编译的语言,意味着大量繁重的工作必须在加载时和运行时完成。因此,模板的功能越强大,从中获得的性能就越差


如果您真的要走这条路,那么您还可以在运行时将编译器作为一部分包含进来。事实上,有很多语言可以做到这一点

通过这样做,您将使您的语言实现成为“解释的”或部分“解释的”。在这些术语中,模板只是match replace eval的一件奇装异服,这有什么不对的,在动态语言中,模板通常是这样工作的。请记住,最终将是功率与性能的较量


注意:当面对这种决定时,可能值得后退一步。识别用例并对其进行优先级排序,将如何实现与设计分开,这样您就可以迭代设计,而不必让实现成为瘫痪的原因,但仍然需要考虑它

每次迭代,您都会扩展设计以覆盖更多的用例,同时决定什么是最佳设计。当你达到你喜欢的设计时,你可以迭代,然后你也可以迭代实现。此方法允许您首先涵盖更重要的案例

是的,我建议采用迭代增量方法。我这样做是因为这个问题是关于语言的设计,但它似乎非常关心实现。有必要将这些想法扎根在基础上,否则您将陷入极端(对于高性能解决方案来说,功能太强大,性能太差,或者根本没有模板)