top | item 12889302

Go’s alias proposal and all my concerns of Google controlling Go

183 points| activatedgeek | 9 years ago |hackernoon.com | reply

68 comments

order
[+] Manishearth|9 years ago|reply
IMO

- just because a company owns the domain doesn't mean they control the language. You need someone to own the domain, and it's always preferable if they are part of a company that won't disappear anytime soon. Similarly being able to unlist someone with powers isn't enough. If I pushed a commit replacing the Rust core team members with someone else it may go through, but nobody in the community will think that was legitimate and it would be reverted. Same with Go, surely.

- If Go has a defined governance model you can't say that Google controls it. If it's wishy-washy then you can't tell. IIRC it's wishy washy right now but ICBW, the last time I was doing go was a year ago. However, it's not clear that Google forced this type alias thing to happen.

-type aliases are a useful feature even without Google's use case. They might be a broken solution to Google's problem but they solve a lot of other things.

Dave Herman once gave a talk about "The Great Int Debate" in Rust. The core team had made a decision (pre 1.0) that many folks disagreed with, leading to resentment. The process was improved with a few rules both participants and decision makers had to abide by, and the re-discussion was more productive. The final decision was a different one, but everyone was happy with it. This evolved into the current set of processes for Rust's rfc process and is going strong.

https://air.mozilla.org/friday-plenary-rust-and-the-communit...

Go might want to look into governance models like these if they truly are a problem. From one blog post, I can't really tell.

[+] eveningcoffee|9 years ago|reply
The one that controls the situation is the one that has most the power over it. Especially the one that can change the rules of the game. The change does not have to be sudden to be effective.

I am not familiar with Go community, so it is hard for me to say anything, but I think that this is something we should consider to get an objective view of the situation.

[+] pbsd|9 years ago|reply
> but everyone was happy with it.

For what it's worth, that worst-of-all-worlds solution was what made me give up on Rust back on 0.9, and I haven't really missed it since.

[+] aikah|9 years ago|reply
> Go might want to look into governance models

The problem is not the governance himself but how Go ties namespaces to API and the lack of flexibility in the language. It has nothing to do with who owns Go. The ownership issue is a distraction.

[+] tree_of_item|9 years ago|reply
I don't really get it. What's the big deal? I see a lot of dramatic language about the "strenuous objections of many external contributors", but what exactly is so bad about this proposal?

There was even a comparison to `goto`...? What am I missing?

[+] aristidb|9 years ago|reply
Type aliases have been useful in many languages for many reasons. I also don't understand why the author is so upset.
[+] shadowmint|9 years ago|reply
The main issue seems to be if A imports and re-exports symbol B from C, reading code that uses A.B you have no idea where to look to find out more about B; it may even be multiple hops of indirection to get to the original C.B, and that layer of cruft will never be removed, realistically.

...that said, I don't really see the problem either, except in that it will make go less 'simple' to read and understand.

[+] oolongCat|9 years ago|reply
I think the big deal here is, a political one, more than a technical one. While google is the reason we have go and google basically pays for go, people are afraid that go might lose its simplicity in order to cater to google's wishes.
[+] chmike|9 years ago|reply
To me the root problem for this alias proposal is that go currently ignores version dependencies.

Go is designed so that we have to assume that an API and the compiler are either perfectly backward compatible or immutable. This is a simplification inherited from C and other programming languages.

If we want to support changing an API, then we have to specify version along the package name and import statement. Some packages already do that but it isn't satisfying because it is hardcoded in the package name.

I like the versioning rule chosen by ICE from zeroc. A version is not backward compatible with other versions. A release must be backward compatible with previous release of the same version.

So it should be possible to specify a version and release for packages in import statements which specify that the specified release and all subsequent release are valid.

Dub, for the D programming language is going that line of direction.

I'm aware that it may create a dependency hell. But it already exist and is hidden. The alias hack is not a good solution. It will make things worse by making the rules more lax.

[+] hodgesrm|9 years ago|reply
Forgive me for asking but are you saying that you want this kind of versioning baked into the language? That seems to add a lot of complexity to Go itself.

Java does not have versions baked into the language except for for class formats, which change rarely and are upwards compatible with new JDKs. Package versioning nowadays is handled by tools like maven and gradle. It's a good separation of concerns that keeps Java from being even more complicated than it already is.

If the concern is with handling interface versions, why not just use loosely coupled web services?

[+] tomohawk|9 years ago|reply
http://labix.org/gopkg.in is useful, but maybe it doesn't go far enough. Perhaps it should be expanded to do the aliasing?

Having the version in the package name is useful, as an incompatible API change usually requires visiting the code and this forces the issue.

[+] blablabla123|9 years ago|reply
Go is somehow based on the assumption that code is really carefully designed. The tools in /bin are the perfect example for that. Unfortunately commercial projects usually have a much faster development pace.

It definitely eases the problem, like proper dep mgmt would, but not more... ;)

[+] rtpg|9 years ago|reply
is this because Go handles dependencies itself?

What's preventing a tool like pip, npm, or stack from working with Go for versioning?

[+] IshKebab|9 years ago|reply
I don't see what is wrong with including the version in the package name. `http`, `http2`, `http3` and so on. I mean if the API changes in a backwards-incompatible way it is effectively a new package.
[+] cromwellian|9 years ago|reply
To me this alias proposal is pretty much the way it's been done in Java forever, so whenever you call for "foo.bar.Baz", the classloader is free to give you back a different implementation, including vendor/foo/bar/Baz, or even a mock implementation.

I think in any large scale dependency chain, you're eventually going to have two transitive dependencies D1 and D2 that both use dependency E, but different versions.

