编程与软件工程arp242.net
Go 并不是一门简单的语言
Go is not an easy language
2021 — 2024,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
作者通过一系列具体例子论证 Go 并不像宣传的那样“简单易学”:从切片删除元素、错误处理到并发模式,许多看似基础的任务在 Go 中要么繁琐、要么暗藏陷阱。文章认为 Go 的“简单”更多是把复杂度转嫁给了使用者,而非真正消除了复杂度。
为什么经久不衰:它挑战了“Go 简单”这一流行叙事,且多年后(2021、2024 两次上首页)围绕语言易用性与显式性的争论依然没有定论,值得每个选型或学习 Go 的人对照思考。
HN 评论精选
易用性是语言最重要的属性,但入门门槛对圈内人不可见,导致社区长期忽视它。
入门门槛是看不见的——对圈内人如此,对制造这些门槛的人更是如此。我曾和一位创始人聊他们的注册流程,第二步竟要求填信用卡号,而他们从没想过中国、非洲大部分地区的人可能没有信用卡,因为他们接触的每个人都有卡。语言也一样:如果你没教过面向大众的编程入门课,你就看不出什么重要什么不重要。你看到 foo.bar() 觉得“这就是个简单的方法调用”,却不知道这吓跑了多少人。几十年来我们社区一直在淘汰那些在意语言易用性的人,我们争论大括号该放哪,却没意识到自己已经把几十万潜在程序员拒之门外。
iandanforth查看英文原文
Barriers to entry are invisible. They are invisible to people on the inside and most frequently invisible to people who have a hand in creating those barriers. I once had a conversation with a founder about their signup flow. This founder had aspirations to be a global player. They said that step 2 of their flow included entering a credit card number. I had to stop them. "What about people who don't use credit cards?" They were nonplussed. "You know, China, much of Africa ..." they had never actually thought about whether people had credit cards because every single person they interacted with had one. Back to languages. If you've never taught an introduction to computer programming for a general audience you are blind to what does and does not matter about a language. You look at things like `foo.bar()` and think "Yeah that's a simple method invocation" and have no idea how many people you just lost. Never underestimate how much ease of use matters. We, as a community, have selected for decades against people who care about language ergonomics because they get hit in the face with a wall of punctuation filled text and turn away. We fight over where braces belong while not realizing how many hundreds of thousands of people we've excluded. Ease of use is the most important part of a language. It's just that the barriers to entry are invisible and so the people who happen to be well suited to vim vs emacs debates get to talk while the vast majority of potential programmers are left on the outside. We create barriers to entry accidentally because we design for people like us. To us the barriers are invisible.
Go 的问题更多是缺少常用模式的标准库支持,而非语言本身设计缺陷。
按文章第一个例子,我写 list.delete(value) 时意识不到它涉及线性搜索,这反倒被算作 Go 的优点。不过我同意 Go 可以在保持高效的同时增加一些符合人体工学的便捷方法。并发那节的例子其实有别的解法:Go 给了你所有工具,只是缺一些近年流行的模式进入标准库或 cookbook——比如 worker 模型可以起 3 个 goroutine 从同一个 channel 接收;worker 返回数据时读取本身就是等待;也可以用 sync.WaitGroup 同步完成状态;用 close(channel) 表示工作结束。设计并发系统本来就复杂,有些教程让人以为一个 go 关键字就够了,这些都可以通过改进标准库解决。
harikb查看英文原文
Going by their first example, the fact that I couldn't write list.delete(value) without realizing it involves a linear search is considered one of the benefits of Go. That said, I agree Go could use a bit for ergonomic and handy methods, while still remaining efficient. The example on Concurrency also has a different answer. Go gives you all the tools, but there are many different ways their problem can be solved. By explicitly avoiding a "join" method and having any default 'channels', Go makes all these possible. What is missing is some of the popular patterns that emerged in the last few years need to make it to into stdlib or some cookbooks. 1. If you want a worker model, I would start n=3 go-routines and they all receive from a single channel. They don't need to much around with a channel of buffer 3, as in the example. 2. If the workers already return data from a compute, the read from driver serves as the wait. 3. In other cases, there is sync.Waitgroup available to synchronize completion status. 4. End of work from the driver can be indicated via a channel close. Closed channels can still be read from until they are empty and the reader can even detect end-of-channel. Designing concurrent system is a bit complicated. Some tutorials do make it sound like a `go` keyword is all you need. All of these can fixed by improving std-lib or cookbooks.
Go 的价值不在“容易”而在“简单可推理”,特性少反而是一大优势。
没人说过 Go 容易,它只是简单、易于推理。代码行为和字面意思完全一致、没有隐藏行为、没有过度复杂的语法,这是巨大的好处。我从 C# 过来,对语言不断堆砌新特性越来越沮丧:现在有 class、struct 和 record,有 async/await 又有 channel——工具箱太大就是这个结果,不同人用不同特性写代码。在 Go 里我知道并发只有两种方式:goroutine 加 mutex,或 goroutine 加 channel。泛型会带来很多以前写不了的辅助函数,消除重复代码。除此之外我写 Go 非常开心,现代 Java/C# 让我烦恼的东西全没了。
Philip-J-Fry查看英文原文
But no one said Go was easy. It's just simple and easy to reason about. There's a huge benefit to something doing exactly what it says. No hidden behaviours, no overly complex syntax, nothing like that. I came from C# where I have gotten increasingly frustrated with the amount of additions to the language. Like we now have classes, structs and records. We now have async/await but we also have channels. This is what having a huge toolbox causes. Some people are going to write code using channels, me others will use async. Some people will use features that others don't care about. I think there's huge benefit in a simple language. In Go I know that there's only 2 ways to do concurrency. You either use go routines and mutexes or you use go routines and channels. Generics will bring a lot of helper functions that weren't possible before which will remove a lot of repetitive code. But otherwise I am super happy with writing Go code. All my pet peeves of something like modern Java or C# are gone.
从外部读者视角看,Go 的“简单”反而降低了代码可读性。
作为一个 Go 经验不多的人,我在实际中遇到的不少 Go 代码,反而比更复杂语言里的代码更难读——因为我得逐个理解那些模式。希望泛型的加入能改善这一点。但在我看来,Go 的简单实际上妨碍了可读性。
thayne查看英文原文
As someone without a ton of experience with Go, a good amount the Go code I have encountered "in the wild", has actually been more difficult to read and understand than code in more complicated languages because I have to read through and understand all of these patterns. Hopefully the addition of generics will help with that. But IMO the simplicity of go actually hinders readability.
历次讨论
同类还值得读
开源应用架构
The Architecture of Open Source Applications
《开源软件架构》(AOSA)是一本在线免费书,邀请知名开源项目的作者亲自剖析其内部设计,涵盖 SQLAlchemy、LLVM、Audacity、Apache、Bash 等系统。
编程与软件工程上首页 9 次 · 2011–2024aosabook.org编辑精选编程语言简史:简短、不完整且多半错误
A Brief, Incomplete, and Mostly Wrong History of Programming Languages
一篇以戏谑、故意不准确的方式回顾编程语言史的博客文章,用夸张轶事和讽刺定义串起 Lisp、C、C++、Java、JavaScript、PHP 等语言。
编程与软件工程上首页 8 次 · 2009–2021james-iry.blogspot.comSQLite 是如何测试的
How SQLite is tested
SQLite 官方文档页,系统介绍 SQLite 的测试体系:多种测试方法(TCL 测试、模糊测试、回归测试、静态分析等)和海量测试用例,展示了这个小型开源项目如何靠极致测试获得…
编程与软件工程上首页 8 次 · 2009–2025sqlite.org编辑精选高级编程语言(2009)
Advanced programming languages (2009)
Matt Might 的经典文章,按用途推荐“高级编程语言”:如果追求就业就选主流语言,如果追求表达力、学术研究或创业,则推荐 Haskell、OCaml、Scala 等函数式语…
编程与软件工程上首页 8 次 · 2009–2022matt.might.net我的 Forth 与栈机器经历
Yosefk - My history with Forth & stack machines
作者以亲身经历回顾了使用 Forth 语言和栈式机器的历程:既赞叹其简洁优雅、代码量小、可自举的优点,也坦率指出栈操作在实际编程中的痛苦,以及 Forth 社区文化中的问题。
编程与软件工程上首页 8 次 · 2010–2024yosefk.com编辑精选