Hacker News new | past | comments | ask | show | jobs | submit login

Well I must say the Go team is certainly putting in the work to avoid a catastrophic major version bump (e.g. Python).

That said, any major additive change to Go, especially generics and/or try/catch will push me away from the language. If I need a well designed language, I have Rust. Go's sell for me is it's so naively simplistic it's actually useful when your team members are idiots.

If they bolt on type variables, well that's just a different language, and we'll just end up on the hedonistic treadmill towards another Java. No thank you.

Isn't the premise of Go that a team sufficiently large enough will eventually act as a collective idiot in terms of code maintenance? I'm looking forward to some real research on the question of whether Go's design choices have had real world results in improving productivity with supersize code bases.

(Disclaimer: at Google)

My team has ~200k lines of Go code and I'm exceedingly happy with the state of the codebase. Having previously maintained a C++ codebase of similar size, I can say that the pace of changes is higher, the effort necessary for large scale refactorings is lower, and our ability to reason about the system is similar.

A few examples:

- Refactorings are simpler due to the use of consumer-side interfaces. Say you want to inject an in-memory cache above a backing store. To do that you probably have to change the constructor and provide an implementation matching the 2-4 relevant methods. That's it.

- Tracing code is slightly worse, due to having to track callers through said duck-typed interfaces, but on the flip side multi-threaded code is sufficiently simpler to reason about that I call it a wash. Having previously had to do threading in the form of "control flow" state machines, and then fibers (which were better but not perfect, and still aren't widely available), Go constructs are great. Locks where appropriate, channels where appropriate, overall very fast and clean code.

- Performance is good, and reliable. Not as good by cycle-count as C++ - and e.g. the comparable RPC libraries are definitely less mature than Google's very-well-kicked C++ libraries - but on the other hand it scales almost linearly. We started a system at ~5 cores/task under AutoPilot, and then when we next got around to adding more tasks it was peaking at ~60 cores/task at essentially the same per-core throughput. I've never managed to write a C++ server that can accidentally scale concurrency by >10x without hitting _some_ bottleneck.

- We use Go for ~everything. Server code, definitely Go. Client tools, also Go. Simple scripts, bash until they need their first 'if' or flag or loop, then Go too.

- I'd prefer real generics to interface{}, but the number of places it comes up is minimal enough that it's no more than a minor annoyance.

I can't speak to the issues of package management - we dropped compatibility with Go's native package structure fairly early on and went all in with blaze/Bazel (http://bazel.io) to coordinate builds and dependencies and whatnot, and haven't had reason to try modules yet.

> Simple scripts, bash until they need their first 'if' or flag or loop, then Go too.

If you don't mind, can you give a little insight on what this looks like in practice? I'm not sure how to use a compiled language as a script. I've played with executing go as a script using a shebang hack, but I somehow don't think this is how others are doing it.

For reference, the shebang hack I was using looked like this:

    //usr/bin/env go run $0 $@; exit $?
    package main

    import "fmt"

    func main() {
        fmt.Println("i am a script")

It looks more like Go code than a bash script - the tradeoff we settled on is that pretty much as soon as you need to add any sort of logic it's no longer really a simple "script" and you _know_ it's just going to grow into a monstrosity. Better to use a language with real functions, real error handling, that you can actually unit test, etc. In that sense, I guess you could say we write lots of little tools moreso than we write scripts.

For something of this form, if the standard library has the functionality, we us it - os.Mkdir() instead of `mkdir` and so on. But to simplify shelling out, we have a little library that includes the interface

  type Runner interface {
	Execute(dir, name string, args ...string) (*CmdOutput, error)
so it's easy enough to call miscellaneous programs and get the exit code / stdout / stderr. It also supports printing and executing a command, etc.

Iteratively executing a program of this form looks like `go run whatever --flag=value`, though your shebang hack looks like it'd also do nicely.

Anecdotally (n = 10 or so) every Go codebase I've worked on has devolved into a trash fire, so no. Turns out collective idiots can write horrible systems in any language.

Languages are products as well, either they grow to fulfil the needs of their customers or their fade away.

What if the need is for a small language without generics?

If there was such a need, the languages without them would still have a major market, which isn't the case.

Naturally those of us coding since the early days have experience with programming languages without generics support, yet a large majority eventually adopted generics.

Even C has minimal generics support since C11.

In what context would “need” a language to not have generics? I can understand not “wanting” generics to keep it simpler, but I can’t see that as a “need”.

Personally, in any typed language, I want generics, not having them feels very limiting.

I feel the same way. By the time Go2 releases, I hope Rust has solidified its async/await syntax, and Rocket can build on stable.

As I understand it, async/await is not going to be too far behind the initial 2018 Edition (which is coming to stable soon).

Latest estimate is 'in 2 release cycles' (iirc), or 12 weeks.

I really don't know why you got downvoted. The fact that go was meant to force "average" programmers produce maintainable code is an extremely important push for the language.

I do think that generics are needed if go wants to become more useful in contexts others than network middleware or data plumbing, but i'm also pretty sure that adding them will help cripple a lot of codebase in a very short term.

I don't think Go pushes maintainable code. It's simple. That's it. Most of the code bases I see have no layers. As long as you write once and forget, you're fine. After that Go's lack of structure with functions for structs just floating freely in the source file makes things hard to manage. The community's extension of the language to prefer 1 or 2 large files per package makes things worse. The lack of an explicit interface implementation makes it hard to jump to the interface definition of a function on a concretion.

Is there a definitive source for the "average" programmers target? I'd always considered it a tongue-in-cheek response to architecture astronauts who sneer at Go's simplicity.

“The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt.”

-- Rob Pike

From https://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Fr...

And there are other hints on https://talks.golang.org/2012/splash.article

What a remarkably condescending philosophy! Do people really think that poorly of their coworkers? Of themselves?

It's worked pretty well for go.

I'm a relative expert in some domains, but I just find the fancy languages tiresome. I even find so called experts who find it condescending to use a straightforward language tiresome. Seriously - these so called experts never actually deliver any actual product. They just loop around writing line noise that is unreadable.

If you code with others, look into the idea of write-only languages. I think you'll find some of the ideas behind go make some more sense if you understand what they are working to avoid.

I don't hate generics, but don't think they are critical to go's success.

Treating users like idiots is a common engineering practice, not only in programming. Assuming users only make intelligent choices is just unrealistic. It is not that you underestimate any particular person.

You may argue if Go finds the right compromise between giving enough power to their users and not allowing them to shoot themselves in their feet, but the general premise seems to be a very sound one to me.

I think that often people judge programming languages, or frameworks, based on how it would work for them when working on a medium sized one man project.

I believe the designers of Go are onto something.

It's not just the code, but how the code will evolve over time, after a few years of having dozens or perhaps hundreds of programmers modifying it.[1]

In a large shared code base the following dynamic plays out.

* A programmer is assigned to fix a bug, or add a feature.

* His reward for that task is limited to whether he succeeded in achieving that task.

* Even if he is rewarded for improving the codebase overall (refactoring), this introduces much more risk than simply making his changes and getting out.

Basically, everyone wants to get in, make their change, and get out. Now iterate this a few thousand times.

Really it's just the tragedy of the commons, and codebases rot because of it.

The problem is magnified if the language encourages lots of complicated abstractions and meta-programming, because abstractions are difficult to evolve incrementally.[2]

Honestly, I just see Go as a reaction against C++ in this regard.

I still believe however, that the Go team went too far in leaving out features, especially in the areas of generics and error handling. I mean both create more code, so what if it's simple code?

Then the problem becomes that you just have more lines of code to maintain and test.

[1] And for twenty years I was a freelance consultant brought in to untangle big pile of mud codebases for projects in crisis.

[2] See the concepts of assimilation vs. accommodation in psychology. Once your abstractions need to accommodate an inconvenient new fact, then it takes a lot of disruptive effort to fix the problem.

Have you checked that he actually says this in the talk that you're linking to? I've seen this quotation repeated all over the place, but I've never been able to source it. It sounds more like a hostile paraphrase than a word-for-word transcription.

Of course, or do you think I enjoy doing false statements?!?

Enjoy the video from 00:20:40 up to 00:21:10.

Fair enough. I had not found any other citations that gave the timestamp.

I wasn't suggesting that you'd deliberately make up the quote, but you can find it all over the place without a proper citation, so I thought it was possibly apocryphal.

> when your team members are idiots

Just remember, they probably think the same thing.

If Go implement generics I’m out

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact