
Go’s alias proposal and all my concerns of Google controlling Go - activatedgeek
https://hackernoon.com/gos-alias-proposal-and-all-my-concerns-of-google-controlling-go-a39f6c6046aa#.79iuuucic
======
Arcaire
This was linked previously, and the single comment therein linked to a
discussion on reddit[0] about the issue.

Of note, this change has been reverted now[1].

[0]
[https://www.reddit.com/r/golang/comments/5alxa3/gos_alias_pr...](https://www.reddit.com/r/golang/comments/5alxa3/gos_alias_proposal_and_all_my_concerns_of_google/)

[1]
[https://github.com/golang/go/issues/16339#issuecomment-25852...](https://github.com/golang/go/issues/16339#issuecomment-258527920)

------
Manishearth
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...](https://air.mozilla.org/friday-plenary-rust-and-the-community/)

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.

~~~
pbsd
> 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.

~~~
Manishearth
I mean, yeah, not _everyone_ , but it was no longer a very divisive issue;
most of the community was okay with the outcome even if they disagreed with
it. Much better than the previous round where there was a lot more resentment.

Sorry you had to leave.

------
tree_of_item
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?

~~~
shadowmint
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.

~~~
evincarofautumn
> that layer of cruft will never be removed, realistically.

It will if you mark the alias as deprecated. Unfortunately, there seems to be
no standard way to do that in Go.

~~~
zaphar
I have worked on codebases where the deprecated annotation lasted years in the
wild. Marking something as deprecated does almost nothing to make it possible
to remove code. It doesn't even do all that much to prevent new uses most of
the time.

Preventing it in the first place is a _much_ more effective method.

~~~
evincarofautumn
Sure, my comment is only meaningful if someone bothers to fix the warnings.
Before Vendan’s comment I didn’t know that Go doesn’t have warnings, so it’s
moot anyway.

I was thinking in terms of upgrading a library to a newer version. It’s nice
to at least get warnings for everything you’ll need to update, even if it
doesn’t make it any easier to actually do so.

~~~
zaphar
Yeah. Part of the problem that Go attempts to fix is exactly this. They just
make it fail to compile if you don't update your code. In a large monolithic
repository this is easier to police and manage. In the rest of the world not
so much.

------
chmike
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
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?

~~~
chmike
with big projects we will have dependencies with other packages. It is a good
sign that this happens. But then we get also version dependency witch is
currently ignored by go. I use gvm which is one way to handle it, but it is
not enough because external package I use may have their own external
dependency. The bigger the project, the bigger the problem will be.

Actually the version dependency is undpecified. One has to guess it by trying
to compile. I don't think aliasing package names solves this.

You tell me that java tools take care of it. So go tools could take care of
it. But this requires that the info is provided in a standard and clear way.
This info can be kept optional for backward compatibility. Without this info,
we are limited when trying to use go for bigger projects.

~~~
aikah
Versioning is not going to fix go's namespace problem, unless the package
manager does the aliasing, like in every other well crafted language. Go
namespace feature is completely broken, URL shouldn't be namespaces. This is
yet another half backed feature put in Go that doesn't scale in practice.
There are so many of them in the language, they'll be more and more obvious as
the language gains adoption.

~~~
chmike
Version conflicts and package naming collisions are two different problems.
The OP referred to the version problems.

I overlooked package naming conflict which can occur with composed package
names. It is true and correct that aliasing will help solving such type of
problems.

Thanks to point this out.

PS: I suspect you have been down-voted because your critic is excessive (cf.
"half backed feature").

~~~
aikah
> Version conflicts and package naming collisions are two different problems

You cannot separate both issues. Go assumes all API are immutable which is
insane, a package manager won't solve that.

------
cromwellian
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.

------
rusht
Alias declarations were reverted from 1.8 recently[0]

[0]
[https://github.com/golang/go/commit/87f4e36ce7d7dffbf1f2a869...](https://github.com/golang/go/commit/87f4e36ce7d7dffbf1f2a869f3014321f6cfff3c)

~~~
speps
Good, one of Go's strength is easy refactoring given that the standard library
includes its own parser and syntax packages. If something gets renamed, just
write a small script to replace all references...

~~~
Sphax
It's coming back in Go 1.9

~~~
rusht
I thought the implementation was still up for discussion so I doubt it has
been assigned a release yet, do you have a source?

~~~
Sphax
I inferred it from the comments here:
[https://github.com/golang/go/issues/16339#issuecomment-25852...](https://github.com/golang/go/issues/16339#issuecomment-258527920)

But of course it can still change.

------
secure
[https://www.reddit.com/r/golang/comments/5alxa3/gos_alias_pr...](https://www.reddit.com/r/golang/comments/5alxa3/gos_alias_proposal_and_all_my_concerns_of_google/d9i15sj/)
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.

~~~
sagichmal
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.

~~~
secure
Vendoring still requires that _all your dependencies_ (even vendored) use
_either_ “golang.org/x/net/context” _or_ “context”, hence I don’t quite see
how that addresses the problem. Can you elaborate?

------
iainmerrick
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
> 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
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
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.

~~~
cyphar
> Having a global vendor folder where everything is the same version
> regardless of the project seems like a fragile solution to me

That's not what I said. The way that every Go project used to do this (which
was how Godep solved the problem) is that you have a vendor/src directory _in
the project_. It's very similar to having vendor/ in your project, but the
issues I mention are because of the lack of the "src" prefix. If it sounds
like a trivial difference, that's because it is (but because of Go's lovely
filesystem dependencies it makes everything awful).

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

Sure. I don't think it's a good thing that they standardised an incompatible
solution, apparently ignoring how everyone else in the Go community had solved
the problem before them.

------
brianolson
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
One of go's defining features is the lack of these things. If you want them,
use another language.

~~~
aikah
> One of go's defining features is the lack of these things. If you want them,
> use another language.

Go will end up having these missing features whether you like it or not. It
might take a new generation of Gophers but it will happen. The alias problem
is a nice illustration of how broken Go is.

------
EugeneOZ
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
you can disagree, but it's quotation: "I’m happy not trying new things, and I
was happy with Go."

