Hacker Timesnew | past | comments | ask | show | jobs | submitlogin

With the mix of affection and disdain one traditionally feels for a younger brother, i refer to Go as "systems PHP". It may not be a sophisticated language; it may not produce beautiful code; it may, arguably, even have inexcusable flaws. But it is astoundingly easy to learn to the point where someone can be productive with it.

This is a terrifically powerful, and very unusual, advantage for a language to have. Master programmers won't be choosing it as their tool of choice. It won't be used to attack the craft's hardest problems. But it allows a huge number of people to write programs they otherwise would not have been able to write, and, conversely, a huge number of programs to be written which otherwise would not have been written. There's something rather "quantity has a quality all its own" about it. As with PHP, this is something of a mixed blessing, but it certainly puts a dent in the world.



Master programmers won't be choosing it as their tool of choice. It won't be used to attack the craft's hardest problems.

I see almost the opposite, with many new distributed systems being written in Go.


I use a lot of this distributed systems tooling on a day-to-day basis: Docker, Kubernetes, Vault, Pachyderm, etc., etc. It's all brilliant and innovative software and I'm glad to have it.

But every time I need to dig down into the source code, I quickly realize why Docker falls over all the time with weird bugs, and why Vault's high-availability backend for etcd falls over once per week, and why Kubernetes is capable of inspiring such epic love-hate relationships.

There's a ton of code in Docker where nil can sneak in, and where the types of certain data structures are harder to determine than they should be. Sometimes nil represents "none", and sometimes the empty string does. There's a bit of multithreaded stuff in Vault's etcd backend (or was) that doesn't understand the corner cases inherent in concurrency.

I'm totally convinced that these new distributed tools are awesome and a boon to our industry. I just wish that somebody had a long conversation with a good type checker and thread safety checker at critical moments during the implementation process.

This may be a classic case of the "New Jersey approach": https://www.jwz.org/doc/worse-is-better.html Software that's sufficiently innovative and which works will be forgiven odd corner cases and bugs.


> But every time I need to dig down into the source code, I quickly realize why Docker falls over all the time with weird bugs, and why Vault's high-availability backend for etcd falls over once per week, and why Kubernetes is capable of inspiring such epic love-hate relationships.

Vault's documentation clearly states to not use ETCD as the HA backend.

Docker's problems stem from their bone-headed decision to start with a client/server architecture that they've been unwinding ever since. They should have started with small composable tools that integrated well with the existing infrastructure (init systems, file distribution, and security infrastructure). Instead they started with an architecture where everything goes over an HTTP socket through a daemon with high probability for contention, deadlock, and failure. None of that has anything to do with Go. They could have built that abomination in any language.

I can't speak for Kubernetes. I have not used it in anger yet.


I'm not sure what that has to do with things like race conditions that randomly result in "kill and delete" erroring and leaving the container in a invisble, dead state, with a totally useless error message. There are a lot of resources to keep track of in a system like docker and esoteric error conditions, and pretty poor tools to help you do it correctly in Go.


> Vault's documentation clearly states to not use ETCD as the HA backend.

Yes, when I reported bugs against the etcd HA backend they said they were going to add more prominent warnings to the docs, if I remember correctly. :-) I think the underlying bug comes from overly optimistic multithreading code using CSP, but I stared at the code for several hours and couldn't see how to make it unambiguously correct.

We now have our own in-house Redis "HA" backend that I wrote which appears to be rock solid in production, but which temporarily disables Vault during Redis restarts. So it's really "fake HA" but it works nicely for our use case and never requires manual intervention or embarrasses us during business hours. I refuse to set up and administer an entire Consul cluster for a single leader-election lock. Managing Consul has its own complications: https://www.consul.io/docs/guides/outage.html

> Instead they started with an architecture where everything goes over an HTTP socket through a daemon with high probability for contention, deadlock, and failure. None of that has anything to do with Go.

