三足鼎立 hdu
我经常争辩说,语言,库或框架的良好设计并不是要在解决方案中尽可能多地包含功能,而是要发现一小部分相互关联的功能,以相互促进。 也就是说,我们希望最大化解决方案的功能/表达能力,同时最小化表面积。 此外,我经常愿意为了优雅而牺牲一些灵活性 。 我认为,优雅的解决方案更易于学习,更令人愉悦且易于抽象。
考虑到这一点,我想考虑一下语言设计师至少已经研究了二十年的问题:如何将子类型多态与参数多态 (泛型)结合起来。 这是任何带有静态类型的面向对象语言都面临的核心问题。 最近的语言已经逐渐接近令人满意的解决方案,但是我想提出,如果听起来不太自私,则锡兰提供了迄今为止最令人满意的解决方案。
我们的吉祥物是Trompon大象,因为大象有四只脚,如果一只脚失踪了,它会掉下来。 锡兰的字体系统就是这样! (是的,这是一个平衡面。)
类型系统的四个分支是:
- 申报地点差异
- 临时联合和交叉点类型
- 基于主体类型的类型推断
- 协变细化和主体实例继承
如果我们要去除这四个特征中的任何一个,突然的东西,Just Works根本就不再起作用了,或者即使我们能够使它起作用,结果也会变得更加复杂,并涉及推理程序员难以复制。
考虑下面这行非常简单的代码:
value animals = ArrayList { Cat(), Dog(), Person() };
推断的animals
类型为ArrayList<Cat|Dog|Person>
。
- 如果我们要删除声明位置的协方差,则不能将
animals
分配给List<Animal>
。 - 如果要删除联合和交集类型,则推断类型实参的过程将是模棱两可的,并且会更加复杂。 (在语言规范的两页伪代码中定义了锡兰的类型自变量推断算法,这听起来很像,直到您意识到该算法在其他语言中是有问题和未充分说明的,并且该算法的实际实现并不多更长)。
- 如果要取消类型推断或主体类型,则需要在此代码行中明确写下一些不感兴趣的类型。
除去这些特征中的任何一个,我们剩下的是三足大象 。
主体实例化继承是Ceylon的一种隐藏功能,尽管我们在容器类型的整个设计过程中都广泛使用它,但我们并没有太多讨论。 例如,它可以说List<Element>
是Ranged<List<Element>>
, Sequence<Element>
是List<Element>&Ranged<Sequence<Element>>
。 主体实例化继承与声明站点协方差以及临时联合/交叉点类型的结合非常好。 考虑以下代码:
List<String>|Integer[] ranged = ... ;
value span = ranged.span(0,max);
在此, span
的推断类型为List<String>|Integer[]
。 那不是很好吗? 所述typechecker已推断的主超类型实例化 Ranged
对List<String>|Integer[]
是类型Ranged<List<String>|Integer[]>
并且从而确定用于完美返回类型span()
如果我们要删除声明站点协方差,主体实例继承或联合类型中的任何一种,那么这种推理将不再成立。 大象会掉在他的屁股上。
翻译自: https://www.javacodegeeks.com/2013/12/on-three-legged-elephants.html
三足鼎立 hdu