Inside Google we have the OneVersionPolicy, because we control everything in our repo, but in the external ecosystem, this is a frequent occurrence, that has to be solved by either classloader isolation, or upgrades.

[+] secure|9 years ago|reply
https://www.reddit.com/r/golang/comments/5alxa3/gos_alias_pr... points out that this isn’t actually a problem that is specific to Google, but rather affects the FOSS community as a whole, and I think the recent move of golang.org/x/net/context into the stdlib (as context/) is a perfect example.

The author of the article doesn’t seem to mention or consider this point at all.

[+] Kubuxu|9 years ago|reply
The 'context' problem is an interesting one.

Application I am working on was creating over 5k additional goroutines for context handling because part was using context from mainlib and part was using /x/net/context. The lib has special optimization that would fail if you mixed both.

[+] sagichmal|9 years ago|reply
Yet there are existing solutions to the context issue, namely vendoring and versioning, that work well for OSS but don't work for Google.

The alias change could be useful in OSS, but it's certainly most useful in a monorepo.

[+] iainmerrick|9 years ago|reply
This has an interesting interaction with another of Go's quirks.

As I read this (and it seems like the author has an axe to grind so maybe they aren't explaining the motivation correctly) the idea is that when you want to rename A to B, you can make an A -> B alias to ease the transition.

However, people calling your code and using A won't know that they need to update their code unless there's some kind of warning. But Go doesn't have compiler warnings.

So I think the author is right, this would be better implemented as a compiler error plus an automatic refactoring tool. That approach would leverage one of Go's strengths -- it's a pretty regular language and already has good refactoring tools.

[+] bsg75|9 years ago|reply
> Google unambiguously owns golang.org and and therefore controls releases of Go.

Even with the subsequent explanation, this is a tiresome level of what I can only call paranoia.

[+] cyphar|9 years ago|reply
The author mentions Go's vendor/ implementation, and I just have to comment about my issues with it (I am filled with the rage of a thousand suns each time I have to deal with vendor/). I hope this will serve as an example to other language designers to understand why you should always listen to your community. [ Disclaimer: I am a maintainer of runC and have been contributing to Docker and other Go projects for almost 3 years. ]

Go didn't have vendoring support in the old days, so the solution that people came up with was to hack with the GOPATH. The idea is quite ingenious, you just have to create a directory in your project of the form vendor/src/... and the set GOPATH=vendor:$GOPATH. Now, it's a hack around the fact that Go tries to take control of your filesystem (something that I'm still bitter about, and have near-daily issues with) but it's a fairly good one.

There are several benefits to this method that are quite crucial to point out:

1. It doesn't require any source code changes to implement. It's entirely a build system trick. It also makes the version tagging completely separate from the source code. Luckily this is true for the new vendor/ implementation. But note that this is actually a complaint people have about vendoring. At least this brokenness is maintained... Lovely.

2. You can turn off the vendoring by no longer changing your GOPATH. Or you could point your GOPATH to somewhere else.

3. Go's importing of the package path is unchanged by vendoring (look at the output of `go list -f '{{ .PkgPath }}'` to see what I mean). This may seem like a trivial thing to point out but it has an impact on building in certain contexts, as well as users of the reflect package.

4. It worked with every version of the Go compiler (even gcc-go).

There is also a few downsides (though you could see them as upsides). The main one is:

5. All of the vendoring is done globally. This means that if you pin a version of a repository, and one of your dependencies also uses that repository they will both use the same version. This could cause issues, but also ensures that you know what version of the code you're running.

But the solution that Go went with (where vendor/ becomes a magical directory within every project and changes how package imports are resolved) doesn't fix all of the same problems. Namely, it breaks points (2), (3), and (4). (2) is hard to do (you have to manually delete the vendor/ directories), (3) is just simply not possible to fix and (4) is a fun exercise to try to hack around (trust me, I've tried) but because (3) is broken it's not possible [ Did I mention that Go _really_ hates symlinks? ].

Now, you could argue that it fixes (5) (but the GOPATH trick could've fixed it too). So really the solution Go went with was worse than the solution the community came up with. And it was incompatible with the GOPATH trick (fixing (4) involves trying to convert the vendor/ to a GOPATH -- it only works sometimes but because the trick involves symlinks good luck with that).

And now Go is going to work on packaging. I can't wait to see how they break it. I really regret that the containerisation community went with Go as their language of choice.

[+] Skinney|9 years ago|reply
Go essentially went with the node solution (node_modules). Go's pm will essentially just ensure the version that resides in vendor/, and will work more like yarn than npm. This is, of course, not unique to node.

Having a global vendor folder where everything is the same version regardless of the project seems like a fragile solution to me, especially if you work on a lot of projects. And how would that work with third party libraries? Those would still have to vendor?

I think it's a good thing that Go standardizes vendoring.

[+] brianolson|9 years ago|reply
Whether you like the alias proposal or not, the bubble problem is real. Go's maintainers live in a bubble and have blindspots around what Go is missing. They refuse to consider any of the usual language mechanisms for code reuse: subclassing, generics, templates, or macros. They repeatedly shoot down any discussion of these topics.
[+] woah|9 years ago|reply
One of go's defining features is the lack of these things. If you want them, use another language.
[+] EugeneOZ|9 years ago|reply
Whining about nothing - author just would be happy to don't learn new things. Then decision to be a programmer was his mistake.

And about fashion: yes, fashion is better when innovates. Without innovation fashion just can't exist.

[+] EugeneOZ|9 years ago|reply
you can disagree, but it's quotation: "I’m happy not trying new things, and I was happy with Go."