The Problem with Go
vanitynotes.com
vanitynotes.com
Myself and another non-Googler wrote and worked on a portion of the code. We'd of course have to get it blessed and merged by G, which wasn't that bad.
My problem became when a Googler started messing around in that portion of the code, changed it, got it approved, without it notifying the two of us who wrote it. Not that we'd need to be approvers or anything, just would have been nice to have gotten some heads up so we could see how it was changing. I only know as it ended up having bad behavior, went to see what changed, and wrote a rant on the mailing list about it :).
>> [...]when a Googler started messing around in that portion of the code, changed it,[...] it ended up having bad behavior
Your word choice did no favors to your intention.
if I was in your shoes, I would assume that once the feature is merged, the maintainers have final say and can modify or remove your code as they wish. An RFC for a breaking change would surely be nice but I wouldn’t expect any kind of notification if the change was some kind of minor update or enhancement.
"Hi, this PR is modifying a line of code that you submitted. You don't have to do anything, we're just notifying you in case you want to weigh in on the PR".
You could extend it into a general purpose "subscribe" mechanism - if someone raises a PR against this bock of code, please email me.
I can even imagine something like take the top 3 authors of code changed or removed by the PR and if they aren't already the author or reviewer CC them. That way you can pull in some people with context.
That being said: I don't even expect people to notify me when changing code I have written at work. In fact, if people bothered me about code someone else should be perfectly capable of reviewing without me, I'd be a bit annoyed. I really don't need MORE interruptions.
The fact that a breaking change was introduced is really an orthogonal issue. It isn't a given that the original authors would catch the problem. Maybe in this case they would, but I don't think this is a given.
I have certainly experienced reviewing pull requests against code I have written only to let breaks slip by me. :-)
To me this sounds more like the code didn't have sufficient tests to catch the breakage. If I had written the code I would probably have looked at improving the tests after helping fix the breakage so at least it doesn't happen again. But of course, that's just speculation since I don't know what was broken and how.
There are automation tools that do this already.
I don't think "managing the web of contributions" seems too impractical. If for example you CC the top 3 contributors who authored the lines that were changed or modified (excluding large automate or "tree-wide" changes) then for any line you write you are getting notified at most once. In practice it will be much less than that since multiple lines will be changed at a time and you won't always be in the top 2 or 3. Plus consider that many of these people are qualified to review the code and would need to be in that discussion anyways. What I'm trying to say is that the data is there and available automatically and the cost of reviewing follow-ups is bounded.
Imagining the Linux repository (because I have no idea how the golang one looks), creating this doesn't look like a big deal.
I don't think it's reasonable to expect to be contacted, because most projects don't do it. But it's also not unreasonable to contact everybody that touched the code either.
To counterpoint, it's pretty easy to explain why you might not have been pinged; if every engineer was pinged every time any of the code they wrote changed I expect they'd be buried in notifications. Also, whose responsibility is it to send the notifications? the org's? the engineer making the changes? This seems like a lot of organizational and/or social complexity that has no chance of actually being implemented.
Maybe the solution is that it's the engineer's responsibility to watch the code they care about. This model is better aligned with everyone's goals, but it highlights the lack of tooling to watch for proposed changes and manage your desired notifications.
People are certainly free to fork Go, or any open-source project, and take on the roles and responsibilities of Maintainers, but I believe fragmenting the community has almost always led to the overall downfall of a language. Communities are stronger united.
With that in mind, generally Maintainers have the prerogative to decide the specific areas of a project that need improvement, and to focus their time and energy there. Contributors are welcome to contribute code to areas highlighted by Maintainers, and generally Maintainers are responsive and happy to work with those.
Certainly with the volume of PR's (100+) and Issues (5k+), the current Maintainers have their hands full. Decisions will have to be made, and priorities established. While an argument may be made that we need more Maintainers, this is not an overnight solution. A Maintainer needs to really "own" the project, and has to have substantial knowledge of the code inside-out.
Developing a great product like Go takes a lot of time and effort. I believe that slow(er) development is a fine tradeoff for the polished, focused language that Go has become. I would gladly take that any day over a fast-and-furious project where development happens at light-speed but the overall quality decreases with every commit.
I'm saying that people who are not capable of writing a bestseller (solving a complex problem) are still capable of editing a bestseller (their judgement would improve the overall system).
Warning, I am not a professional developer, only a mere scripter.
Aren't forks and transpiled languages sometimes a driving force? Typescript/coffeescript pushed changes in Javascript. Scala on the VM pushed changes in Java. jQuery as a DSL of javascript even pushed changes in the language.
And in all of these cases, the branch language/framework eventually becomes less relevant, but that does not take away the utility and influence they provided in their time.
So if someone imagines running a Golang fork and successfully develops the fork with new features and/or better processes and faster iteration, it may be useful even if they end up dying once and if Golang itself incorporates the changes.
I think that a Go fork would be more like, for example, Go with text internationalisation fixed. It wouldn't be very interesting to a large part of the Go community who is using the language just fine.
I think one of the big problems is that decisions aren't being made. Issues, proposals, PRs, etc. get ignored. Ignoring is not a decision, it's the absence of a decision.
It's fine if they don't want to accept/fix/invest/etc in whatever issue a contributor is raising, but by not providing a rationale, the community just gets left in the dark without any idea how to proceed.
Comparing go to itself, I feel like they've lost some steam and are coping with the ecosystem steadily growing. I can't say for sure if that's the case, and I can have a lot of empathy for anyone just feeling exhausted all the time these days. That doesn't change the experience on the trying-to-contribute side of the interaction though.
I'd argue the opposite. Most programming languages that truly thrive have multiple independent implementations. Go always (1.0+) had multiple implementations and for some of us this was a factor in accepting it as a serious contender.
Fragmentation is not a concern as long as the language and standard library remain well defined. The more the merrier.
(I'm not arguing for trying to wrestle control from the current team, I think they are doing a fine job. Only meant to address the fragmentation thing)
The same human processes broke down when Google acquired GoDoc and rewrote it using proprietary Google tech. I watched employees argue down people concerned with the effects of taking something fundamentally open and making it fundamentally closed, and subsequently making it dependent on GCP infrastructure.
This just skims the surface of what's gone on over the years. Generally, if you're frustrated by the way Go does stuff, I'd say you need to realize that their internal priorities trump external ones and that cannot be shifted.
Compare that with C# or Objective C.
Other compiled languages resolve their dependencies without any special configuration. Or, if you want to use non-shared dependencies, with project-wide configuration, not system-wide.
As a dev using both Go and C# I'm not entirely sure what you mean?
C# is great to work with outside Microsoft, it has lots of non-MS code in it, has masses of unglamorous tooling and fixes, and is used across a load of domains. I don't know about Objective C (that's not my bag) but I'm really missing the point re C#.
When you've finished doing something, you want to get that review right away so you can fully move on to the next thing. OTOH, if you're a reviewer, you don't want to lose focus by jumping on random things at random times.
It creates frustration all around. Not sure what the answer is. What works well for your team?
I can understand than for changes in a language it's a bit more involved than that though.
Also, I'm really curious about teams that do reviews after merge. I heard some places do it but I never really got a good understanding of the pros&cons
I can imagine it works for larger features that need a more thorough, formal review. I'm personally only familiar with code reviews on smaller changes (from trivial fixes to whole features, but often limited to <1000 LOC). The danger of only reviewing small parts of a larger whole is that you miss things in the larger whole.
But for that, you can do both; small code reviews from a 'task' branch into a 'feature' branch, then a big code review before merging into the main branch. The smaller reviews should catch the more trival or obvious issues.
If I don't have time to do it I'll update the person on when I plan to do it. So if I'm heading to lunch and see a review, I'll ping them that I'll do it after lunch.
And if it's the very end of the day, I let them know I'll take a look first thing in the morning.
If that doesn't pan out for some reason, I let them know and give them an update on when I expect to be able to do it.
Really? I consider it part of the due diligence of a good review to pull down the branch and at least make sure the tests pass, maybe even try the functionality out if it's something easy to do. Maybe you mean something different in this context though?
The plugin also will determine if the user is "Active" - maybe what needs to happen is that the Go Devs need to make a sweep and mark everyone on their Gerrit who hasn't committed in say 6 months as not Active: https://gerrit.googlesource.com/plugins/reviewers-by-blame/+...
That said even after the cleanup of active users this is fundamentally a human problem with a part of the codebase that isn't being actively maintained.
As an aside - I really like Gerrit. It's leaps and bounds better than GitHub if your goal is putting code review front and center as the important task to accomplish, as opposed to search and making a fancy webpage. But YMMV.
I suspect it will also be related to a recent change where every CL needs to be signed off by two google employees. Reducing the number of people who can +1 CLs is going to make it harder to get +1s on your CLs.
Reading between the lines I suspect some on the go team at google find it a frustrating situation where they have to rubber stamp contributions from trusted and capable contributors.
Second, is it public how the contextual assignment of reviewers works on the Go project?
None of this is insurmountable, but I do think it explains the effort it takes to merge even a one line bug fix.
At the end of the day Go is the most stable language I’ve worked with in my entire career. It’s far from perfect, but it’s unbelievable how stable it is. In 6 years of working on nomad I can count the times an upgrade caused a regression in nomad on one hand, and nomad uses a lot of Go. Coming from Java and Python (and the MS ecosystem before that) this is unreal. We just never updated Java at a previous job. Python upgrades were significant time investments and never were completed without regressions.
While it would be nice to have this level of stability without googles heavy hand bureaucracy, I can’t think of an example of that happening.
I think a lot of folks at Google who work on Go are trying to improve this situation, but it’s harder than any technical problem.
[1] perhaps Erlang, but that seems dated as a ref to its origin versus contributions and expanded field of endeavor.
Oh that's an interesting observation! Made me peek at the TIOBE index top 10:
1. Python - has a Foundation and is as "pure" OSS as I think something can be.
2. C - slow moving standards body
3. Java - there's a few players here but a fairly small number of corporations have outsized impact (Oracle being the most)
4. C++ - slow moving standards body
5. C# - Microsoft
6. Visual Basic - Microsoft
7. JavaScript - standards body but mostly controlled by a small number of megacorps and Mozilla
8. ASM - I guess corp owned? Hard to reason about this one.
9. PHP - Foundation (I think? I've been out of that world for decades and Zend defacto controlled it when I was in it that world)
10. SQL - slow moving standard with tons of vendor specific variation
So by rough count I think we have about 30% of the top 10 controlled by either 1 or a very small number of corporate backers. 30% controlled by standards bodies, 30% by Foundations, and ...what you count ASM as.
So I think it's fair to say governance by corporate backers is as popular a route for languages to take as any.
(To be clear I don't mean "slow" to be a pejorative when it comes to standards bodies. If it isn't clear from my OP, I'm a big fan of slow moving languages!)
Hope the above saves you a click.
Me: "sure it is." So I follow the footnote reference. That links to r/haskell. That post, in turn, is nothing but a link to r/golang. That post again is nothing but a link to Innoq, which is finally the article. Why make a reader jump through so many hoops?
All for a second article that … doesn't support the claim the footnote needs to support! (The article concludes that … error handling is indeed problematic, and Pike's advice insufficient.)
.NET and Java, both garbage collected, are just as fast or faster with a much larger ecosystem. The only real differences are mild (composition vs inheritance, simpler multithreading, better TDD support, etc).
Rust owns the low level space for modern composition based development and manual memory management. C/C++ exists as well.
Typescript and Python completely dominate the dynamic space.
So... why does Go exist?
1. Python is installed by default of pretty much every linux out distro out there.
2. Go is a bit overkill for something that realistically doesn't need any of the speed/performance benefits you would get in Go
3. No need to compile Python
4. Go is way less readable than Python IMO
Go and Rust are fine languages for a lot of things, but sysadmin scripts is not a good use case for either of them.
If you can install a Python script you can install a binary, and you won't have missing modules or version compatibility issues.
> 3. No need to compile Python
Anything on a server better be coming out of your orchestration tools anyway...
Which Python? Do I need to install pyenv or venv? What about deps? Python is an absolutely disaster every time I try to use it. Golang easily cross compiles (fast enough it doesn't seem like a compilation is happening) to various platforms, I drop the executable there, and it runs.
And Go builds virtually instantly, meaning for any non-trivial script (and if you prefer Go of course) it's a virtual certainty that given the negligible build time and far better performance a Go 'script' done this way will massively out-perform a Python script.
In other words if you don't accept 4 (and I like Python so not a dig) and you have a need for 2 then 3 can become irrelevant and Go is a good choice.
I mean sort of opinion, it’s a pretty solid fact that there is less TO read, maybe you can argue that doesn’t make it more readable.
Go
package main
import "fmt"
func main() {
fmt.Println("Hello, World")
}
Python print(“Hello World”)
Seems like a no brainer to know which one would be easier and faster to develop sysadmin scripts in from the above alone.As an aside, I can't deny that on a per-line or even per-scope basis Python is often more readable. But at the meta level where you're dealing with an entire codebase, which to me is more relevant, the structural aspects come into play and that's where it devolves into pure opinion.
In other words, comparing for readability across a handful of lines is not valuable unless you're only dealing with codebases which are also only a handful of lines.
Of course the main driver of this thread is script files, and for readability Python probably does win as they tend to be short. But I'd argue that as long as something is readable enough (which Go is) then other factors like performance may need to come into the decision.
3. Go compiles so fast it's not that far off from an interpreted language.
2. It's not as big of a scripting language but it's close enough such that I can see justification for it's usage.
1. Yeah but go can be installed pretty quickly from package managers on every linux distro out there.
Especially with a language that prides itself on being like a modern version of C, of all things.
Your lack of knowledge about this fact, however, is a symptom of intelligence.
This is not a mild a difference in practice.
> .NET and Java, both garbage collected, are just as fast or faster with a much larger ecosystem.
Go executables don't require a runtime.
Neither do .NET executables. Cross-platform single-file dependency-free.
(I really like Go, just clarifying because I really like C# too.)
Sure they do, it just happens to be built into every single executable. Something has to manage the GC and coroutines for the application.
Personally, I've largely stopped using the JVM ecosystem and it has nothing to do with the languages. Start up delays killed applets and have always limited command line tools. Now the same startup limitation is afflicting cloud functions. Memory management has always made running JVM processes in a multi-tenant environment complex (from desktop apps to kubernetes pods). The JVM is great in so many ways, but gets extremely complex if you want to do anything the runtime authors haven't prioritized. Maybe GraalVM will change this? After literally decades of waiting, I'm skeptical. /rant
Typescript is still javascript and single threaded. Python kinda has types, but most libraries I used don't.
Go's popularity is an indictment of every other language ecosystem. It's not better, just less bad.
I really enjoy using Go as my main server backend programming language. It's verbose, but simple, and that simplicity makes it easy to maintain. The CSP model of concurrency/parallelism works really well at making multi-threaded applications.
In Go, I can pull from a work queue, fan out for parallel processing via multiple threads, fan into a smaller pool for some post-processing, really easily. In the HTTP engine, I can service each request with its own goroutine, which lets me write simple, synchronous, linear code, versus using promises or futures or callbacks in other languages, breaking up the flow.
To me, subjectively, it's the best backend language when I'm writing something from scratch and don't need to tie into a pre-existing ecosystem. Go exists because there are lots of people like me.
Go is about efficient compilation, efficient execution, and ease of programming.
Go’s memory footprint is also quite a bit better than Java, at least until value types land. .NET doesn’t seem to have a lot of traction; I’ve been meaning to reevaluate its improved Linux story but haven’t yet.
I feel like I'm shilling for C# in this thread (a handful of replies so far) so apologies, but I'm genuinely not being partisan here as I'm a dev using both Go and C# daily.
However if you think .NET doesn't have traction I can only assume you are excluding virtually the entire enterprise in favour of start-ups and pure-tech firms. For the second group you may be right. For the first group Go is (relatively speaking) absolutely nowhere in comparison to .NET, which has for years had the enterprise virtually sewn up alongside Java.
Outside of enterprise I agree you're probably right, which is a shame as it is approximately the equal of Go in most areas, worse in some and better in others.
However when we go for UNIX solutions, Java is the alternative, Go is not even part of the picture unless we are talking about devops tooling (which nowadays is becoming trendy to rewrite in Rust anyway).
If you're the suit'n'tie engineer that is Corpo through and through you might not notice the baggage but from the outside looking in, both of those stacks have this sheen about them that is just too much architecture. Too many factories of factories of generators of memoized factories. Hell I even tried Kotlin, and got pretty far but it didn't take long to get smeared with some Java stuff.
Compare that to Go thats lean and you can write the code with nothing but a text editor and a compiler -- it's very compelling for non-Corpo engineers.
It's why I use Elixir and Nim - I can use both stacks with a simple text editor and terminal. They are built with that perspective. I don't have to fiddle around with MavenASPNetResource.xml digging into 14 different nested folders.
With all due respect to the thousands of man hours that went into these technological marvels, I just don't have it in me to dive into this kind of stuff again: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/c...
Look at it! And weep!
But as with anything, when you have the experience even the linked-to code is second nature and not an issue - it's boilerplate, yes, but it is simple stuff that is both obvious and clear to those within the ecosystem and simply represents a different approach.
Personally whilst I use Go daily I think Linq in C# is far superior to anything in Go, but it doesn't stop me using Go as well as C# because each has its own approach and each is a better fit for specific needs.
> you can write the code with nothing but a text editor and a compiler
Nothing is stopping you from doing the same in other languages. At some point, the benefits of what IDEs offer (refactoring, inspections, integrated debugging, profiling, etc.) almost become necessary when working on large programs.
Because it does offer an alternative to C/C++ for some projects that need to be fast while learning the language requires very little investment. And I say that as someone that has been criticizing Go for a decade. Go has its place.
It's absolutely faster than both Python and Node.js as a HTTP Server,produces faster tooling for linux/PC , it's easy to distribute programs written in Go...
It is not serious alternative to Enterprise Java development, but neither are Python nor Typescript.
However, I don't think Go's opensource ecosystem is comprehensive compared to Python's or Node.js and it is ironically due to how rigid the language used to be which impaired code generalization since it made polymorphism difficult before Generics. It also didn't have an actual package system for years. The Go team has had hard time understanding that in the past.
Enforcing no exceptions is a pretty big win for me.
Go didn't get rid of exceptions, it just made them more awkward.
I've worked on large golang projects. Linking takes a very long amount of time. Languages like Java or C# have a much faster compile then run unit test cycle. Even full compilation, it's hard to prove that golang is faster in any significant manner, and could very well be slower.
Like you, I wish Google was more ambitious with their language design though. Honestly I'd rather stick to the JVM, especially with Virtual Threads now in preview.
This seems like something which can be fixed, technically, and which can also be short-circuited (perhaps after verifying that the technical fix worked). Rust PRs also require a human review, but AFAIK they ensure the list of reviewers tracks people who are currently engaged, and also you can explicitly say "I want my PR reviewed by person A" and the robot checks that person is a reviewer and assigns your PR.
Look at nearly any open source project that's corporate-led, and then - if you can find a FOSS alternative, because most of them die if there is an incumbent well-funded project - look there too. The FOSS one works the way you want it to. It has features built-in that the corporate-led one locks up as a "paid feature", and refuses to accept an open-source alternative contribution.
Our entire Open Source community only works when it really is a community. People contributing their works and getting it merged just because it's what we all want. Corporations aren't part of the community, because they don't do anything without profit. Imagine a FOSS project lead who wouldn't merge a PR unless she could make money off it.
I use Go for the deployment story, but I think (and I know that I'm not alone in this) that error handling in Go desparately needs a runtime-exception-kind-of awakening.
I will use Go if and when this comes to pass.