用圆括弧 + type关键字来做type abstraction好吗?

我觉得这是很好的,远比尖括弧好。首先看到括弧向前看一次就完事,没有ambiguity(也就是parser架构不会太复杂。连关键字都觉得影响速度则完全不可理喻)。其次「type」是关键字,高亮出来辨识度也够高。而且type abstraction和value abstraction遵循类似的语法也是很consistent的。事实上在OCaml也可以这么干:

fun (type a) -&> …

所以这个type abstraction没毛病。

用圆括弧做type application好吗?

不行啊,完全不行啊(大雾。看看上面type abstraction的优点:

  1. 没了type关键字,说好的parser要快呢?
  2. 没了type关键字,你让我怎么一眼区分type/value application呢?指望semantic highlighting?
  3. 和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


有点儿圆胖肿


推荐阅读:
相关文章