Wild FJ 论文中类型变量和类型参数的区别?
Difference between type variable and type parameter in the Wild FJ paper?
在 2005 年 Wild FJ Torgersen 等人的论文中,第 2 节和第 3 节的第一段使用术语“类型参数”。然后3.1节第一句介绍了“类型变量”这个词。考虑到讨论它的上下文以及缺少关于 Google 的信息,我只能推测“类型变量”专门用于指代通配符。我敢肯定,这是导致在 Java.
中实施通配符的“开创性”论文
编辑:非常感谢 deduper 为编辑我的问题所做的辛勤工作!
方法foo(int x)
中使用了以下术语:
该方法有 1 个 形式参数 (int x
),尽管它通常被缩短为参数,导致潜在的混淆。 int
是 参数类型 ,x
是 参数名称 。
x
是一个 参数变量 ,尽管它通常被缩写为 参数,导致潜在的混淆。
在调用 foo(5)
中,该值称为 参数 ,尽管它是通常称为 参数值 ,缩写为 参数 ,导致潜在的混淆。当需要澄清时,它被称为实际参数。
如您所见,shorthand 对单词 参数的使用 可以表示 int x
、x
或 5
,视上下文而定。
对于泛型类型,Foo<X extends Number>
,使用类似的命名方式:
类型有1个类型参数,其中extends Number
是类型绑定 ,X
是 类型标识符 。
X
是一个 类型变量 .
当使用Foo<Integer>
时,Integer
部分被称为类型参数.类型参数可以是通配符。
不要混淆方法 parameter type
和泛型 type parameter
。
如您所见,您得出的 ""type variable" 专门用于指代通配符" 的结论是不正确的。 类型变量指的是类型参数名称,与类型参数是否绑定无关
类型变量的"actual"类型,即类型参数,可以是也可以不是通配符,因为它是在泛型类型的使用中指定的,而不是在泛型类型的定义中.
泛型类型变量仅在泛型类型的定义中被引用,类似于方法参数变量仅被引用在方法的主体中。
全文搜索显示 "type variable" 首先出现在第 2 节中:
As long as the element type is known at the call site, this may be expressed with plain generics using apolymorphic method with a dummy type variable:
〈X〉void m1(List〈X〉list) { ... }
如您所见,此示例根本不使用通配符,这与您的假设相矛盾 "type variable is used to refer to wildcards specifically".
那么,什么是类型的变量?由于该术语未在论文本身中定义,因此必须在其参考文献之一中对其进行定义。
但是哪一个?由于习惯上在首次使用术语之前包含参考文献,参考文献必须在介绍部分,从上下文来看,这句话看起来最有希望:
Parametric polymorphism — also known as genericity or generics — originated in the world offunctional programming [21]
所以我们很有可能在
中找到答案
[21] Robin Milner. A theory of type polymorphism in programming. Journal of Computer and System Sciences, 17:348–375, August 1978.
通过谷歌搜索该论文的标题可以找到包含全文的 PDF,事实上,该经典论文包含大量类型变量的示例,例如:
EXAMPLE 1.
Mapping a function over a list.
let rec map(f, m) = if null (m) then nil
else cons (f(hd(m)), map (f, d(m)))
Intuitively, the function map
so declared takes a function from things of one sort to things of another sort, and a list of things of the first sort, and produces a list of things of the second sort. So we say that map has type
((α → β) x α list) → β list
where α, β are type variables.
因此,类型变量只是一个包含类型的变量(在数学意义上)。类型变量可以通过类型参数引入,但正如 Milner 所示,类型变量也可以通过其他方式引入。 (注意 α 和 β 如何没有出现在 map
的定义中?)
当 Java 编译器执行通配符捕获时,会发生类似的情况。例如,如果我们写:
List<?> sourceList = ...;
List<?> targetList = ...;
targetList.add(sourceList.get(0));
编译器说:
The method add(capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (capture#2-of ?)
正如我们所见,在对通配符类型进行推理时,编译器"captures"将通配符的值转化为新的类型变量,例如capture#1-of ?
。与类型参数引入的类型变量不同,这些类型变量永远不会出现在源代码中。
这就是为什么在讨论通配符捕获时,Wild FJ 论文谈到了类型参数未引入的类型变量。
在 2005 年 Wild FJ Torgersen 等人的论文中,第 2 节和第 3 节的第一段使用术语“类型参数”。然后3.1节第一句介绍了“类型变量”这个词。考虑到讨论它的上下文以及缺少关于 Google 的信息,我只能推测“类型变量”专门用于指代通配符。我敢肯定,这是导致在 Java.
中实施通配符的“开创性”论文编辑:非常感谢 deduper 为编辑我的问题所做的辛勤工作!
方法foo(int x)
中使用了以下术语:
该方法有 1 个 形式参数 (
int x
),尽管它通常被缩短为参数,导致潜在的混淆。int
是 参数类型 ,x
是 参数名称 。x
是一个 参数变量 ,尽管它通常被缩写为 参数,导致潜在的混淆。在调用
foo(5)
中,该值称为 参数 ,尽管它是通常称为 参数值 ,缩写为 参数 ,导致潜在的混淆。当需要澄清时,它被称为实际参数。
如您所见,shorthand 对单词 参数的使用 可以表示 int x
、x
或 5
,视上下文而定。
对于泛型类型,Foo<X extends Number>
,使用类似的命名方式:
类型有1个类型参数,其中
extends Number
是类型绑定 ,X
是 类型标识符 。X
是一个 类型变量 .当使用
Foo<Integer>
时,Integer
部分被称为类型参数.类型参数可以是通配符。
不要混淆方法 parameter type
和泛型 type parameter
。
如您所见,您得出的 ""type variable" 专门用于指代通配符" 的结论是不正确的。 类型变量指的是类型参数名称,与类型参数是否绑定无关
类型变量的"actual"类型,即类型参数,可以是也可以不是通配符,因为它是在泛型类型的使用中指定的,而不是在泛型类型的定义中.
泛型类型变量仅在泛型类型的定义中被引用,类似于方法参数变量仅被引用在方法的主体中。
全文搜索显示 "type variable" 首先出现在第 2 节中:
As long as the element type is known at the call site, this may be expressed with plain generics using apolymorphic method with a dummy type variable:
〈X〉void m1(List〈X〉list) { ... }
如您所见,此示例根本不使用通配符,这与您的假设相矛盾 "type variable is used to refer to wildcards specifically".
那么,什么是类型的变量?由于该术语未在论文本身中定义,因此必须在其参考文献之一中对其进行定义。
但是哪一个?由于习惯上在首次使用术语之前包含参考文献,参考文献必须在介绍部分,从上下文来看,这句话看起来最有希望:
Parametric polymorphism — also known as genericity or generics — originated in the world offunctional programming [21]
所以我们很有可能在
中找到答案[21] Robin Milner. A theory of type polymorphism in programming. Journal of Computer and System Sciences, 17:348–375, August 1978.
通过谷歌搜索该论文的标题可以找到包含全文的 PDF,事实上,该经典论文包含大量类型变量的示例,例如:
EXAMPLE 1.
Mapping a function over a list.
let rec map(f, m) = if null (m) then nil else cons (f(hd(m)), map (f, d(m)))
Intuitively, the function
map
so declared takes a function from things of one sort to things of another sort, and a list of things of the first sort, and produces a list of things of the second sort. So we say that map has type((α → β) x α list) → β list
where α, β are type variables.
因此,类型变量只是一个包含类型的变量(在数学意义上)。类型变量可以通过类型参数引入,但正如 Milner 所示,类型变量也可以通过其他方式引入。 (注意 α 和 β 如何没有出现在 map
的定义中?)
当 Java 编译器执行通配符捕获时,会发生类似的情况。例如,如果我们写:
List<?> sourceList = ...;
List<?> targetList = ...;
targetList.add(sourceList.get(0));
编译器说:
The method add(capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (capture#2-of ?)
正如我们所见,在对通配符类型进行推理时,编译器"captures"将通配符的值转化为新的类型变量,例如capture#1-of ?
。与类型参数引入的类型变量不同,这些类型变量永远不会出现在源代码中。
这就是为什么在讨论通配符捕获时,Wild FJ 论文谈到了类型参数未引入的类型变量。