如何看待go语言泛型的最新设计?
用圆括弧 + type关键字来做type abstraction好吗?
我觉得这是很好的,远比尖括弧好。首先看到括弧向前看一次就完事,没有ambiguity(也就是parser架构不会太复杂。连关键字都觉得影响速度则完全不可理喻)。其次「type」是关键字,高亮出来辨识度也够高。而且type abstraction和value abstraction遵循类似的语法也是很consistent的。事实上在OCaml也可以这么干:
fun (type a) -&> …
所以这个type abstraction没毛病。
用圆括弧做type application好吗?
不行啊,完全不行啊(大雾。看看上面type abstraction的优点:
- 没了type关键字,说好的parser要快呢?
- 没了type关键字,你让我怎么一眼区分type/value application呢?指望semantic highlighting?
- 和type abstraction的consistency去哪了呢?
让我们再看看OCaml… 哦,人家没有type application,人家可以全部推断出来(弱是原罪(指type system
所以你都搞出个挺不错的type abstraction语法了,type application这么搞是想不开吗?type application也要求个type关键字很难吗?什么?boilerplate?Go会担心用户写的boilerplate太多么(雾
总结:type abstraction和application都要求type关键字我就开吹了,只搞一半就让人心情复杂……
为了保证编译速度而不引入新的符号著实没看懂,我寻思这也几乎影响不了什么编译速度,最影响编译速度是后端,纯粹是编译器团队懒得改 parser 的借口罢了,好一个大道至简,编译器团队的工作量的确大减,不过和用户没什么关系。
Foo(int, int)(a, b)
不过这么设计下来自己给自己挖坑,用 &
其实都已经有潜在的 generics instantiation 和 tuple construction 的二义性问题,这倒好直接用()
,我倒是对 Go 以后如何处理 generics instantiation 和 currying function call 的二义性挺感兴趣的。
不过我觉得处理方式大概率会是:「Go 是工程语言,大道至简,不需要这些特性」
更新:
Go 团队果然发现了二义问题,现在要给类型参数加 type 关键字,逐渐变成了 VB 的样子。
再次更新:
Go 团队已经决定把小括弧换成中括弧了,官方打了那些口口声声说用小括弧好的人的脸,不过官方就这么不想加新的 token 吗(逃
知乎这个问题提问的时候的「最新设计」是指:https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-contracts.md 也就是以contract的概念去实现泛型。
但contract这个方式在9月下旬已经被官方放弃了,现在最新设计是:https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md 即以类型参数的来实现泛型。
从语法上看,前一份基于contract的设计,泛型函数要这么定义:
func Print(type T)(s []T) {
// same as above
}
而最新的类型参数则是:
func Print[T any](s []T) {
// same as above
}
区别在于:
- 木有type关键字
- 不使用小括弧,改成方括弧
这个问题下很多回答都是在吐槽上一份设计中使用小括弧,质问官方为什么不像Java等语言那样使用尖括弧,这个问题go官方在新设计中也给出了更为详细的回答。
go是支持多重赋值的,如果使用使用尖括弧的话,那么可以参考下面的代码例子:
a, b = w &< x, y &> (z)
上面的代码在不知道w的类型的时候,实际上是具有二义性的,它如果是一个变数,那么上面这行代码可以被认为是:
- w 跟 x 比较,然后赋值给a
- y 跟 z 比较,然后赋值给b
而如果是w是函数的话,那么则是:
- 将x, y作为泛型类型参数,z是参数
- 调用w函数
- 函数会有两个返回值分别赋值给a 跟 b
所以,如果要使用尖括弧的话,go编译器在做语法解析parsing的时候,便需要获得变数的类型信息,而这对于go的编译器来说是一个非常关键的设计决定。
我感觉go官方既懒得给编译器做大改,也不觉得改完之后会更好,因此就采用方括弧这一方案啦~
突然想起朋友的一个评价
「Go 通过把语法搞得极丑从而造就一种自己很底层的错觉」
实际上自带runtime/vm 还不如JVM battle tested
有点儿圆胖肿
推荐阅读: