一个小论点 _pro_ 内部 DSL(如果这太过分了,请投反对票。)
内部 DSL
内部 DSL 以类型安全的方式构造模型,并且通常带有语义检查。自动完成也有帮助。因此,即使不是应用程序性能,它也有利于软件质量,也就是开发性能。
现在一个好的 DSL 由构建器类组成,它们构成了一个单独定义的模型。最终的评估,归结为一个结果,可以“编译”。
Java 在正则表达式 Pattern/Matcher 中使用它,带有 Pattern.compile/matcher。那里没有真正的 DSL,但也是内部正则表达式模型的构建者。
回顾一下,当模型准备好构建时,它也可以“编译”。有时热点编译器会启动。
外部 DSL
但外部 DSL 可能会预编译为更直接的代码,从而省去内部 DSL 的编译和优化。您不能轻易地遵循代码、数据模型和优化。 DSL 的一些努力必须涉及语法着色/语法错误/自动完成。此外,外部 DSL 编译器产生的数据可能比代码多。 “加载器”部分也必须很快。
内部 DSL 的开销:以及要考虑的内容。
流畅的 API 和立即构建模型之间的开销并不大。通常return this; 用于链式调用,最好在final(不可覆盖)方法中完成,以便编译器可以立即优化,而不是依赖于热点编译器的检测。语义检查是不可避免的开销:错误是有问题的,不需要隐藏它们。如果它们导致代码迭代,则您正在构建的数据结构可能是错误的(= 使用映射)。所以开销应该足够小。
我个人的结论是 DSL 有利于开发,而且速度足够快。通常下一步是有问题的。 jOOQ 很好,JPA 标准 API 很好,ORM 有一些问题。 Java 8 的 lambda 也是如此。看到它们用作 DSL,很有趣,而且可能只是过于间接,过度劳累。
目前,DSL 仅应用于几个领域:技术接口,如 java+SQL,但实际上并不需要它。以及开发人员有时将责任转移给最终客户的业务逻辑,例如编程、版本控制、登台。 (更改后的业务规则会立即对生命系统生效,表单编辑器。)这些业务 DSL 的效率取决于系统背后有一个复杂的语义模型,例如数据库引擎。效率低下是由于声明/程序不匹配造成的。
代码跨语言的统一可以部分深入; Java + SQL:Java 将 java 存储过程传递给 SQL。矢量处理可能相同。
附言
.NET 有一些跨/混合语言编译器工作(我认为 Irony)来生成令牌流、AST 并从那里开始。