CircleCI最近出版了一本非常有用的帖子“ 为什么我们不再使用Core.typed ”这引起了一些WRT重要的关注类型化Clojure的 ,在他们的特定情况下导致的成本增持的好处。 CircleCI与core.typed的主要作者Ambrose Bonnaire-Sergeant有着长期而积极的关系,后者在他最近的Strange Loop演讲“ Typed Clojure:从可选到渐进式打字 ”中解决了他们的担忧(渐进式打字也在他的著作中得到了解释6/2015博客文章“ Clojure的逐步键入 ”)。 为了便于搜索,以及我们中的一些人喜欢文本而不是视频,我想总结一下答复的要点(并附有自己的想法)。
顾虑
(应该注意,CircleCI具有相当大的代码库,带有〜90个类型化的名称空间。)
- 检查速度慢–如果您处理多个文件,则需要重新扫描所有文件,这在大型项目上需要很长时间
- 类型化和非类型化代码的混合,并因此将类型与:no-check一起使用会导致保证减弱; 既可以在自己的代码库中进行,也可以在与无类型库进行交互时使用(请参阅#4)。
- 有些表达式无法按类型输入(获取,…),并且很难区分错误是由core.typed的限制还是所检查代码的实际缺陷引起的
- 维护未类型化的第三方库的类型的成本很高
- 很难为某些表达式找到正确的类型签名
解决方案
简介:这种情况已经好了,逐步输入完全完成后情况会好得多。
#1慢速检查 -类型化REPL和内置在require / load中的缓存已经解决了这一问题。
Ambrose Bonnaire-Sergeant(ABS):但Typed REPL仍在开发中,“特别是,它与许多使用当前名称空间来评估特定于工具的事物(例如,自动完成)的工具不能很好地配合。 […]它没有记录和未经验证”,尽管可以将需求/负载缓存分开并单独使用,因为它不会遭受这些问题的困扰。
#2类型化和未类型化代码的混合,因此缺乏编译时保证–这可以通过在完成时逐步键入来解决,方法是将运行时检查添加到这些类型(并添加运行时检查以确保未类型化的代码不能将非法值传递给类型化的代码) )
#3不可能/难以键入的表达式 –尽管我在Google小组中看到社区一直在思考能够键入更多Clojure习语的方法,但我认为对话中并未解决这个问题。 我的想法: 这里应该是对这些内容的一流支持,即一种众所周知的,得到良好支持且易于使用的方法来解决这些问题。 类似于外部无类型代码的解决方案,我们提供了自己的类型签名并将其标记为“:no-check”。 (尽管我显然不知道针对类型无法检查的表达式的特定问题的解决方案是什么。)而且,应该不应该修改错误报告以清楚地区分由core.typed的限制和缺陷引起的错误。代码正在检查中。
ABS:“自2013年以来,这方面最重要的工作(即在编译时支持更多习语)一直在增加。需要大修才能将CircleCI用作示例的挑战。”
#4维护第三方库类型签名的成本 –这仍然是昂贵的,但由于这些类型将变成运行时保证,因此更加有价值和可靠。 我的想法:这与使用Prismatic Schema没什么不同,您还需要检查外部代码是否符合您的合同。
ABS:一个有趣的想法是将现有的模式注释转换为具有它们的库的core.typed。
#5难以找到更复杂功能的正确类型签名 -尚未解决。 我的想法:尽管现在可能不在主要关注范围之内,但探索类型无疑更容易引起探索。 最好通过一些魔术盒运行一个函数,并提供一些用法示例,然后为它返回类型签名:-)
ABS:“我个人目前最感兴趣的是使用编译时数据来推断类型,如果可能的话,这将再次需要进行大修。 您的建议已在实践中成功使用,请参见DRuby 。 我想知道这种方法是否适用于典型的Clojure代码。 当跨越函数边界时,许多Clojure程序中的IME类型不是多态的或高阶的,函数通常带有映射或其他简单的值,因此可能值得研究。
结论
Core.typed在许多情况下都是相关且有用的。 随着逐步打字的发展,它将在基于混合类型-非类型代码的基础上变得更加强大和有用。
有用的其他资源
- 核心类型的电子邮件组-f.ex. 从7/2015 开始 “ core.typed的未来方向 ”
- Wiki:core.typed的局限性
- 核心类型的吉拉