目前在编译时很少检查类型;这主要是作为静态优化器的副作用发生的。今天的检查主要是关于子程序调用,其中:
- 我们可以确定调用的数量并知道传递的参数数量永远不会匹配
- 我们有文字参数,可以看到它们永远不可能与签名匹配
这是静态优化器进行更多内联工作时的遗留问题。现在,它只在编译时内联原生操作符,其余的留给 VM 的动态优化器,后者在内联方面的能力大大提高,也可以取消内联(允许推测优化,但也意味着可以恢复原始堆栈跟踪,而静态优化器丢失了此信息)。
在编译时做更多的事情被认为是可取的,但是有一些实际问题需要考虑。
- 引入额外的检查也可能会破坏以前工作的代码。考虑一个具有代码路径的模块,该模块将无法通过更严格的编译时检查,但它正在用于从未遇到这种情况的系统中。如果它开始无法在较新版本的编译器上编译,那么在编译器升级后将无法部署该系统。一般来说,这意味着执行的检查应该随着语言版本的变化而变化。(这仍然意味着人们在编写代码时应该声明他们正在编写的语言版本,请注意。)
- 在编译时进行的更多检查将“肯定避免运行时成本”可能是正确的,但这并不是一件容易的事。托管运行时不能盲目地相信它给出的字节码中的承诺,因为这可能导致内存安全违规(导致 SIGSEGV 或更糟)。这在 Raku 之类的语言中非常明显,其中类型检查的语义是可编程的,但在 JVM、CLR 等中却是这样。Raku 中与类型相关的最大优势来自使用本机类型,这可以避免大量分配,从而避免垃圾收集工作。
- 实施进一步的检查将增加编译器的复杂性以及编译所需的时间。其中第一个已经是一个问题。大约十年来,编译器前端没有看到任何重大的架构变化。当前为宏奠定基础的 RakuAST 工作还涉及对编译器前端的近乎重写。改进后的架构应该可以简化实现进一步的编译时类型检查,但也考虑了如何并行化编译的各个方面,这可以让编译器在不增加挂钟编译时间的情况下做更多事情。
当前编译器前端大修完成后,似乎很有可能引入更多编译时检查(但仅从下一个语言版本启用) - 至少,只要有人在它上面工作。
然而,在这个领域还有一个更令人兴奋的机会出现:因为将有一个用于 Raku 程序的 API,并且随着定制编译器通行证的计划一起出现,很快也可以将类型检查器实现为模块!其中一些可能会导致检查,使其成为未来的 Raku 语言版本。其他的可能是特定领域的,旨在更正确地使用给定的模块。其他人可能会强制执行不符合基本语言精神的严格要求,但某些语言用户可能希望选择加入。