Go’s alias proposal and all my concerns of Google controlling Go
hackernoon.com
hackernoon.com
Of note, this change has been reverted now[1].
[0] https://www.reddit.com/r/golang/comments/5alxa3/gos_alias_pr...
[1] https://github.com/golang/go/issues/16339#issuecomment-25852...
- 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.
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.
Sorry you had to leave.
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.
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.
There was even a comparison to `goto`...? What am I missing?
With or without pointers, as a programmer you'll have to understand passing by value and passing by reference. Go just makes it explicit in a language construct.
Your second paragraph seems to invalidate your first?
Go pointers make references and values quite visible to the programmer, because in the real world it's not actually convenient to hide those details.
Go's pointers are certainly BETTER than C++ pointers, but I don't think that immediately makes it better. BOTH languages have value and reference semantics, and BOTH languages use syntax to dogwhistle that to programmers.
...that said, I don't really see the problem either, except in that it will make go less 'simple' to read and understand.
It will if you mark the alias as deprecated. Unfortunately, there seems to be no standard way to do that in Go.
Preventing it in the first place is a much more effective method.
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.
Which probably will defeat the point of using Go... its main selling point for me it is its simplicity. If they keep making it more difficult to work with, I might just end up going back to C++
I honestly think you're just being dramatic here, there's no way Go catches up to C++ in that respect any time soon.
On this metric, Go scores 1 (just Go itself), and C++ scores 3 (C preprocessor, C++ itself, C++ templates).
Reflection especially with plugins, are essentially another language that is even more difficult to track down than macros (or templates). Though you can at least write Reflection using go.
I don't think the language as a whole is getting any simpler.
Most language designers generally say that if your language requires a sidecar development environment to be reasonably productive, you've failed at your design tasks. Tools should be time saving helpers, not requirements to understand and navigate even basic code structures.
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.
What's preventing a tool like pip, npm, or stack from working with Go for versioning?
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?
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.
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").
You cannot separate both issues. Go assumes all API are immutable which is insane, a package manager won't solve that.
Having the version in the package name is useful, as an incompatible API change usually requires visiting the code and this forces the issue.
It definitely eases the problem, like proper dep mgmt would, but not more... ;)
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.
[0] https://github.com/golang/go/commit/87f4e36ce7d7dffbf1f2a869...
But of course it can still change.
I think people suggesting a transformer script are inviting Go back into the dark pre-vendor days when every dependency got out of date rapidly and builds were "losable".
The author of the article doesn’t seem to mention or consider this point at all.
The alias change could be useful in OSS, but it's certainly most useful in a monorepo.
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.
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.
Even with the subsequent explanation, this is a tiresome level of what I can only call paranoia.
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.
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.
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.
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.
And about fashion: yes, fashion is better when innovates. Without innovation fashion just can't exist.