关于《我为什么放弃Go语言》的讨论

lovegolang · · 6797 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

CSDN 上有一篇文章 [《我为什么放弃Go语言》](http://blog.csdn.net/liigo/article/details/23699459),在 golang-china 讨论组引发了一些讨论,为了便于墙内 gopher 们阅读,选择了一些有价值的评论发在这里。(重点关注 minux 大神的回复) 刘鑫: 无所谓啦,本来就是个工具语言,没必要人人都去拜。对自己好用,就用实际行动来支持,这不比打嘴炮好多了。从来没有一门编程语言能让所有人都满意。何况人家文章里有些东西写的还是挺有道理。特别是社区的态度问题。去年我说某IDE的插件不能识别不可达的逻辑,一大群人出来教育我说go语言本来就这么设计的。只有巢鹏一个人的博客上写着这是go官方2009年就明明白白列出来的一个bug。现在不但那个bug修掉了,我要是再写同样的代码,go的工具还会发警告…… minux: 不存在一种语言能适合每个人,恩。 早点意识到某个语言不适合自己是个好事。(如果意识到之后不去对应的列表 trolling 就更好了。) 在不适应所有人这个问题上,Go 比其他的语言更严重,因为Go作者们非常“顽固”,在他们认为的原则问题上绝不让步。所以Go终究只能适应和他作者意见一致(或者至少是能够理解)的人。不过幸好作者们的意见一般是对的。 尽管 Go 支持 Windows,而且我也认识一些在 Windows 上开发 Go 或者用 Go 开发的人,但是理解 Go 还是需要先理解 Unix(最好是 Plan 9)的设计理念。 chai2010: 有语言能是完美的, Go也是一样. 作者提到 "很多言行都是“反开源”的。", 我到觉得开源软件集权的好处远大于坏处. 开源主要给你的是fork的权利. 比较认同的几点抱怨: 1.3 极度强调编译速度,不惜放弃本应提供的功能 1.8 对象没有构造函数和析构函数 1.10 许多语言内置设施不支持用户定义的类型 1.11 没有泛型支持,常见数据类型接口丑陋 编译速度快是好事, 但是如果因为编译速度而严重影响语言的特性设计就不好了. 不知道后面的 语言内置类型和泛型 支持限制是否是受编译速度的限制. 关于资源析构, 之前cgo中, 都是用 runtime.SetFinalizer 来增加一层保障. 但是前几天 golang-dev 居然有人讨论要干掉 runtime.SetFinalizer ... 我觉得最不爽的地方还是在泛型/运算符重载/内置的特权类型等方面. 当然 IDE 也是很让人不爽的一个地方. 最后, 最喜欢的还是Go的简洁但不简单. minux: 对于 GOMAXPROCS 的问题,参看 http://golang.org/doc/faq#Why_no_multi_CPU “版本都发展到1.2了,goroutine调度器依旧默认仅使用一个系统线程。” 这个不确切。即使 GOMAXPROCS == 1,也可能创建任意多(受限于 runtime/debug.SetMaxThreads 的限制,默认 10k)的系统线程的(只是任意时刻只有一个线程能执行Go 代码而已),而且也不一定只有一个线程在执行,比如 cgo 或者GC 都是能够让 GOMAXPROCS == 1 的 Go 进程使用超过 1 个 CPU 的。 “GOMAXPROCS的长期存在似乎暗示着官方从来没有足够的信心,让调度器安全正确的运行在多核环境中。这跟Go语言自身以并发为核心的定位有致命的矛盾。“ 这个推论就完全错误了。即使是 GOMAXPROCS == 1,Go 的调度器也是完全 concurrent 的。而且关于 runtime 调度器的优化的工作都是同时比较 GOMAXPROCS == 1, 2, 4, 8, 16, 32下的性能的。 确实,GOMAXPROCS > 1 的话存在 data race 的问题,但是这完全跟调度器无关,存在 data race 的程序本身结果就是 undefined(在 C++ 11 里面其实也是这么说的)。默认设置 GOMAXPROCS 为 1 跟这个一点关系也没有。 之所以 GOMAXPROCS 默认是1,主要的原因是,concurrent != parallelism。不是所有 Go程序在 GOMAXPROCS > 1 都能提速的,参见 http://golang.org/doc/faq#Why_GOMAXPROCS 如何让 runtime 自动设置 GOMAXPROCS 来达到最佳的性能是个困难的研究课题。 (注意到,程序的执行 pattern 是会改变的,如何知道何时应该提高 GOMAXPROCS? 另外,channel 的用法有非常多的模式,如何让调度算法自动适应每个模式?还有优化 的目标是什么?很多情况下最低响应延迟和最大系统吞吐量是不可兼得的,如何让用户 选择/影响优化目标? 恩,如果你还觉得这个问题很简单,那恭喜你,欢迎仿真并在 golang-dev 发布你的设计 文档。不过我个人建议你先把这个算法写成论文发表。) Go 目前做的是尽可能优化 GOMAXPROCS 在一定范围内(1~32或者64?)的 runtime 性能,然后由用户决定到底用几(一般需要 benchmark 才能知道)。 鉴于对于不同的应用的 GOMAXPROCS 的最佳值不确定,官方也不建议在 .bashrc 之类 的地方设置全局 GOMAXPROCS > 1。 minux(对chai2010的回复): ft 我本来克制自己不去看这篇文章,不过看来都被引用过来了。不过既然有人赞同,就值得讨论一下。 没有语言能是完美的, Go也是一样. 作者提到 "很多言行都是“反开源”的。", 我到觉得开源软件集权的好处远大于坏处. 开源主要给你的是fork的权利. 开源软件有很多种运行模式。其中比较主要的一种就是独裁似的。纵观开源社区, 很多著名的项目都是最终核心的一个人,或者几个人有绝对的话语权。 (实际上也不存在一个成功地开源项目是完全民主的。连 committee 设计的东西 都不是完全民主的……) 如果被动地接受每个意见,那么项目很容易丧失方向性,导致各种各样的特性被 加入,但是没有一个人在总体上把握特性之间的交互。对于一个编程语言,这点 更为重要。 一个好的开源项目领导者要能说 No。 比较认同的几点抱怨: 1.3 极度强调编译速度,不惜放弃本应提供的功能 恩,强调编译速度是个特性。但是并不意味着 Go 会放弃优化(我假设优化是 属于这”本应提供的功能“之一。Rob 也说了,以后 gc 会提供 SIMD 优化。 1.8 对象没有构造函数和析构函数 1.10 许多语言内置设施不支持用户定义的类型 1.11 没有泛型支持,常见数据类型接口丑陋 编译速度快是好事, 但是如果因为编译速度而严重影响语言的特性设计就不好了. 不知道后面的 语言内置类型和泛型 支持限制是否是受编译速度的限制. 泛型的支持总是被人拿出来说事儿。关于泛型的支持,官方唯一说的就是在等一个 完美的设计。倒不全是编译速度上的考虑。 关于资源析构, 之前cgo中, 都是用 runtime.SetFinalizer 来增加一层保障. 但是前几天 golang-dev 居然有人讨论要干掉 runtime.SetFinalizer ... 不是没同意么。Dmitry 完全站在 GC 实现者的角度考虑这个问题,不免有失偏颇。 顺便说一点,他说的 SetFinalizer 的问题一个都没有错,只不过一般情况不会遇到 或者很容易避免罢了。 我觉得最不爽的地方还是在泛型/运算符重载/内置的特权类型等方面. 运算符重载绝对不会有,这是个特性,不是 bug。 内置的特权类型是因为没有泛型。泛型要想有很大可能得等 Go 1.2,假设能有人 设计出来一个完美的泛型设计。参看 http://research.swtch.com/generic。 (虽然基本上每个月在 golang-nuts 列表上都会有人宣称某个语言同时解决了文中 提到的3个问题,但是没有一个能给出具体的解决方式的,最终的讨论都归结于: ”XX 语言解决了所有的三个问题,至于怎么解决,你自己去看它的实现“) 当然 IDE 也是很让人不爽的一个地方. 这个等社区了。要知道作者们是觉得 Acme 就足够了的。 不过最近 go.tools 的发展很欣喜。Go 在语法上设计的优越性终于慢慢被 adonovan 和 gri 等发掘出来。最新的进展比如 godoc -analysis type 还有 eg,这些都将是 IDE 的核心组件。作者们大多不是搞 GUI 的(虽然 Rob 开发过若干 GUI 程序,但是他搞 的和我们理解上的 IDE 这种 GUI 完全不是一会儿事儿),所以他们能为 IDE 做的 就是提供这些基础结构,至于 UI,那就没办法帮忙了。 PS: 没有试过 godoc -analysis "type,pointer" 的人强烈建议安装 Go 1.3.1。完完全全不一样的体验。(唯一的问题是需要很多内存。) 最后, 最喜欢的还是Go的简洁但不简单. 恩 我也喜欢这个。设计一个超级复杂的系统简单(能否正常工作不一定……), 但是设计一个简单的能正常工作的系统就很难了。 (C++ 就是一个反例,C++ 很强大,但是有多少人完全理解 C++11 的方方面面? 如果我不能全部理解 C++11 标准,我如何参与 C++ 的项目? 大多数 C++ 的开源项目都刻意限制了某些 C++ 结构的使用,为什么?) chai2010: 运算符重载和泛型比, 没有也不算大的问题. 之前看过rsc的泛型文章, 说实话还是喜欢C++的方式.但是rsc说C++的方式会: "This slows compilation." 难道这个不是他们抵制这种方式的原因吗? 看了你的回复, 感觉泛型和IDE都都盼头了... minux(对chai2010的回复): 还有 bloated binary 吧。就我个人来说,我也认可 C++ 的方式。对于 Go 或许 有办法来解决这个问题(C++ bloated binary 我以为是两个原因: 1.即使是内存里面结构相同的的不同类型T1和T2,std::vector<T1>和std::vector<T2>会生成两套实现; 2.大多数目前使用的 C++ 依赖于传统的链接器,所以 C++ 编译器必须假设每个可能用到的 template 都得例化,然后依赖链接器去解决重复定义的问题。但是这个不是万能 的,rsc 的文章里提到的取消/重新规整 template 之后 .text 从若干 MB 减少到 几十 KB 就是例子。 Go 不完全依赖普通的链接器,而是拥有自己的链接器,所以其实是可以部分解决第二个 问题的(template 会导致过度的 inlining,这个问题靠独立的链接器解决不了),但是第 一个问题就比较麻烦了。 我的感觉是,相对其他方式,C++ 这个是唯一 Go 能接受的实现方式(用最常见的例子,max 函数来说,我就是希望对于不同类型例化完全独立的函数,也就是有一部分二进制体积的增长是不可避免的,相对现在手工提供maxInt32, maxFloat64来说,这个其实是一样的)。但是有几个问题 必须解决: 1. binary bloat 2. template 不是在某种意义上说不是 type safe 的。Go 显然不会引入 C++ concept 来解 决这个问题。(e.g. 使用一个 template 的时候,如果不展开 template 的内容,无法知道使用是否正确;这里似乎是使用 interface 的好机会) 3. 如何把设计和现有的 Go 特性(尤其是interface)完美地融合和交互? 我相信编译器的速度不是大问题,具体的语法也不是大问题。 (当然,不能像 D 语言那样做一个 Turing complete 的 generics 系统。换句话说,编译时 要做的事情必须是 bounded 的,也就是存在高效的实现方式) 看了你的回复, 感觉泛型和IDE都都盼头了... 我非常确定的一点是,Go 对 IDE 的(底层)支持会越来越好。(对于 IDE 感兴趣的一定要关注 go.tools sub-repository。Go Oracle, godoc, eg 这些都可以用来做 IDE 的。) 泛型完全取决于能不能有人提出满意的设计。(这个比较难) 我不知道放弃Go的文章提到没有,调试器的问题。他们决定要彻底放弃 gdb,据说,**仅仅是据说**,然后给 Go 开发一个新的。 IDE 的问题绝对不是他们不重视,实际上 http://golang.org/ref/spec#Introduction 就提到了: The grammar is compact and regular, allowing for easy analysis by automatic tools such as integrated development environments. gri 和 adonovan 看来是在专职做这方面的事情。(相比完整的 IDE,具备一个 refactor 工具,即使是命令行工具,是重要得多的事情) 我记得我昨天说过 1.4 和 1.5 的展望。大体就是,Go 要完全变成用 Go 写的(从工具链到 runtime)。 gccgo (gofrontend) 要改成支持 非 gcc 后端(换句话说就是要支持 LLVM 做后端,当然,在这之前,go 要切换到 gccgo 目前的 runtime: libgo,这样 llgo 就能完整支持 Go 语言,然后就可以开始优化了。gccgo 也会是类似的计划,先把后端独立出来,然后优化。(不过提醒一下 gccgo那边只有 2 个人。) David DENG: 做个不恰当的比喻:暗恋上了一个女神,可是一直不被接纳,结果还慢慢的发现女神很多地方其实自己并不能接受,还不肯按照自己喜欢的方式改,终于有一天决定不在一棵树上吊死,走出来了。福哉?祸哉? 我想说的是,语言不是用来崇拜或者痴迷的,不要当成女神,要当成韦小宝一样的好朋友来看。文章中提到的缺点我基本上都认为是 Go 的优点;关于 feature 的取舍方面,我刚用的时候也在 golang-nuts 上提过不少建议,应该基本上都被否决的,不过我最后佩服的是开发者对于自己信念的坚持。我个人是一个写程序很有洁癖的人,因此对于 Go 里面各种看似过于严格其实非常合理的限制很满意,呵呵。 fanflash: 我也觉的一个语言限制越严越好,这样会提高开发效率,你想想,当一个需求可以用几十种写法实现,并且相互没有非常明显的好坏时,而这时又有几个始终觉的自己是真理的人在开发组。。。。 最明显的就是花括号在是不是另起一行的问题, 其实另不另起一行都可以,只要统一就好,GO光这项,就省了多少无胃的争端。

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

6797 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传