JSCIG / js-class-fields-chinese-discussion

JavaScript的『class fields』提案中文讨论
127 stars 20 forks source link

建议缩小反对范围 #23

Closed LongTengDao closed 5 years ago

LongTengDao commented 5 years ago

以 public field 为例,目前列出了 [[define]] 问题,[key] 二义问题,; 风格问题,但实际上这些问题无论解决了哪个,剩下的都会更尖锐,除非全套费了。

但其实单独看的话,define 是很合理的,因为 set 很容易用传统的 constructor 中 this.key=value 的方式实现,相反自行用 defineProperty 实现 define 则麻烦又慢。

而只要修改一处,剩下的反而就都不是问题了,就是 =。目前的全套做法都像是对象字面量声明,而那种情况下,从来都是 define,而且结尾用 , 也就不存在改变 ; 习惯的问题了,大家总是会写 , 结尾,同时 [key] 也不存在二义了,对象字面量的方法写法和类实例方法写法也统一了(仅是写不写 , 的区别)。只不过由于 ts 用掉了 :,这里没法简单把 = 换掉完事,但这依然是问题的关键。

如果不集中矛盾到小点上并给出简单的替换建议,而是单纯列出所有的矛盾证明现在问题很大,很可能不会被采纳吧……毕竟现在列出的所有问题的单纯相反的做法,相互之间并不兼容。

考虑到省略 ;, 的需求,我想了种语法,仅供参考:

class C {
    propertyA #( value )
    [propertyB] :type #( value )
    method () {}
}

不用括号是无论如何无法省略结尾 ;, 的,除非此上下文中,行末默认强行断句。如果用括号,三种括号中另两种都会造成新的二义语法,而直接小括号本身又和 ts 的方法重载语法冲突,所以只能再加个前缀,这里我随手选了个 #,或许有更好的选择。

如果支持行末强行断句,那问题会简单一些(毕竟括号比 ;, 还啰嗦,还不如用 ;,):

class C {
    propertyA # value
    [propertyB] :type # value
    method () {}
}
hax commented 5 years ago

实际上这些问题无论解决了哪个,剩下的都会更尖锐,除非全套费了。

应该这样说,单独解决了某个,会使得一部分原本不接受的人接受这个提案了。对于整体上反对提案的人来说,可能是『剩下的问题更棘手』。按理说,该提案的champion应该采取这种策略(分化反对者)。但我说过,过去的讨论和会议上,所有我们讨论过的issue没有一个得到哪怕一点点缓解,即使为此只需要做一点点改动。因此无论我们(或者各位)的目标是什么,采取哪种策略,结果都是一样的——就是失败。

但其实单独看的话,define 是很合理的,因为 set 很容易用传统的 constructor 中 this.key=value 的方式实现,相反自行用 defineProperty 实现 define 则麻烦又慢。

这确实是一个用 define 的理由(想用set的可以用老方式,而想用define的过去很麻烦),但是有两个重要的问题:

  1. define造成的footgun(define own property与基于prototype的accessor的冲突)没法解决,这纯粹是一个语义问题,无论语法怎么改,都是解决不了的。
  2. 从过去的经验来看,几乎没有人主动用define。当然我们可以说是因为写起来麻烦,这当然可能是一个原因,但仍然首先需要证明这种需求是真实的,否则就是一个伪需求。如果没有真实需求,那么无论define看上去有多么合理,都不能构成充分的理由。

你后面的思路其实有人探讨过类似的可能性,比如

class {
  foo = { initializer }
}

或者用圆括号也可以。

但问题是,所有这类修改建议都无法通过。

如果不集中矛盾到小点上并给出简单的替换建议,而是单纯列出所有的矛盾证明现在问题很大,很可能不会被采纳吧……

我已经解释过,无论是小修改建议,还是大改建议,反正按之前的经验看,都是过不了的。所以现在我只列出所有的问题,并不考虑任何具体的修改建议(至少不是重点)。

LongTengDao commented 5 years ago

我已经解释过,无论是小修改建议,还是大改建议,反正按之前的经验看,都是过不了的。所以现在我只列出所有的问题,并不考虑任何具体的修改建议(至少不是重点)。

这我始料未及。。这么说这个 repo 目前最大的意义是为了该提案正式成为规范后,把危害尽量降到最低,让广大程序员对其有充分的认识?

hax commented 5 years ago

为了该提案正式成为规范后,把危害尽量降到最低,让广大程序员对其有充分的认识?

部分是这样。

但我之前可能没有完全表达清楚,前面讲的是之前所有的情况。但现在有一个不同,就是360已经是TC39的成员,因此我们是可以阻止该提案成为标准的,当然代价是break在我们成为会员之前已经达成的consensus。

LongTengDao commented 5 years ago

噢噢。那现在的目标,是简单阻止新提案,还是提可行的建议引导 ES 继续进化?

我看有讨论到 classes 2.0,是 1.1 被否决后的新建议吗?您认为它是全面更优,还是只是部分解决了目前的问题,但本身同样有问题?我只找到了 1.1 的 repo,2.0 的通过各种方式目前还没有搜索到

hax commented 5 years ago

当前的目标是『在没有 alternative 提案的前提下』阻止 class fields 提案进入标准。因为之前所有基于『alternative 提案』的动议都失败了。

故虽然我有考虑一些新的替代方案(classes 2.0是其中之一),但并没有公开,因为即使我们都认可某个替代方案(如classes 2.0)确实比当前提案要好,也几乎不可能在委员会达成一致意见(所有人都同意一个替代方案比当前的好),这里有几个因素:

  1. 有些TC39代表可能坚持认为某些需求是必须的,而我们认为是可以被tradeoff的
  2. 理论上说,新的替代提案对于现有提案的champion和支持者来说是有利益冲突的,这是流程缺陷(即流程假设了每个tc39代表都只从纯技术角度去决定立场,而不掺杂个人情绪,但这极难保证)