Other contenders I find myself sharing and re-reading:
- https://swtch.com/~rsc/regexp/regexp1.html
- https://swtch.com/~rsc/regexp/regexp4.html
At the time, the community seemed to have settled on dep - a different, more npm-like way of locking dependencies.
rsc said "nope this doesn't work" and made his own, better version. And there was some wailing and gnashing of teeth, but also a lot of rejoicing.
That makes me a bit sad that rsc is leaving.
On the other hand, I don't really like the recent iterator changes, so maybe it's all good.
Btw if you reading this rsc, thanks a lot for everything, go really changed my life (for the better).
Hope he gives us more in the future
thanks rsc
I’ve wasted so much time dealing with “module hell” in go, that I never dealt with in the prior years of go usage. I think it has some major flaws for external (outside Google) usage.
Ah, I still remember this thread:
https://groups.google.com/g/golang-nuts/c/rvGTZSFU8sY/m/R7El...
Separating the concept of pointers and nullable types is one of the things that I think go having from the beginning would have made it a much better language. Generics and sum types are a couple of others.
Ouch, who were they asking? There are so many problems from even the most simple CRUD apps where "lack of a value" must be modelled, but where the zero-value is a valid value and therefore an unsuitable substitute. This is probably my single biggest pain point with Go.
Using pointers to model nullability, or other "hacks" like using a map where keys may not be set, feel completely at odds with Go's stated goal of high code clarity and its general disdain for trickery.
I know with generics it's now trivially easy to implement your own Optional wrappers, but the fact that it's not part of the language or even the standard library means you're never going to have a universal way of modelling this incredibly basic and common requirement across projects. It also means you're never going to have any compile-time guarantees against not accidentally using an invalid value—though that's also the case with the ubiquitous (value, error) pattern and so is evidently not something the language is concerned with.
Go needs a null-like thing because the language forces every type to have a zero value. To remove the concept of zero value from Go would be a major change.
Iterators are very nice addition, even with typical Go fashion of quite ugly syntax.
Because of this change, Go 1.22 is actually the first Go version which seriously breaks Go 1 compatibility, even if the Go official doesn't admit the fact.
I think you are assuming more guarantees than are actually guaranteed.
You have a well-documented history of making incorrect claims about Go compiler and runtime behaviors, so this isn't surprising.
> since Go 1.22, you should try to specify a Go language version for every Go source file
What on Earth?? Absolutely 100% not.
I always assumed that it was considered faulty to do so.
Other than that, I agree with your comment.
If you learned idiomatic go, you can maintain and patch other libraries in the ecosystem very quickly.
Unified codestyle, unified paradigms, unified toolchain.
It's a language with harsh opinions on everything. If you manage to get over your own opinions, you'll realize that any opinion upstream is better than no opinion downstream.
That's why go's toolchain isn't as messed up as npm, yarn, grunt, gulp, webpack, parcel, babel and other parts of the ecosystem that have no conventions and are therefore as a result very expensive to maintain.
I suppose in theory it's some independent entity/commitee/whatever, but who pays the majority of the people working on it? Google?
Checking the 20 top contributors from https://github.com/golang/go/graphs/contributors
Google: 10
Unclear: 7
Tailscale: 1
Canopy Climate: 1
Isovalent: 1
Just checking the GitHub profile and not doing any deeper digging, so take it with a grain of salt.Caddy and docker pop right into my mind. I‘ve also seen databases, image processing and other nitty gritty systems programming related projects in Go.
People also love to write CLI apps in Go that do a lot of heavy lifting like esbuild or k6 etc.
The sweet spot for Go seems to be IO heavy programs. It allows for just enough control to get good performance for a lot of use cases that bleed into systems programming.
And neither Zig nor Rust have replaced C++ to any meaningful degree. Nearly everywhere it would count I still will have to deal with C++ for years, if not decades, to come.
It's interesting that the best projects have BDFLs, and that the best BDFLs are skeptical of their own power.
As compared to people who want to be leaders, for the sake of being known as a 'leader', but have neither the competency nor accountability to be leaders.
The best leaders are interested in being leaders for the betterment of their team/community, not for the clout. But people who are pushed to be leaders without being interested in that, they tend to suck and make life miserable for everyone else. Leadership is a skill, if you treat it differently, you will suck at it.
Meanwhile there's entire landfills of failed projects with single owners who couldn't bend enough. We just don't find this worth discussing.
Of course this won't happen, but a man can dream.
* Keras
* Ruby
* Clojure
* Zig
* OCaml
* Vim
* Elixir
I think all of these have ended up being unusually coherent. I may not agree with their design philosophy, but there clearly is one.
This extends well beyond OSS projects.
Despite playing around with several programming languages, Go still feels like home.
The development experience is terrific and I really appreciate how unapologetically simple and responsible the language and its creators have been.
Good luck and all the best in all your endeavours!
You're quite welcome, and thank you for this comment. I never expected when we started that Go would have such a positive impact on people's lives, bringing new people into programming and software engineering. That's definitely the impact I'm most proud of.
I do wonder, if you could re-do Go or another programming language again. What feature / changes would you add or take out.
Here is the first episode - devastating, convincing, easy to understand and very well written:
I disagree on one point that has nothing to do with Go. Python has not benefitted from GvR stepping down. The new "leadership" is non-technical, tyrannical and has driven almost all true open source contributors away.
Development has stalled except for the few corporate contributions of doubtful quality. The atmosphere is repressive and all that matters is whether you have a position of power at Microsoft/Instagram/Bloomberg.
It is not necessarily the fault of these companies. They may not know that their generosity is being abused.
Do you have some data to back that up?
The stats on Github seem to show healthy activity. 700+ merged PRs from 120+ contributors in the last month [1].
There seems to have been a big influx of new contributors in the last few years. [2]
I hate what autoformatters do to my code, but I love not having to talk about spacing anymore.
An LLM-based architecture for helping maintain OSS projects. Seems cool.
Thanks Russ.
I'm certainly thankful for golang as it made my https://github.com/purpleidea/mgmt/ project possible!
Thanks Russ!
Strongly disagree. Beyond very simple codebases lack of generics means either duplicating a bunch of code or eschewing type safety - neither of those things are particularly attractive to me. I can't imagine writing code in a strongly typed language that doesn't have support for generics.
Even if you don't use them directly it's almost certain you're using libraries that would be forced to be less ergonomic or type safe because of a lack of generics.
Type casts are checked.
> that doesn't have support for generics.
We get first class functions and compiled closures with zero syntax overhead. It's entirely manageable.
> or type safe because of a lack of generics.
Case in point: sort.Slice(). It lacks ergonomics, otherwise, entirely usable.
That being said, the generic version is faster and easier to use, so they are not without purpose, but they're not fundamental to large scale design either. Used without caution they can become a burden in and of themselves.
I like them just fine, but I could completely live without them.
I strongly disagree. Sure, like anything in programming, generics can be misused. But even comments can be misused!
OTOH I am able to build things in Go with generics that I would not be very happy building without them.
But generics as a high-level concept are wonderfully simple and useful ("let me use different types with certain code constructs without having to manually duplicate them, and stop me from doing anything that doesn't make sense"). It would be a far easier call for languages to add them if they were just a bit of syntactic sugar instead of a whole new section in the manual. (I do think adding generics was a good call; practicality trumps a fussily clean design, in my book.)
And arguably are in Go, where they are used for all kinds of things that are not inline documentation!
That doesn't look like is going to happen — the leadership change announced here seems to me to continue on the Google path. Both Austin and Cherry are relatively unknown outside Google and are to my knowledge not active in the community outside Google.
I don't believe this is true at all. They are both highly active in external Go development, far more active than I have been these past few years. (It's true that neither gives talks or blogs as much as I do.)
What does this even mean? Google basically just finances the project, but doesn't really "control" anything, never mind that "Google" isn't a monolithic entity in the first place.
And now he’s continuing the stretch of outstanding leadership by passing the torch. I can wait to see what the next 12 years of Go brings. Thanks for your service, Russ!
I trust specs[1], multiple implementations[2], and how easy it is to bootstrap a compiler[3].
[2]: https://gcc.gnu.org/onlinedocs/gccgo/ (even if feature parity isn't quite there yet)
[3]: Instead of requiring double-digits compilation steps that each take too long to be reasonable.
New Jersey vs. what? I read about that phrase sometime earlier but forgot the rest of it. Is it vs. MIT / Stanford / West Coast / other? implying worse is better vs. other?
is it also related to neat vs. scruffy approaches in AI?
too much in tech to keep track of it all.
but asking out of interest.
source?
https://news.ycombinator.com/item?id=40997745
https://news.ycombinator.com/item?id=40184763
Among others. Again I'm not saying I agree, I'm just saying you don't see the same with Go.
For example, if a language doesn't come with a built-in formatter that's a huge red flag. Go broke the tyranny of style discussions.
Easy static binaries is right up there for all new languages.
Kudos to rsc and team for all the work that went into making a great language. Good luck on your next projects.
Go is awesome and I hope it will continue to progress in that direction. Thank you Russ Cox
Go evolves slowly but steadily. No drama, no politics (external, I don't know about the internal), not social justice wars, just great technical and community work focussing on the thing at hand: A programming language and ecosystem.
Which isn't surprising to the rest of us. If you remember the days before Go, every second thread on HN was about how "company X", including the company now known as X, saw their Ruby network servers completely falling down under load, forcing a rewrite in whatever the language du-jour was that day. But Googlers tend to live in a completely different bubble with respect to the way software is written.
It is pretty clear that with respect to that goal, Go is a success. It has attracted Python programmers who need type safety and performance. Someone with no Go experience could land a useful new feature in a big Go program in 3 months.
Introducing a junior person to a large Rust system would still take a year, because it is so much more difficult than Go. Which means to me that if Rust had been aiming at this same adoption goal (it wasn't) it would not have succeeded where Go did.
A recent study done at Google disagrees with this assessment.
""it takes about the same sized team about the same time to build it, so that's no loss of productivity",
said Google's Director of Engineering Lars Bergstrom about porting Go to Rust in the talk https://youtu.be/6mZRWFQRvmw?t=27012
Do you really think large Golang codebases are so easy to survey? I could see the argument wrt. C++, but Rust actually has a great featureset for programming "in the large". Take a look at the k8s codebase for an example of a large project that's written in Golang - doesn't seem all that easy to get started with.
What I am more curious about is how much actual use Go has within companies and especially Google. What is the percentage of Go within their monorepo? How much of Google search is powered by Go?
It was supposed to replace C++ in projects where the developers would’ve otherwise reached for C++ simply because it was the default language choice.
thanksStr := "thank you rsc"
ret, err := sayThanks(thanksStr)
if err != nil {
return nil, err
}
return ret, nil return sayThanks(thanksStr)
I've seen this "if err != nil" pattern before, but I can't help thinking that it's not necessary."return ret, nil" ignores err's value, which is nil anyway.
"return nil, err" ignores ret's value, but why? If the caller checks for err before doing anything with ret, it doesn't hurt having ret always passed up.
4 extra lines only to lose the value of ret in case of error.
return sayThanks("thank you rsc")
without losing anything, but then it could just as easily be JS.Usually the pattern is used to perform better error handling (wrapping errors) or in case you call multiple functions that might return an error.
In this case, your suggestion is actually what I would expect to see
Imagine in Java or Python or C# or ... many languages that use exceptions to handle errors:
return a(b(c(arg)));
...where a(), b(), and c() can throw some kind of exception, so you don't have to handle them then and there. In Go there aren't exceptions, all error handling is explicit and handled conventionally by returning an error as the last (sometimes only) return value, which isn't composable, so you get: cVal, err := c(arg)
if err != nil {
return nil, err
}
bVal, err := b(cVal)
if err != nil {
return nil, err
}
return a(bVal) // the final call can be simpler
That's the minimum verbosity required. Since Go 1.13 (2019), they officially added the concept of "wrapped" errors (aka "cause" in languages with exceptions) so instead of returning err you can return errors.Wrap("error in the a-b-c function calling c", err). But nonetheless, _every_ level of the call chain has to wrap or pass on all errors with explicit code. Go does have panic() and recover() which allow for exception-like error handling but it's not idiomatic to use them for normal error handling, go wants that to be explicit.As for why "return nil, err" rather than "return ret, err"? Because while the caller _should_ check for errors, sometimes they just don't.
ret, _ := abc(arg) // just ignore the error
ret.DoSomethingFun()
You as callee don't want to get the blame if you've _partially_ filled an struct because you returned early with an error, and it's then usable but causes a crash because it was partially initalised, because someone ignored the error they got when creating it. That hides where the problem really was. Better to return an empty value, default value or nil. return nil, fmt.Errorf("expressing gratitude: %w", err)Thanks for your leadership of the Go team over the past 12 years, and for your patient comments and guidance on our proposals and PRs.
Best wishes for the future, and hope to see you in the community again.
Wonder what he’s going to do next? Maybe just moving around within G? or another OSS project within G?
I don't intend to make more of those, but that was a lot of fun.
Russ has also got a pull request to add an operator, see https://github.com/robpike/ivy/pull/83
Being able to use channels in a modern programming language is such a gift.
rsc thank you for all your contribution to our field. You blog posts also taught me a lot.
Golang is easily one of my favorite new languages. It's fast and clean without the difficulty of Rust. I was able to create a small mobile app with Chat GPT without any real experience in Golang.
I would like better mobile and gaming frameworks though. Although I really like Flutter, I think Google missed a major opportunity to use Golang instead of Dart.
What's next? Any good for native Chrome support?
>I would like better mobile and gaming frameworks though
er, try asking chatgpt to create them for you.
so you didn't really create it then did you? ChatGpt created it for you.
It's just another tool.
Go's obsession with glibc-isms is really unfortunate, and it's been many years. If you're using Go with containers on Alpine/musl, keep your code very vanilla, because they won't support you.
Go requiring non-ELF standard parameters for initialization of supposedly "C ABI" libraries, open since 2015.
https://github.com/golang/go/issues/13492
The Go project specifically acknowledging the glibc-isms here:
"All Linux first class ports are for systems using glibc only. Linux systems using other C libraries are not fully supported and are not treated as first class."
https://go.dev/wiki/PortingPolicy
Go only supporting static-init thread local storage, and thus their "C ABI" libraries can only be dlopen()'ed if the libc pre-allocates memory to hack in libraries later.
If you want to use c-shared mode and dlopen, then yes that only works with glibc, but that mode barely works at all anyway. It's not actively supported at all.