Brad Fitzpatrick on the future of Go
dotgo.sourcegraph.com
dotgo.sourcegraph.com
- The Go mantra is "share by communicating, not by sharing". Then look at all the thread examples in "Effective Go". They all share memory, while trying to construct locks using message passing. Multi-threaded Go programs are not memory-safe. That's why Google won't let you use them on their AppEngine. Compare Erlang, which takes message passing seriously.
- The lack of exceptions is resulting in hacks using the "panic" mechanism to create an exception mechanism. This is where we were with "longjmp" in C. I know someone at Google who has constructed a language on top of Go mostly to deal with exceptions.
- The lack of generics is resulting in hacks using the reflection mechanism to create generics. This is painful and slow. Go has generics for built-in objects; channels and maps are parameterized types, so there's already syntax for instantiating a parameterized type. Extending that to user-defined types would not be too bad. Fear of the C++ template mess seems to have been the problem.
Having tried out both Go and Rust I don't see any reason to prefer Go, at least once Rust has a 1.0 release, which is supposed to happen the next 2-3 months.
Both languages were designed to replace C++, but only Rust has the features to actually succeed at that, IMHO.
AFAIU Go was designed to replace C++/Java/Python as _the_ language to use at Google, not as languages themselves. Which is why there is so much focus on simplicity, tooling, productivity (like compile speed and easy deployment).
Criticizing Go for not having enough features is missing the whole point: Go was created in part because C++ has too many features.
To my understanding, it was built for systems creators, not for programmers; it was built as a goto language who have to write program that is both efficient and simple to write and maintain. OTOH, I do see Rust as a C++ replacement, which makes it complementary to Go's focus (sadly it seems that D is lost in the middle, though...)
The language being dead simple also seems to be to that end, with things like removing ternary operators or not having the pre-increment being smaller sacrifices, and no generics being a larger one.
All in all it seems like the underlying philosophy of Go is focused on Google specific context and engineering goals, and it's a happy accident when they work out well for programmers in the general case, whereas something like C++ or Rust isn't catering to those specific parameters (though they're obviously capable of working in that role, perhaps just not in the "ideal" way that the Go language maintainers would prefer).
Weird. Because I see the opposite.
Go would be fantastic for microservices or targeted applications. But features like exceptions are critical when you have 100+ developers spread across the world working on the one codebase and you want to ensure consistent error handling behaviour across the application.
Come to think of it, Go does seem pretty similar to the subset of C++ that Google allows their developers to use. If you think of it that way, it starts to make sense to think of Go as an intended replacement for C++ at Google.
[1]http://google-styleguide.googlecode.com/svn/trunk/cppguide.h...
> Things would probably be different if we had to do it all over again from scratch.
Meanwhile: Golang neatly fills in a sweet spot just "below" Python and Ruby, where finer-grained control of memory and more predictable performance characteristics are required, but bare-metal performance isn't. That sweet spot actually describes a huge fraction of all the use cases for C/C++ in Internet software.
So this is a meme I'd like to see die. It somehow manages to simultaneously get Golang, Java, and C++ wrong all at the same time. The only way to make it worse would be to work in some kind of Lisp comparison, based on Golang's parsimony with parenthesis.
Golang is the new Java, you are watching it being born. Its not ready for the corporate world, its not on any large organisations radar (apart from its creator for course). The point is that Golang solves the problems of the future, it offer parallel execution to normal programmers.
In the future banks and large companies are going to stop having data centres of their own, CPU's are going to have 32+ cores. Java does not solve those problems natively.
Java is great, its got 40+ years of life left in it, but don't say that Java is strong because of its ecosystem. Ecosystems change from decade to decade.
Anyone who thinks Go will ever be a replacement for Java is frankly clueless about enterprise software development. Go has almost non-existant integration with enterprise systems e.g. SAP, Hadoop. It lacks operational management capabilities e.g. JMX. And seriously the range of libraries on the JVM covers pretty much everything e.g. banking/finance use cases.
And concerningly there is not a single reasonably sized Go project to get an understanding of how it works with 20, 50, 100 or 500+ developers working on the same codebase.
----------------------------------------------------------
Language files blank comment code
----------------------------------------------------------
Go 750 14601 9901 115877
CSS 8 107 194 10010
HTML 11 362 21 3594
Bourne Shell 28 391 323 2044
Bourne Again Shell 25 249 185 1475
Javascript 12 111 48 756
Python 1 23 24 192
C 1 20 19 179
YAML 4 25 13 162
XML 1 6 2 60
make 2 27 5 60
Perl 1 11 37 29
vim script 2 8 3 13
----------------------------------------------------------
SUM: 846 15941 10775 134451
----------------------------------------------------------
And I believe there are a number of projects internally within Google but they tend not to talk about internal product technologies (at least at how large they are).Most people simply don't have an understanding of enterprise applications. The majority of the apps are single codebase, Servlet/Spring type monstrosities. They are 10+ years old and have had hundreds of contract developers who come in, add a few new features and then go onto the next contract.
And my point is that I am yet to see what Go would be like in these situations.
It happened to every language without exception.
Anyone who has ever worked in enterprise software can tell you, Go is (currently) exceptionally poorly suited for that style of development. I don't think that is an accident though. I think there is at least the implication that enterprise software development models and architectures are flawed at the core. Go seems to be designed from the start to prevent you from developing that way.
I may be reading more into the Go culture than I should, and I certainly don't think that there is proof that enterprise software can't be successful, but Go clearly steers you into building small, self contained servers that do one thing well and can go without change for a long time.
I'm not sure if I misunderstood your statement, but Go has Docker, CoreOS and numerous other projects which have more than 20 developers working on the same codebase.
Take for example eBay or Amazon and the huge array of different use cases they support. Those are the typical sized Java applications we are talking about. Insurance, Banking, Finance etc. Legacy integration, payments, reporting, various web front ends. One codebase.
Also, OT, didn't realize Eucalyptus had worked so much towards friendly development, and was moving towards including RiakCS as a S3 work-a-like backend[2].
[1] https://github.com/eucalyptus/eucalyptus [2] https://github.com/eucalyptus/eucalyptus/wiki/Scalable-Walru...
[edit: yes, I realize you were probably talking about Amazon the shopping cart, not Amazon the IT infrastructure provider]
I don't see any web technology Go could replace. Not even dynamically typed langauges.
We could easily have done so in Java, but we'd be in Java's concurrency model, which is much more difficult to reason about.
I think this is exactly what people mean when they say Go is more of a replacement for Java than it is a replacement for C++: In the sense that when Ruby and Python become too slow, people normally reach for Java, but now they have Go as an alternative option, with a better concurrency model than Java's.
Better language? Not really, if you want types TypeScript is a much better option. With node+typescript+react you can get end-to-end typechecked code with no FFI involved - thats really, really cool.
Better concurrency? Oh yeah, definitely. Better core libraries? Yes, by far.
Better package ecosystem and management? Definitely not.
> Better language? Not really,
There is no conceivable universe in which the expression "JavaScript is a better language than Go" evaluates to true. ~$ node
> "JavaScript is a better language than Go" ? true : false
true
> "JavaScript" > "Go"
trueWe can argue that the Go concurrency model is better.I think nodejs's is good enough,easier to understand and to deploy. If your goal is to write lightweight webservers that do a specific task,nothing beats node in my opinion.
Ehm, really? Tree of javascript, possibly with some compiled libraries easier to deploy than a static binary?
I'm not saying node is hard to deploy, but I think maybe I'm misunderstanding what you mean here?
let input = reader.read_line().ok().expect("Failed to read line");
And I thought "Cool, Rust has exceptions!"I'm probably too used to thinking in Python. Or maybe I'm just dyslexic and I read "expect()" as "except()".
Either way, your comment prompted me to dig into it further and find out how Rust actually handles errors. So, thanks!
Perhaps you'll be one of the 5% users who will actually miss generics or cannot work without exceptions (even though Go's error handling makes perfect sense without them, it's just a different approach), but it's not very likely.
Go is basically Java 1.0 + Quasar. At some point Go will "grow up" and start adding these features and people like you will fall by the wayside.
If you want a specific language, then just use that one, but don't try to impose your expectations on other languages.
> The Go mantra is "share by communicating, not by
> sharing". Then look at all the thread examples in
> "Effective Go". They all share memory,
That mantra is spoken in the context of concurrent code, not as a general axiom of the language. And I think it's remarkably well sustained in all of the concurrency examples I've seen so far. Can you be a bit more specific? > The lack of exceptions is resulting in hacks using the
> "panic" mechanism to create an exception
> The lack of generics is resulting in hacks using the
> reflection mechanism to create generics.
At the risk of making a No True Scotsman fallacy, idiomatic Go code does neither of these things.https://golang.org/doc/effective_go.html#sharing
All that's sent over the channels is a flag message to start the process and report completion.
Yes, there's the fanboy answer that they're not "really sharing" because both threads don't access the list at the same time. I've heard that excuse. The threads are sharing data. Deal with it. Locking is (hopefully) provided by abusing the channel mechanism to simulate a semaphore. The channel mechanism isn't doing anything here that a semaphore couldn't do better.
But still the Go mantra is valid, the means (channels) provided by the language allow for sharing by communicating and IT IS actually considered idiomatic where appropriate. Also your points about exceptions and generics are non-valid or at least very specific cases. I am working on backend stuff (mostly command-line tools) and i never felt any "lack" of them.
I am leaving those 10% for kernel code and portable macro assembler tricks.
Even with my position regarding generics in Go, I have to agree interface {} is way better than void* or macro tricks.
EDIT: Should mention that those 10% also include embedded deployments where ANSI C barely fits.
I hope I'm wrong though. It'd be exciting to see Golang equivalents of optimized C utilities that come close to using the same disk and memory. Or maybe there's an embedded golang compiler in development that does a good job of optimizing for these use cases...?
QNX gets this. Almost nobody else does. The reason for having subroutine-like IPC, rather than "send on channel A, then wait on channel B for reply", is that the scheduler can immediately transfer control from sender to receiver. If two unidirectional channels are used, you have the sender and receiver threads both in ready-to-run state, which means a pass through the scheduler for somebody, and possibly a handoff to another CPU, with all the attendant cache misses.
A good test of an IPC system is to have one thread calling another as a service, with control going back and forth rapidly, while other threads are compute-bound. If the presence of compute-bound threads kills IPC performance, it was done wrong.
Seeing [what's happening in Haskell (GHC)](https://www.haskell.org/pipermail/ghc-devs/2014-October/0065...), which is soooo much more exciting; but then I totally understand that "exciting" is what you want to stay away from in some cases. In these cases a Go is a much better choice I guess.
So I think Go is an extremely dull language - but personally I think that's what makes it so good.
And Java for an OO lang, after C++, is pretty boring...
Boring has its place.
Q: There are several dependency management tools in the wild: godep, gpm, etc. Are there any plans to provide this functionality in the core?
Brad Fitzpatrick: We don’t want to dictate a policy, so we hope the community fights it out and a victor emerges. Then maybe we’ll bless that one. Then if everyone likes it and it has been stable for a couple of years, maybe we’ll add it to the core.
Brad Fitzpatrick: Part of the reason why we don’t care as much about dependency management inside Google is that we don’t use the go tool inside Google.
Andrew Gerrand: The lack of versioning built into the Go tool incentivizes library authors to provide good, stable APIs.
Are you kidding me??? So if some invariant behavior on an otherwise stable API changes, I don't know until runtime that a bunch of the code that I shipped, haven't changed, and then recompiled a month later has changed it's behavior?
Lots of people run internal Maven repos, they have every dependency vendored, but they also want the ability to choose between versions of that dependency.
[0] https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGh...
[0] http://dotgo.sourcegraph.com/post/99652344343/go-team-q-a-de...
The way $GOPATH works and dependencies are managed is well-documented. Everybody is free to develop their own tooling. Right now, many people flock towards godep, but that might change in the future. Also, since this is only relevant during development and for compilation, getting it right is not as important as if you had to deploy every single one of your dependencies. With Go, you get one binary, and that's what you deploy.
I've leaned towards just having everything it our DVCS (git in our case). External libraries are handled using git subtree.
There must be some standard, though. If you have neither a defined protocol, nor a defined tool, then you have a broken community. That you need to support different package managers for different Linux distros is one of the reasons people don't support Linux for their tools, and I personally would even argue that it is one of the reasons languages like Ruby, Python and Go need to solve that themselves.
Also, if you are unaware, Go has great cross-platform building. I can generate the executables for all platforms/architectures Go supports from my single dev machine.
...I don't remember reaction to that really qualifying as a fiasco, but I could just not have been paying attention at the time.
But I find it hard to believe that one person can go and fix up all the projects he's hardly ever heard of that depends on that library.
In some ways this is similar to what Linux distros do, but sharing common source control, build system, and test runner makes it easier.
Anyway, just wanted to point out that it's possible you're using Ruby lingo and not general-purpose tech terms. I could be wrong, maybe I just missed the boat.
I think "bundle everything" might make sense to everybody, including Rubyists.
http://svnbook.red-bean.com/en/1.7/svn.advanced.vendorbr.htm...
That's where I first read the term, but it predates svn. As far as I know, it's been the common term for committing external dependencies to your own VCS for as long as there's been such a thing as a VCS.
Vendoring means having the physical source code on hand. Not version numbers, not SHAs -- actual checked-out code.
It certainly encourages stable APIs, but I don't see how making it very painful to iterate on your API is a strategy for good ones. My experience is that doing anything well requires the ability to gather and respond to feedback. If you can't iterate, then you're doomed to be stuck at 0.0.1 levels of quality.
No, I think a language basically has to declare that level of compatibility for a major version. The important part is to get as much real-world feedback and iteration in as possible before you bang the 1.0 gong.
Also, gccgo is a very good optimizing compiler but is held back by lack of escape analysis, which I mentioned is being worked on.
It would be great to see what could be accomplished with a big-budget GopherJS.
Dart has other selling points than the type system, sure, but degrading it to Go-style types would be a serious loss.
Also, this would require Google to finally polish up the Android NDK, which would be great even for non-Go users.
I wouldn't have taken that risk.
There are just so many things in Go that feel like 80% solutions - they make great demos but in every day use you have to fight them (looking at you import system and the GOPATH, magical make() function, magical overloaded accessors, lack of expressions or at least ternary if, pre and post increment are hacks not expressions, lack of coercion to more precise types, no templating / generics / preprocessing, needs an equivalent to realloc, having to go through reflect / unsafe to get things done, lack of proper type resolution for complex types).
There are many things I do like about Go, but much of the time it feels like a very pretty prison compared to the (admittedly less pretty) freedom of C.
I'm very excited about this, but I wonder if it will scale to visualize hundreds to thousands of goroutines in a useful way. That's where existing inspection tooling like logging and snapshotting goroutine dumps fall apart.
2) Large parts of the trace viewer are separate from Chrome: https://github.com/google/trace-viewer/wiki
3) The event format is documented, so you're free to write an alternate viewer: https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQt...
How is ARM "exotic hardware"?
Android team only cares about Java as stated at Google IO 2014.
Are you allowed to say anything regarding support from the Android team?
The way Android team spoke at Google IO, I got the idea Go will only have an unofficial place on the NDK.
LiteIde for golang is the closest to the IDE+debugger combination you would expect if you were coming from an Eclipse/Netbeans background.