The Docker daemon's wire protocol suffers from a kind a of sloppy thinking about data types, in my opinion. Consider this line in a Rust Docker client: https://github.com/faradayio/boondock/blob/bf29afb0c78f8d5d6...

    pub Ports: Option<HashMap<String, Option<Vec<PortMapping>>>>,
Here, the `Option` types say, "This might be a JSON `null` value on the wire." So the `Ports` member might be `null`, or it might contain an empty hashmap, which in turns contains values that might be `null`, or might be `PortMapping` value. The corresponding Go code is extremely unclear (at least in most similar situations) as to which values can be `null` on the wire.

There's a lot of really foggy specifications going on in the network layer of the Docker server. It's not bad in the way that certain old Unix servers like `csvd` were bad, but I feel like Docker could be better if Go demanded more clarity about data types.

On the other hand, Docker is clearly a raging commercial success, and it actually works quite nicely (at least if you use Amazon's ECS to manage your clusters). So maybe I'm just being overly fastidious. Clearly all this new Go-based devops infrastructure is hugely successful, even if many of us get frustrated with it now and then.

Still, I really wish that more programming languages forced you to be clear about which values can be `null` and which can't. Hoare called it his "billion dollar mistake": http://lambda-the-ultimate.org/node/3186


I'm still unconvinced Docker's choice of using Go is the primary culprit for their problems. If Docker had started bottom up they would have been forced to design tighter contracts between the components from the beginning (regardless of language).

Ultimately it's the architectural decision to couple everything that allowed them to be loosey-goosey with internal-only interfaces. Why bother specifying them thoroughly if you can update all components simultaneously and have no dependencies outside of your control? I'm sure a tighter language would have helped in the small, but their problems are categorically big problems that I believe transcend smaller and more localized failings.

My experience using Consul for the Vault backend has been pretty good. Yes, you have to manually go in and clean up old nodes after a restart, but that isn't too bad. So far (knock on wood) we haven't run into a situation where a replacement node has refused to join the cluster or the cluster has out-right failed.

That said, I do wish they would put the effort to properly integrate with Etcd. We've gone through the motions of setting up and managing a highly-available Etcd cluster for quite some time now and are more confident running it than Consul. I'd rather standardize on Etcd myself, but I'm not inclined to swim upstream. :)


I have yet to see Go code among that class of projects that I would consider bad. I find Go to be a kind of equalizer -- the low ceiling prevents masters from moving upwards in syntactical/semantic complexity, and the high, uh, floor prevents junior developers from doing too much obviously bad. There are plenty of edge cases a newbie can cut themselves on (the addition of unsafe pointers is an antique, Victorian footgun that you'd not expect in a modern language), but overall, Go's forced simplicity normalizes code quality to a degree that I've not seen elsewhere.

Docker's faults do not come from Go, and the same goes for Kubernetes.


Well I do hope analogous tools appear in Rust and show design soundness of Rust. For now I remain sceptic that Rust is perfect language for large, complex, high-perf highly concurrent software.

Rust Roadmap says this much for production use:

"Production use matters for the obvious reason: it grows the set of stakeholders with potential to invest in the language and ecosystem. To deliver on that potential, Rust needs to be part of the backbone of some major products.

Production use measures our design success; it's the ultimate reality check. Rust takes a unique stance on a number of tradeoffs, which we believe to position it well for writing fast and reliable software. The real test of those beliefs is people using Rust to build large, production systems, on which they're betting time and money.

The kind of production use matters. For Rust to truly be a success, there should be clear-cut reasons people are employing it rather than another language. Rust needs to provide crisp, standout benefits to the organizations using it."

https://github.com/aturon/rfcs/blob/roadmap-2017/text/0000-r...


Is that because go is such a great choice, or because it was written by a famous guy for google?


You could read the top level article and find out?


Go does not deserve this comparison. It is a well-engineered and conceptionally sound language, quite the opposite of php: https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/


It isn't PHP-bad, but it isn't a great example of clean, orthogonal design. The only generic data structures being maps, arrays/slices, and channels, is not indicative of a "conceptionally sound" language.

Don't get me wrong, it a great, practical, engineering-oriented 90% solution kind of language; "conceptually sound" seems like computer language theory got involved, and it didn't.


I would never think "conceptually sound" has anything to do with PLT. Seems like an odd definition...


If you have not done it already, I recommend that you give Lua a try. There's a "Learn Lua in 15 minutes" thing that you might like.


To me, Lua feels like "Javascript done right". I only find the `end` syntax very annoying to write.


Exactly. I learned Javascript after Lua, and it was pretty similar, except a bunch of clearly worse design choices, and a pile of complexity mostly related to the web platform. (Why is this magical? Why aren't returns symmetrical to inputs? Why are the semicolons and other syntax so silly? Where are the cooperative coroutines? Why are the types and conversions so much more complicated without adding any additional value? Why all the extra ceremony around what is fundamentally the same prototype OOP system? Etc, etc.)


Yes, except for 1 based indexing.


Configure your editor to do it for you, just like most people do for closing braces.


Then you'll just have an annoying editor and an annoying language.


That seems rather elitist and dismissive. Why wouldn't master programmers use Go if it's the right tool for the job?


The craft's "hardest problems" are tackled with C or C++ (embedded and real time stuff) or with R, Python, Fortran, Matlab (scientific stuff). Some of the most used and therefore most scalable systems on the web use Java, PHP (and variations of PHP), C#.

None of those languages strike me as being both elegant and state of the art at the same time.

Meanwhile the "weapons for a civilized time" such as Lisp or Haskell haven't really gotten a major hold in either a Fortune 1000 company or the software giants on the West Coast.

It's like there's no correlation between "hacker points" for a programming language and the actual results delivered with that language! I'm being ironic, there isn't any. I'm open to someone proving me wrong though...


Well, you usually don't choose languages based on their technical merits, but rather on the ecosystems around them. These depend on popularity which you get by having traction, which you get by being quickly productive. This is why very tolerant or very familiar languages succeed. Being chosen as one of the blessed languages that are taught in universities is also, of course, priceless. A killer framework (Hello, Ruby) can also do wonders.

Not that this defends the very poor syntactical choices that Lisp and Haskell and their communities have done (minimal grammar is not a good thing! One-symbol names are horrible!), but a lack of popularity is not as damning as it sounds.


> Well, you usually don't choose languages based on their technical merits, but rather on the ecosystems around them

Ecosystem is part of technical merit, but I'd agree that in many cases (particularly non-software firms), languages aren't chosen by technical merit (including ecosystem), but for social reasons.


I can't bet for everything, but a lot of sophistication has been put into making Fortran, C, and Java very fast and efficient, for different but meaningful values of "efficient". They are very sharp tools, if not most elegant.


> Meanwhile the "weapons for a civilized time" such as Lisp or Haskell haven't really gotten a major hold in either a Fortune 1000 company or the software giants on the West Coast.

Last I checked, the list of publicly acknowledged production Haskell uses included several significant ones in Fortune 1000 firms, and various Lisps have seen production use at major firms, both inside and outside the software industry.


Sure, Haskell and Lisp (and APL and any other language you care to mention) is used somewhere, in some Fortune 1000 company, but that's a far cry from having gotten a major hold. Just because a group of futures traders in one HSBC office use Haskell to price a certain type of future you cannot really say the Haskell has a major hold at HSBC.


Upvoted because it absolutely is elitist and dismissive - it's a fair cop!

To pedantically respond to your question, note that what i said was that master programmers "won't be choosing it as their tool of choice", by which i mean that it won't be the language they dream about being able to use on their next project. Of course, if Go is the right tool for the job, a sensible and honest programmer will use it.


Well I was all ready to disagree with you and then you had to go and be reasonable.

That's a fair point.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: