Hacker News new | ask | show | jobs
by rdsubhas 3144 days ago
I'm not sure what you mean by vocal minority's complaints.

Golang generics is the second most voted issue on GitHub itself: https://github.com/issues?q=is%3Aopen+is%3Aissue+sort%3Areac...

(I'm not sure if GitHub sorting is broken, but the same issue has more +1s than the top +1d issue as per that sort mode as well)

Generics has the most experience reports in Go 2 proposal. Maybe this can be categorized and excluded as a vocal minority, but above data doesn't seem to.

7 comments

I'm afraid not all votes are (and should be) considered equal by the project maintainers. A great number of casual Go users might want feature XYZ. OTOH a couple dozen of large Go projects, with combined millions MLOCs and hundreds of millions of end users, may have a different list of priorities, and these priorities might be catered first.

Also, let's not forget that Go is created at Google, and definitely Google's internal projects, likely large-scale by both line count and users served metrics, must take priority.

Frankly, there is a number of reasonably nice languages that do provide generics, good / great type systems, good / great package management, decent async features, and quite decent performance: Rust, Nim, Crystal, ... all the way down to Haskell. Go is not competing with them at their strongest features. Instead, it's in the sweet spot of simplicity, fast build times, reasonable hygiene, and trivial deployment. It's the "getting job done" mentality which worked so well for PHP and Perl back in the day. There is a considerable demand for that.

>I'm afraid not all votes are (and should be) considered equal by the project maintainers. A great number of casual Go users might want feature XYZ. OTOH a couple dozen of large Go projects, with combined millions MLOCs and hundreds of millions of end users, may have a different list of priorities, and these priorities might be catered first.

Many large users writing in company and project blogs have mentioned lack of Generics as a pain point, so that distinction doesn't go very far.

>Also, let's not forget that Go is created at Google, and definitely Google's internal projects, likely large-scale by both line count and users served metrics, must take priority.

Go was not created through some official decree to create a Google language, nor was it mandated to be used or to have some timeline to convert other stuff to it, etc.

It's just a project started by some Go people with the idea "let's examine what a language appropriate for Google's programming would be" -- but using their personal ideas of what Google style programming would need, not something requested, researched etc by Google as an organization. In other words it started as a glorified 20% project, and today it's not any more official in Google than C++ or Java is.

I suspect that Rob Pike's and Russ Cox's work is paid for by Google.

But even if it were not, I suspect that heavyweight users like Google do have a weighty say, just because of the sheer amount of practical experience they have with developing and running software using the language. Just like Mozilla, I suppose, do have a say in the development of Rust.

We’ve actually worked a lot to ensure that Mozilla can’t dictate what happens with Rust; we run a consensus based process, and while Mozilla has the largest single group of people involved in leadership, it’s still a very stark minority.

As a huge production user, Mozilla’s needs are still important to us, but we think of Rust as an open source project Mozilla contributes to, not a Mozilla project per se.

I wonder if this is good or bad. Sometimes it helps to have that singular vision. I think here of all the systems C coders I know, who have never used complex numbers, yet that finds its way into the standard.
As a Rust user outside of Mozilla, it's very good. Rust would have had a hacked-on OO system solely in order to implement the DOM in Servo if browser engine hackers were the only ones with a voice. :P

It's fair to be concerned at the potential evolution of a language that doesn't have a BDFL (I myself came to Rust from Python, after all), but in practice I've come to trust the Rust devs as having very good taste (objective, I know!) and a strong resistance to maximalism (regardless of what some may claim... the list of features removed from the language is longer than the list of features that it has!).

I think in general, the teams, and especially the core team, have a "singular vision" in the big-picture case; this helps. It really can go any way though, I've also seen BDFL projects where the D doesn't care about what the community wants, which ends up with that complex number problem too.
>I suspect that Rob Pike's and Russ Cox's work is paid for by Google.

They are. The distinction I'm trying to make is they have not been tasked to "create an official Google language for Google scale projects", nor what the language officially adopted as "THE" google language the way e.g. Kotlin was officially adopted as a language for Android programming.

Some googlers (Pike and Cox among them) sat and designed a language that they thought would be good for Google scale programming (according to their ideas and experience) and they went and implemented it. Google paid their salaries the whole time, but at least at first, not for the purpose of creating such a language. After the language is out it paid, and even added more people, to keep it going --it gives good PR, and can be used internally here and there, so that's worth it to them.

It's just not "the Google language" in the way Obj-C/Swift are the Apple languages and C#/VC++ is the MS one (the company heavily investing in them, explicitly asking them to be built, suggesting their use everywhere, etc. For Google it's more of a side project than what e.g. Lars Bak worked on.

Actually I think it's one of half a dozen languages whose use is mandated at Google
It's the biggest issue, but that doesn't mean the majority of Go developers support it. 1734 people reacted to the generics issue, most in favor, but there are many more Go developers than that.

But the people who read the proposal and reacted to it may be the vocal minority who are concerned about generics. The majority may not spend their time reading or reacting to proposals they don't care about.

>Also, let's not forget that Go is created at Google, and definitely Google's internal projects, likely large-scale by both line count and users served metrics, must take priority.

And many more want Generics without having responded to the issue.

Issues are representative as a sampling, not absolute numbers.

Unless you do random sampling, you still can't conclude anything one way or the other about whether it's a majority of users. Perhaps something like Google Surveys could be used to settle this?
I'm not sure who you're quoting or why.

> Issues are representative as a sampling, not absolute numbers.

My point was that issues are not a reliable sample of the Go community as a whole. They're a self-selected population of Go developers who cared enough about generics to click on a Github proposal on the subject and react to it. I'll say it again:

>> The majority may not spend their time reading or reacting to proposals they don't care about.

Maybe the majority do want generics, but the Github issue is poor evidence. A random sample of Go developers would be much better, and then we wouldn't have to make up things like "And many more want Generics without having responded to the issue."

>I'm not sure who you're quoting or why.

I accidentally re-pasted the same quote from nine_k I've answered to higher up the thread.

Meant to quote this from you: "1734 people reacted to the generics issue, most in favor, but there are many more Go developers than that".

>* My point was that issues are not a reliable sample of the Go community as a whole. They're a self-selected population of Go developers who cared enough about generics to click on a Github proposal on the subject and react to it.*

And my point is that I don't think this is the case. I don't know either way, but there's no reason to assume people caring to vote in the issue are necessarily not representative -- like I don't think that for any other project/issue combo on github.

In any case, even if they aren't representative of existing heavy Golang users, who cares about them? The language is still niche. There are tons more programmers to come to the language than those that already are using already.

So I would very much pay attention to what those not yet using it but caring enough to vote have to say about it.

Yeah, I would guess you're right, most existing (and potential) users would probably appreciate having generics.
Speaking as someone who worked fulltime with C# when it was relatively simple in v1/1.1 which was before generics, and Object Pascal/Delphi for many years before then - when generics arrived in C# 2 it was a truly wonderful upgrade.

However the complexity of C# has exploded over the years, and it now lacks in simplicity, where Go shines. Yet I expect adding generics would improve Go as it certainly improved C#.

However the trick is knowing when to stop adding features, and with with the incredible pace of churn in most languages these days, it's a major competitive advantage to just not change the language. And advantage that would complement the simplicity of Go nicely.

(Of course it's theoretically possible for users to not upgrade as the language upgrades, but the reality is when the language changes it fragments the documentation, user base, and overall experience - so the argument for users not to upgrade, is not realistic.)

In chess there is the concept of a zugzwang, a situation where it's actually a dis-advantage to make a move. There's lots of other kitchen sink languages these days, Go may be best to keep building on the strength of it's simplicity, by simply not changing.

And then there are many Go users, who don't really care for generics, or like me, think generics could be nice, but could also make the language more complex than desirable.

If someone came up with a practical, clean, working proposal for Go - then absolutely. But so far I've only seen complaints and proposals where the conclusion starts with "this proposal will not be adopted" - mostly because it's somehow flawed.

It is a vocal minority in the (probably correct) assumption that the majority of Go programmers are not part of that GitHub issue, nor any other group asking for Generics.
It should be obvious to folks on HN why a Github issue that may go completely unseen by a large swath of the go community, or +1's which can be gamed/trolled, should not be taken as a valid measure.

But it must be explained I guess.

Confirmation bias much?
The most vocal group is the always the one that is not happy with someone. Doesn't mean this is majority and often it's not.
Thanks for pointing that out, I went there to downvote the issue.
They haven't said "No" to generics.

What the developers want is for people to submit _actual_ problems that generics would solve, with examples. Because there are more than a few way to do it and they want to pick the right one.

That's easy. Concurrent access to maps is unsafe. https://golang.org/pkg/sync/#Map should be a drop-in replacement but due to the lack of generics it can't present a compatible or typesafe API.
I've run into concurrency problems using maps while writing an irc client. It was really frustrating for me, because it did not happen everytime I ran the program, but rather rarely. I had chosen Go for it's memory-safety and easy concurrency. But I felt like I could not vouch for my program's safety any more. I did not know about sync/map at the time, had I known, I would probably have used it.

I think Golang has a fondness for magical (to me) special language constructs. For example if you want to use the RPC modules, you have to write your functions a certain way. Or as I've explained in a comment above, if you want to use an interface you just have to implement all it's properties. Or you can't have generics, but we have a special language construct called maps, where you kind of can mimick genericks but it is not safe and may break.

Golang is a great language, but I think it expects all its users to think very rigidly in the same way their designers do. Basically, you have to explore the language's deficiencies yourself, read the designers' explanations, dive into the intrinsics of the language, understand it, make yourself believe and move on. I sometimes half-jokingly feel like Golang follows the principle of most obedience.

> I did not know about sync/map at the time

Apparently also not about sync.Mutex =)

> if you want to use an interface you just have to implement all it's properties

You surely mean "methods" --- don't interfaces work like that everywhere they exist?

I discovered Waitgroups during the project, but I have no formal training in concurrent programming, so it was a bit daunting for me. And as the error occured very rarely I could not be sure if using a mutex had solved my problem. But now I understand mutex was the way to go for accessing a shared resource.

As for the second point, sorry for the wrong wording, I meant "methods". But interfaces don't work like that everywhere they exist. For example in Java you explicitly use Class X implements Y, and if you do not implement all methods and properties, the compiler complains.

> I discovered Waitgroups during the project

Don't know about your exact map use-case you had at hand, but generally speaking the Mutexes suffice for Lock()ing/Unlock()ing a resource that is accessed concurrently, whereas the WaitGroups serve usually best to just fire off a couple of parallel jobs (that don't access any shared-between-them resources) and then simply Wait() for them all to finish. No real protection from concurrent accesses in there, other than for the WaitGroup's own hidden internal counter that's used to Wait()

