未装箱类型上的高级多态


10

我有一门语言,默认情况下会将类型取消装箱,并且基于Hindley–Milner进行类型推断。我想添加更高级别的多态性,主要用于处理存在类型。

我想我知道如何检查这些类型,但是我不确定在编译时该怎么做。目前,我通过生成专门化来编译多态定义,就像C ++模板一样,以便它们可以与未装箱的值一起使用。例如,给定的定义f<T>,如果程序仅调用f<Int32>f<Char>,则仅那些专门化内容会出现在已编译程序中。(我现在假设是整个程序的编译。)

但是当将多态函数作为参数传递时,我看不到如何静态生成正确的专业化,因为可以在运行时选择该函数。除了使用方框表示法,我别无选择吗?还是有办法解决这个问题?

我的第一个想法是以某种方式将等级n多态编码为等级1,但我一般认为这是不可能的,因为构造逻辑中的公式不一定具有先验范式。


另一种选择是通过存储位图来减少所需的装箱量,对于这些位图,函数的参数和内存中的单词是指针。然后,多态函数/结构实际上是指针数据的任意字上的多态,并且结构可以内联存储其最后一个字段(即使它是多态的)。GC也可以使用这些位图来避免非和类型使用标记词。
fread2281

@ fread2281:我实际上曾经在旧版本的语言中做过类似的事情。我目前不为非和类型生成标签,并且没有GC。我认为这也与Neel K的方法兼容。
乔恩·普迪

Answers:


6

我对此有所考虑。主要问题是,一般而言,我们不知道多态类型的值有多大。如果您没有此信息,则必须以某种方式获取它。单态化通过专门消除多态来为您获取此信息。装箱将一切放入已知大小的表示形式中,拳击为您提供此信息。

第三种选择是跟踪这些信息的种类。基本上,您可以为每种数据大小引入不同的种类,然后可以在特定大小的所有类型上定义多态函数。我将在下面概述这样的系统。

Kindsκ::=nType constructorsA::=a:κ.A|α|A×B|A+B|AB|refA|Pad(k)|μα:κ.A

在这里,高层次的想法是类型的类型告诉您将一个对象布置在内存中需要多少个单词。对于任何给定的大小,很容易在该特定大小的所有类型上实现多态。由于每种类型(甚至是多态类型)都具有已知的大小,因此编译并不比C难。

α:nΓΓα:nΓ,α:nA:mΓα:n.A:m
ΓA:nΓB:mΓA×B:n+mΓA:nΓB:nΓA+B:n+1
ΓA:mΓB:nΓAB:1ΓA:nΓrefA:1
ΓPad(k):kΓ,α:nA:nΓμα:n.A:n

A×BAB

引用很有趣-指针始终是一个单词,但是它们可以指向任何大小的值。这使程序员可以 通过装箱将多态实现到任意对象,但不需要 它们这样做。最后,一旦显示了明确的尺寸,引入填充类型通常很有用,该填充类型使用空间但不执行任何操作。(因此,如果要采用一个int和一对int的不相交的并集,则需要在第一个int处添加填充,以使对象布局统一。)

递归类型具有标准的形成规则,但是请注意,递归出现的大小必须相同,这意味着您通常必须将它们放在指针中才能进行分类。例如,列表数据类型可以表示为

μα:1.ref(Pad(2)+int×α)

因此,这指向一个空列表值,或一对int和一个指向另一个链接列表的指针。

对这样的系统进行类型检查也不是一件容易的事。我的ICFP论文中的算法与Joshua Dunfield的“ 用于较高等级多态性的完全和容易的双向类型检查”一起适用于这种情况,几乎没有任何变化。


太酷了,我认为这很好地涵盖了我的用例。我知道使用种类来推理值表示形式(例如GHC的*vs. #),但是没有考虑过这样做。将排名较高的量词限制为已知大小的类型似乎是合理的,而且我认为这也将使我能够静态生成按大小的专业化分类,而无需知道实际的类型。现在,该重新阅读该论文了。:)
乔恩·普迪

1

这似乎比“理论计算机科学”问题更接近于编译问题,因此您最好向别处询问。

实际上,在一般情况下,我认为没有其他解决方案可以使用方框表示法。但我也希望在实践中,根据您情况的具体情况,会有许多不同的替代选择。

例如,未装箱的参数的低级表示形式通常可以归类为很少的选择,例如整数或相似,浮点或指针。因此,对于一个函数f<T>,也许您真的只需要生成3个不同的未装箱实现,就可以将多态的表示为这3个函数的元组,因此将T实例化为Int32只是选择该元组的第一个元素,...


谢谢你的帮助。我不确定要问哪里,因为编译器的范围从高级理论到低级工程,但是我发现周围的人会有一些想法。看来拳击确实是这里最灵活的方法。在阅读了您的答案并进行了更多思考之后,我能够提出的唯一其他合理的解决方案是放弃一些灵活性,并要求静态知道多态参数,例如,将它们本身作为类型参数传递。一直在权衡取舍。:P
乔恩·普迪

4
OP的问题包含完全有效的TCS问题,例如当Damas-Hindley-Milner用更高等级的类型扩展时如何进行类型推断。通常,等级2多态性具有可确定的类型推断,但对于等级k> 2,类型不可推断。我不知道Damas-Hindley-Milner的限制是否会改变这一点。最后,现代编译器所做的几乎所有事情都应成为TCS的一部分,但通常不是因为编译器实现者领先于理论家。
Martin Berger
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.