Of course these are the low-level sync primitives, channels are the higher-level abstraction, but the former can take you far --- sometimes the latter are the sanest/only choice of course. Especially for parallel goroutines needing to work with each other's intermediate results.

Java interfaces don't have properties either (nor do Java classes), and you can explicitly state interface conformance in Go as well as others have explained elsewhere in this debate: https://news.ycombinator.com/item?id=15672619

What Java does have (since 8) is default method implementations in interfaces.

For concurrency issues, -race flag is your friend.

Don't blame the language for your buggy code.

Unless otherwise stated, Go's data structures are not thread-safe. Maps are not thread safe.

In that respect Go isn't different from any other mainstream language with pre-emptive threading (C++, Java, C#).

go, a language which comes with many built in concurrency primitives, has chosen to leave its core datatypes thread unsafe (the magic ones with generic powers) and gives no sensible tools to remedy this with. this is one of the many ways in which it is a language hostile to its users.
Often, you don’t need concurrent types and their overhead. The sync package makes it easy to bolt on if you truly do.

It’s not as if every block is sending out each line to run in a separate goroutine. Go encourages users to share data by communicating, not communicating by sharing data [0].

On phone, sorry for syntax

    struct CMap {
        sync.RWMutex
        i int 
    }

    func (m *CMap) Inc() {
        m.RWLock()
        defer m.Unlock()
        m.i++
    }
[0]: https://blog.golang.org/share-memory-by-communicating
>Don't blame the language for your buggy code.

No, DO blame the language if its the one that enables and allows for said buggy code when it could as well prevent it.

Case in point: http://lambda-the-ultimate.org/node/3186

Fair enough, in that case.

However a common situation is that the language is supporting a wide range of uses, not just the use a particular developer has in mind at the time.

I've seen this most commonly where a developer operating at a higher level of abstraction, without understanding low level details, complains that the language doesn't match his high level needs exactly.

When in fact it supports lower level operations for maximum performance or flexibility, while allowing layering on top for higher level uses. In language design it's essential to support the lowest level use cases you are targeting, because you can build on top but not go lower than the language exposes (unless it supports embedded asm or another trick to go lower again). I'm using higher/lower here only to refer in the sense of the level of abstraction.

It's a really common trap for someone working usually at one level of abstraction and not deeply understand other levels, to not understanding why a language or library is the way it is because if needs to support others users needs that are different to ones own - I've done it myself enough to detect the pattern, and seen lots of other people do it. Lurking on design committee discussions can be eye opening!

But I can't implement a drop in compatible concurrency safe map.
Don't blame the language for that: jump through BS hoops to create one such map /s