Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Why Go is doomed to succeed (texlution.com)
291 points by dawkins on June 13, 2015 | hide | past | favorite | 313 comments


Go is doomed to succeed because it extends the mental model of C with a concurrency model that finds a decent compromise between power and ease of use, makes the typing less prone to subversion, adds memory safety via GC, uses a structural subtyping system through interfaces that brings many OO-like benefits while still keeping to the C struct way of thinking, first-class functions, various syntactic rough edges cleaned up and so forth.

Because the Unix system programming world (and POSIX particularly) is very much built with the conventions and semantics of C in mind, most serious POSIX programming outside of C means you have to deal with painful FFIs, lousy wrappers, overly abstracted APIs that hide details like certain lower level flags and so forth. Some are better at this than others, of course (OCaml is one of the better ones)... but, nonetheless.

So it's unsurprising that many infrastructure developers are jumping to Go. There's just enough new things to incentivize a switch, but not too much that it dissuades from it.


I'm a 90's C programmer and a Golang programmer now, and while there's some truth to this, it's reductive. A 2000s-era C programmer would not write socket code that worked the way net.Conn does. While C code gave us the "pipes and filters" abstraction of Unix, they are not an idiom in C code --- in fact, Golang's reader/writer interfaces feel more like a refinement of Java than a modernization of C.

Golang feels very much like an offspring of Java and Python to me.


Yes, Go has a heavy focus on interfaces and structural subtyping, as I said. It reflects the trend behind Pike's languages: C-like + some form of CSP + key abstraction.

But, even the net package has a noticeable Plan 9 legacy, like the use of dial/listen, as opposed to the clumsy Berkeley socket way. You might recall this was a central complaint of Pike's in his famous presentation "Systems Software Research is Irrelevant".

Obviously it's nowhere near as pure as ndb, but that's the reality of being in Unix.


I certainly can't deny the Plan9-ism.


That captures it for me, imagine a Python that squeezed to the essential bits of Java and left you with Go. It helped that Java, Python, and C++ were the core languages at Google where Go was developed so you had to have something that could bring that community along.

For me personally Rust is more my style, but I agree with the original author that the structural aspects of Go program construction will benefit large communities greatly. It is something I had not really considered seriously before.


> Golang feels very much like an offspring of Java and Python to me.

To me when people compare Go to Python, I can't help feeling that means quite an old version of Python (eg 1.5) in terms of expressivity and higher level features.

Python 1.5 was quite a small straight forward language compared to today. Which seems like the goals Go has.


When I looked it over it struck me as a stripped down Java that's friendlier for systems programming and could interoperate with C without the torture of JNI.


I have never used Go before. From the sound of it, it looks like Go hits a sweet spot between C and Java? and of course the Google support is a major factor for a possible success.


Not quite. To understand Go, you need to understand the history of the Bell Labs gurus somewhere around the late 9th and 10th editions of Research Unix, when the vestiges of what would become Plan 9 and Inferno began to take shape (the sam editor that would influence acme, the rc shell, mk and the predecessor to 9P [streams] would all originate here - see "Interprocess Communication in the Ninth Edition Unix System" [1]).

Meanwhile, Rob Pike and his contemporaries did language research, particularly related to the semantics of CSP-style concurrency. Syntactically they were all C-like, as the Plan 9/Research Unix community all generally liked it.

Newsqueak was the first and it was a cross between C and with special syntax and semantics for procs (green threads). It was written for GUI workstation environments in mind, the idea being to easily build multi-seat applications. From Newsqueak arose Alef, which refined on it but had manual memory management. Then from Alef came Limbo, the language running on top of the Dis VM that formed the core of the Inferno OS.

Fast forward some years later, Rob Pike and some other Bell Labs vets are at Google. Some event happens which painfully reminds them of mediocrity in computing, that gives them the drive again and they resume right where they left from Limbo.

Go is born.

[1] http://cm.bell-labs.co/who/dmr/ipcpaper.html


I feel like "bringing CSP into a modern language" gave Pike's team social permission to launch Golang, but the parent comment is closer to the truth than this summary.

According to Pike's blog, the real motivating factor for Golang was how forbidding and painful Google's C++ build process was. A lot of Golang makes more sense if you look at it through this lens: above all else, don't be like C++.


> According to Pike's blog, the real motivating factor for Golang was how forbidding and painful Google's C++ build process was. A lot of Golang makes more sense if you look at it through this lens: above all else, don't be like C++.

You and I disagree in regards to a lot about Golang, but I think you're spot-on here. I've thought for years that it was interesting how yosefk's criticisms of C++ in the "Frequently Questioned Answers" directly correspond to decisions in Golang: "compile times are long" → "use the Plan 9 toolchain", "memory management is difficult and unsafe" → "garbage collection", "templates are a mess" → "no generics", "exceptions interact badly with RAII" → "no traditional exceptions", "header files are a pain" → "use packages and forbid circular dependencies", etc.


Oh, wow. I love the C++ FQA (I'm a C++ refugee, from the nadir of C++, when Alexandrescu's book had just come out and template error messages were still 10 pages long).

I never though to evaluate Golang against it. Great point.


Why do exceptions interact badly with RAII?


You have to think carefully about how to clean up your object if something throws during its constructor, and throwing an exception in a destructor can lead to your program aborting if that destructor was called as a result of another exception being thrown.

Note that I don't think banning exceptions is really the answer; in particular, the destructor issue is just a specific case of "handling errors during finalization is really hard", and you can't get away from finalization in general. Exceptions really put those issues front and center, though.


Although I would say that is a C++ problem, many other languages with exception support do enjoy more sane models than C++.


Oh, exceptions during construction/destruction, right. I don't think Go addresses that at all. Go's defer is just like a finally block, and panics can happen at any time.


According to Pike's blog, the real motivating factor for Golang was how forbidding and painful Google's C++ build process was.

Yes, that was the "spark" that motivated it, as I hinted it.

A lot of Golang makes more sense if you look at it through this lens: above all else, don't be like C++.

"Don't be like C++" is pretty much a side effect behind much of the Bell Labs and Research Unix philosophy that values composable byte stream interfaces and liberally using a small number of abstractions.

The historical context behind Go that I wrote about is quite undeniable, though. I feel that you're being a tad too contrarian here, but I'd love to know more from your viewpoint.


I guess my point is pretty simple: Golang could have succeeded at its core task without channels and "select", but could not have succeeded without an ultra-fast toolchain and a carefully designed standard library that nurtured an idiom of composable APIs defined by nothing more complicated than structs.

Having native CSP gives Golang a differentiator that it would not so clearly have without it. People can disagree about toolchain quality, and for every person that appreciates a well designed stdlib, there are 3 that appreciate CPAN more. It's harder to disagree with a facility that few mainstream languages provide in any form. So CSP is very important to Golang's identity.

It's just not the "why" of Golang (or at least, I don't think it is.)


You seem to be analyzing this from a more economic approach, whereas I'm leaning to the historical. I think I can incorporate your position, but I feel as though you undermine the role of CSP. You see it as a "differentiator", whereas I see it as a central research interest of Rob Pike's that permeated all his previous languages and naturally had to make it into Go, as well.

See this excerpt from the Alef reference manual [1]:

        chan(Mesg) keyboard, mouse;

        Mesg m;

        alt {

        case m = <-keyboard:

		/* Process keyboard event */

		break;

	case m = <-mouse:

		/* Process mouse event */

		break;

       }
Now where the toolchain is concerned, again that was adapted from the Plan 9 compiler collection (which even OpenBSD at one point was considering but backed off due to licensing) which makes cross-compilation a surprising breeze.

Carefully designed standard library? Plan 9's syscall interface...

Composable APIs defined by one key abstraction? Plan 9 syscalls again, though there it was 9P.

Speed was a motivator, but again - direct side effect of the "5 Principles of Programming" espoused by Rob Pike [2].

[1] http://doc.cat-v.org/plan_9/2nd_edition/papers/alef/ref

[2] http://users.ece.utexas.edu/~adnan/pike.html


So, I'm curious. I know how data driven Google is - have they done studies on whether Go met its goals w.r.t C++ development?


CSP == Continuation Style Passing or?


Communicating Sequential Processes.


Ah, thank you.


Communicating sequential processes



That was very insightful, thank you for sharing!


You missed out the Oberon-2 influence on method declaration syntax. :)


To be fair, there is still mediocrity left in computing.


"Between C and Java" hits it very well, I'd say.

When I jumped ship from C to Java, Java's object orientation wasn't exciting to me, and its exception handling is an acquired taste.

But dynamically growable, garbage collected buffers are something I'd missed for a long time. And the simple ability to concatenate strings without first reserving space for the result. Oh, and hash maps! Remarkably versatile data structures, those.

Coming from C, Java was a delight. Java would have a lot more trouble dragging me away from Go.


>And the simple ability to concatenate strings without first reserving space for the result

Not exactly the same thing, but routine string manipulation in C gets considerably easier once you discover a highly underrated function called asprintf (basically combines sprintf and malloc, calculating the buffer size for you).


Woo hoo, thanks for the tip!

But I still need to worry about creating a memory leak with this. :(


Also, asprintf is a GNU-extension, so if you want to write portable code, it's a no-go (as for everything usefull in C).


Thankfully, I'm not doing much C any more. Those hoity-toity hand-holding languages have spoiled me, and now I don't want to be bothered about memory management and other "trivia." :)


Not in ANSI C nor POSIX.


Well, C++ has all of that.


Only for small values of "all." The magic of concatenation and auto-conversion of strings that's baked into the Java compiler and, to a lesser extent, the Go compiler, is missing in C++ - not vital but convenient. Similarly, hashmaps, while built directly into the language in Go, are a library class in C++. Finally, garbage collection will likely never be part of C++.


What do you mean by "the magic concatenation and auto-conversion of strings"?

Also, having a map implemented in a library is a Good Thing. It means that your language is extensible and expressive enough for this. AFAIK Go is - by design - not that extensible.


Magic concatenation: the "+" operator is understood by the compiler to be the concatenation operator if either operand is a String. "Magic" in the sense that it's an exceptional affordance made by the language (not the library) for this one data type and operator.

Auto-conversion: "2" + 5 = "25". This looks horribly hackish, like some type buggering perl might do, or js. But it comes in handy when you want to build a message string.

And yes, as the article tells us, a lot of things are very purposely left out of Go, which has advantages and disadvantages like most trade-offs.


Magic concatenation:

        string hello = "hello";
        string world = "world";
        string hw = hello + ' ' + world;
Auto-conversion:

        stringstream ss;
        ss << "2 + 2 = " << 2 + 2 << endl;
        string result = ss.str();


1 point for "magic concatenation;" I wasn't aware that works!

"nice try" on "auto-conversion".


The main problem of C++ is that it has far too large values of "all".


Which is still too less when compared with Java, CPAN, Gems, .NET....


Similarly, hashmaps, while built directly into the language in Go, are a library class in C++.

And this is a problem because?

(It's actually a weak point of Go that you cannot define them in a library without sacrificing type safety.)


I didn't say it was a problem. I was objecting to "C++ has all that."


Ah, but the standard library (including unordered_map) is part of the C++11 standard.


> Finally, garbage collection will likely never be part of C++.

C++11 has a GC API defined.

Reference counting is part of any GC book in CS speak.


There are a large number of people who would strongly disagree with the claim that implicit casting is a good thing.


Absolutely, and it's something I consider somewhat of a liability in (e.g.) Scala. You can drive yourself crazy if you're not careful.

However, I feel that doing the "implicit casting" thing only for the single, limited case of string concatenation strikes a happy medium between providing useful convenience and giving you enough rope to hang yourself with.


It has garbage collection through shared_ptr.


Not sure if you are serious but the hard part of gcs is resolving and identifying cycles. Cycles with shared pointers are just leaks.


Exception handling may be an acquired taste.

But it is infinitely better tasting than Go's ridiculous error handling which is something you would expect in the 1980s.


> it looks like Go hits a sweet spot between C and Java?

If your sweet spot is 90~95% java and 5~10% C.


That's not really my sweet spot, but if it have such a strong inclination towards Java, then would it be much easier for Java programmers to move to Go compared to C programmers?

And, what about python programmers, how would Go be for them?


Any decent programmer should be able to switch between {C,Java,Go,Python} without too much difficulty. They each have their own differences and learning curve, but as long as a programmer doesn't identify themselves too tightly as a specific language developer (e.g. some people say "I'm a Java programmer", implying they couldn't possibly learn something else) then it's not hard to pick up Go.


I think that's reductive. I'm a "decent programmer". (I think I'm a little better than that, if I'm being honest.) I regularly use Ruby, Scala, C#, and enough bash to choke a horse. Some C++ too, when I have to, but it's not something I ever want to touch.

I can't deal with Go. And I don't think it's me--I don't do Haskell because of me, I don't do Go because of it. I find it almost impossible to think in Go. I find it incredibly primitive, well past the point of "stupid code is impossible to misunderstand" and into "stupid code because the language demands it." This wouldn't bother me, in a very "you do you" sense, if I wasn't stuck debugging faddishly-designed tools like Docker and Terraform written in it. To this end I think Go is a regression for the open source community, because what I see as veneration of stump-dumb languages makes it harder, not easier, to be smart about problems.


I find it incredibly primitive, well past the point of "stupid code is impossible to misunderstand" and into "stupid code because the language demands it."

Since the parent mentioned C and Java. What are you missing in Go compared to Java besides generics? What are you missing in Go compared to C besides manual memory management?

To me, Go seems to have about the same amount of expressiveness as C and Java. The difference being that it's safer than C and more UNIXy/less OO than Java.

To this end I think Go is a regression for the open source community, because what I see as veneration of stump-dumb languages makes it harder, not easier, to be smart about problems.

A lot of open source UNIX software was written in C. To me it seems that if C was acceptable, Go is acceptable (if the application can live with a GC and slightly lower performance). And as the article argues, it lowers the bar for contribution, because it restricts overengineering.


> Since the parent mentioned C and Java. What are you missing in Go compared to Java besides generics?

That's a clever way to attempt to constrain the conversation away from the elephant in the room. "Other than the bullet in your stomach, how are you feeling?"

Not having at least Java-style "dumb" generics, in 2015, is unacceptable; the existence of `go generate` should mortify everybody involved with Go. Not having better than that--consider what you can do with Scala even before you get to something like Shapeless--is not quite unacceptable but short-sighted and limiting because suddenly I as a human have to do what a moderately smart compiler can do around type checking and leveraging types to solve problems.

Go's general ignorance, and the community's general ignorance, to really basic functional programming that so hugely improves your life is probably borne out of the stupid type system; things like composition (Try monads) for error handling, so I'm not vomiting `if err != nil` everywhere, things like functional transforms for data structures so I'm not writing for loops until my eyes bleed. And you can't really do that in a statically typed language without either blind casts (which Go partisans recommend, because clearly everything should be `interface {}`, remember the days when java.util.ArrayList just gave you Objects?) or generics.

It's just...dumb, written for the lowest common denominator, and I guess the lowest common denominator is dishearteningly low. Good for them, but having more and more core tools written in this junk makes my job a lot harder because it obfuscates potential problems under a sea of boilerplate and line noise.

> To me, Go seems to have about the same amount of expressiveness as C and Java.

I agree with that assessment. Go's roughly equivalent in expressiveness to Java.

That is a criticism, not a defense.

Go being a somewhat more terse Java 1.4 is not an endorsement of the language or the environment. I stopped using Java quite some time ago because my frustrations with "coding with gloves on" outstripped any benefits of the language. (Not the virtual machine. The JVM is fantastic, I love using it. But Java-the-language is Newspeak: if I can't coherently describe a solution in its syntax and semantics, I have to resort to worse solutions. Go's actually worse for this, surprisingly enough...)

Michael O. Church discusses the problems of Java and the problems if the Java shop very well in one of his articles, and in my experience the Go people I have worked with and talked to almost universally fit into that mold (echoing the normal Java ignorance of the outside world, a neat sense of epistemic closure, and the weird desire to rewrite the world into it).

https://michaelochurch.wordpress.com/2012/04/13/java-shop-po...

> if C was acceptable, Go is acceptable

Should C be acceptable? I don't think so. C is, in 2015 and in truth in 2000, too stupid to live. For a very long time we had no other alternatives, and it is an effective lingua franca because it's dumb enough that you can knock out a language binding in short order, but it's a bad language. No memory safety, no type safety (seriously, just review the rules for implicit pointer casting, you have no types to speak of), and nothing, anywhere, to help you not do things that are damaging.

Like, I'm not a C++ fan because it has many warts and creeping features, but if you literally limit yourself to C with classes, std::string/std::vector, and use pointers only in a last resort (preferring references), you have just solved probably eighty percent of the correctness and security problems caused by our reliance on C. (And you cannot practically implement many of those solutions in C without a level of developer discipline that essentially does not exist in the wild. Just having ctors/dtors is literally transformative to writing safe, smart code.)

Rust will solve more, better, and I'm a huge fan of what they're trying to do, but isn't there yet.

> And as the article argues, it lowers the bar for contribution, because it restricts overengineering.

That's an argument. I'd say that it restricts engineering. Which is not a fatal flaw of a tool, there are lots of problems where grunting and bashing your way through it makes sense, but engineering problems often require being able to actually write what you mean, not write what you need to address the symptoms of the inexpressive language before you get to write what you sort of mean if you squint through the garbage it forces upon you.

Lowering the bar for contribution is only a plus if it doesn't moronize people who are cool with clearing a higher bar. For most of the stuff that I deal with, four novices don't replace one expert. When using Go, I very strongly feel that I can't do my job intelligently because I don't have the tools, and so not only will I do my job more slowly, but I increase the likelihood of doing my job wrong.


This just seems to hit all of the highlights of the "I tried liking your viewpoint, but you are ultimately stupid" manner of rhetoric. You even give praise to the JVM.

For every post like this that has me starting to think "hell yeah, C is really stupid, how can others not see this?" I'm reminded of why Linus Torvalds is glad he didn't choose c++ for git. And... it resonates too bloody well. Especially when I consider all of the ports to other languages that have been attempted for git.

I think it comes down to generalities. The reality is most programs are doing good if they solve one problem. Not just solve it well, but solve it at all. Many algorithms, on the other hand, can be widely adopted.

This leads one to think they could "write with their gloves off" and nail down that algorithm in such a way that it will be usable everywhere. The reality, though, is that it rarely (ever?) works out. What you find is that all of the small corner cases that matter in solving something come back and bite you. Hard.


tl;dr: Go is a dumb language because it does not provide enough abstraction. (Or with the underlying tone: Go users are just to dumb to understand superior languages.)

I agree and disagree with all your points. I have written C++ and Prolog professionally for years, then some Java (because employer), with a little Haskell on the side (hobby projects).

I am in a bind when it comes to PLs. I prefer the abstraction of C++ and Haskell (or Prolog for the domains where it fits). On the other hand, it is easier in powerful languages to get complete mismatches between the level of abstraction and the abstractions that are used. To take three widely-used C++ libraries as an example:

- Boost: highly template and template meta-programming driven.

- Qt: basically C++ as C with classes, with moc for signals. Really only templates for collections.

- Xerces/XQilla: 90ies style C++ with global state, and too many Java SingletonFactoryProxies.

In projects where you use different dependencies with different styles, things can get ugly. Also, your policy-based design may not be understandable to your 'C++ is C with classes' colleagues/contributors.

In the end there will always be interaction between expressiveness and maintainability/accessibility. The right abstractions can improve both. Too much magic (page-long type signatures, too many levels of templated indirection, etc.) can make everyone's lives miserable. The graveyard of ugly C++ libraries shows that finding the right abstractions can be hard, even for experienced programmers.


I agree with you that the lack of generics is a weakness of Go. Even Rob Pike agrees [1]. But some of your arguments are just plain wrong:

- `go generate` was never designed as a way to bring generics to Go.

- Most Go programmers are not "ignorant of basic functional programming". They use FP in other languages, and even in Go which has first-class functions, higher-order functions and closures. But it's true that the lack of generics severely limits the usage of FP techniques in Go.

- Go partisans don't "recommend" to stuff everything in interface{} and use "blind" type assertions everywhere. They even recommend the contrary. Give me a link to the Go official documentation that recommends that and I'll revisit my position.

To be clear, just like you, I sometimes miss generics in Go, especially when I'd like to use some FP techniques. But for me, it's just an inconvenience. It sounds like for you it's a showstopper and I understand that. But I don't think that using words like "junk", "stupid" or "dumb" helps in making your point.

I hope, and I'm confident, that the Go team will find a way to add some form or type parametricity that fits well with the overall language.

[1] http://blog.golang.org/slices


> `go generate` was never designed as a way to bring generics to Go.

Unix was designed to port Spacewar. What's that got to do with anything?

> Most Go programmers are not "ignorant of basic functional programming".

That doesn't match my experience. The overwhelming majority of Go people I know, and the loudest advocates to whom I am exposed, seem to regard functional programming as a nothing. Your experience may differ.

> Go partisans don't "recommend" to stuff everything in interface{} and use "blind" type assertions everywhere.

Again, that doesn't match my experience; this was literally recommended to me by a senior-level Google engineer. To his credit, he suggested instead using `go generate` as an alternative. (Because that's better. =/ )

> I don't think that using words like "junk", "stupid" or "dumb" helps in making your point.

Completely fair criticism. But let me put it this way: I view Go, and the terminally blinkered Rob Pike, and his disciples, to be so obviously and monstrously disastrous to what I do for a living that those were the remains after a pretty heavy dose of editing and self-censorship.

I could tell you how I actually feel if you'd like. =)


This is probably the best comment I've ever seen on HN.


That wasn't what I was replying to. aaggarwal was asking how easy it was to move to it. I was saying that it's easy. If you find it too primitive, well, that's a fair opinion, but it's still easy to move to. I think it's hyperbole to claim that you can't work in it.


No, something that's as primitive as Go is quite hard to move to. I understand the language, but I can't think in it and so using it is very far from easy.


If you took "C" out of that list, I'd agree with it.


Yeah, C is probably the hardest to learn in that set.


> would it be much easier for Java programmers to move to Go compared to C programmers?

Don't know about "very", but there would be very little difficulty moving from java to go. There wouldn't be that much value to it though (startup speed and deployment would be the primary ones, and if those are your concern chances are you're not using java as it's notoriously not great at those).

> And, what about python programmers, how would Go be for them?

That seems to be the primary actual market, migrations from python, ruby, php and the like: Go provides a bit of type safety and easy concurrency, an easy deployment story, structural typing is closer to duck-typing than nominal typing (where interfaces must be explicitly opted into by objects) and the fast compilation time means the compilation step isn't much of an issue over "direct" interpretation (/implicit compilation).


This is helpful. Thanks!

I have one more question, how does Go ensure easy concurrency?


It provides built-in lightweight thread abstraction ("goroutines", and "channels" for communication between these).

Beware though, Go uses shared-memory concurrency (as opposed to, say, Erlang) so if you pass a pointer to a mutable structure through a channel the structure won't be copied or moved, both sides will be able to alter it. It does provide a data race detector but it's just that, you have to hit the corruption path while running the detector for it to have a chance, I'm not sure it's 100% even if you do, and I understand it has a non-trivial runtime cost and limitations wrt number of routines it can track.


Thanks for informing, that is an important point to keep in mind, ignoring this would lead to potential bugs and very difficult debugging as you said.


Assuming that's an honest question: it has actual lightweight threads, so you don't need to muck around with either async garbage or worrying that you're using too many threads because you aren't mucking around with async garbage.


Yeah,I was reading about the http module and goroutines. It looks nice. Though I still have to try it.


I found this discussion very helpful. Thanks!


It doesn't feel right to say go is "between" java and c. There isn't a tremendous amount of expressiveness in go that java can't replicate, and there's enough in java missing from go that makes it a wash, for me anyway.


The problem with Go is likely a result of having the kinds of stated goals that it has. The designers of Java deliberately created a language that was for people they didn't trust. The result is a hammer that looks and works like a dildo.

So we're likely headed to where the commensurate Go analogy to Java is a hammer that looks and works like a catheter or something?

One last analogy. What would you prefer: a pilot who has been certified to fly that aircraft and has a minimum number of flight hours or giving every passenger a joystick sticking out of their seat tray so that maybe collectively they won't crash the plane?

Oh, and you kids get off my lawn (waves cane)! ;)


The correct analogy (as we are generally not building people) is "Building an aircraft, that needs a pilot with certification and a certain number of flight hours, or building an aircraft that can be flown by any passanger with minimal instructions, if the need arises". In the latter aircraft, you still benefit from an experienced pilot, but at least, if they pass out, get drunk or plainly go rogue, you still have a decent chance of dealing with the situation, instead of just crashing.


I don't like how Go's design turnoud to be, but I surely appreciate that it means less C code and more memory safe code.

Eventually C will be squeezed into an Assembly like niche, used only for shaving out ms out of an application, kernel stuff or those little code tricks not exposed on the safe layer.


It's very clear what Go is for. Go is for the kind of stuff Google runs on their servers. C++ is too complex, too unsafe, and too hard to maintain, and Python is too slow. (Remember that "slow" at that scale means "we have to add another acre of servers.")

Go is an OK language for server-side stuff. It's not perfect. The concurrency isn't as airtight as its proponents originally claimed. Reflection and type "interface{}" tend to be needed too often. Other than that, there are few killer problems with the language when doing server-side stuff.

The libraries for doing web server type stuff are available and well debugged. When you use a Go library that came from Google, you're probably using code that's executing a few million times a second on Google servers. (As I mentioned on here a few months back, I recently ported a medium-sized production Python program from Python 2 to Python 3. I found library bugs which would have been found long ago were the code heavily used.)

So yes, Go is doomed to succeed. That's not a bad thing.

As for Rust, while I like Rust personally, it may be too complex. The borrow checker concept is brilliant, and a huge advance in understanding how to avoid a big class of bugs. We'll see that again in future languages. The type and generic system, though, pick up where C++ left off, and seem to lead library developers to develop very complex interfaces.

Rust is for people who debate language semantics on Lambda the Ultimate and program in Haskell for fun. Go is for people who have a job to do.


That last paragraph is ridiculous. Name one feature in Rust that you think is too much complexity and I'll tell you where I need it to get my job done in Servo.

Without generics and traits, for example, there would literally be no reason for Servo to exist, because it would be too slow. Performance is not optional. Safety is not optional. They are my job. If I opposed language features that are needed for competitive performance or safety on the grounds of complexity, I would be failing to do my job.

I'm responsible for a lot of Rust's features. I have never posted on LTU, and I've never written more than 50 lines of Haskell. I find most of the Rust community's philosophical language debates tiring and pointless; languages to me are tools, not philosophies. The entire core team is largely with me here. I think you have a deep misunderstanding of the language design if you believe Rust has features "just because".


I don't read his/her criticism that way. It's that users of Rust tend to make over complex systems.


Can you provide an example of Rust users making overly-complex systems? Rust is a systems language, and systems themselves have intrinsic complexity that language designers must either choose to ignore or tackle. Scripting languages have the luxury of removing complexity by ignoring systems concerns so you don't have to care that your language is, say, copying strings around like a maniac behind your back. But somebody has to compete at the bottom of the stack, and while you can still seek ergonomic wins there's an enormous amount of essential complexity that can't be abstracted away.


Then let me be clear: contrary to the parent comment, Rust is not "for" people who do that. Rust is for people who have a job to do.


I find it counterintuitive, that generics and traits improve speed. I would enjoy a deeper explanation of that :)


Static dispatching, and all the possible optimisations from that rather than the "black box" of a dynamic dispatch (you can optimise either side of a dynamic call, but not optimise the whole thing because the compiler can't peek through the dispatch).

Note that this can have a cost in binary size as generic functions and types have to be instantiated to their actual generic parameters (that can be optimised somewhat when the parameters themselves are dynamic, IIRC while .Net uses reified generics Microsoft's implementation uses a single instantiation for all reference types)


The claim was specifically "without generics there would be no point for servo to exist, because it would be too slow". This explanation only limits what kind of generics you can use for speed, but not why generics in itself (and specifically as a language feature) are a necessity to get the job done. You could get the same performance (or better) by not writing generic code or by using code generation.

Don't get me wrong. No one doubts the usefullness of generics (not even the core authors of go. Not even Rob Pike as the biggest advocate against generics in go). Just the necessity. And in this specific case, claimed performance improvements.


> You could get the same performance (or better) by not writing generic code or by using code generation.

There are two ways to work around not having generics: use virtual dispatch/reflection (what you usually do in Go, with interfaces) or code duplication.

Virtual dispatch is a non-starter from a performance point of view, not only because of the virtual call but also because of the heap allocation that's usually required to use it. Reflection is even worse.

Manual code duplication makes it extremely annoying to write well-performing code and reduces productivity. Even worse, though, it reduces safety: lots of the generics in Rust use unsafe code under the hood. If you had to manually duplicate all the code, then the amount of unsafe code would explode. (Imagine having to write atomic reference counting from scratch for each and every type that's atomically reference counted!)

As for automatic code duplication via a code generator, that is what generics are. It's just that generics are a particularly good implementation of code duplication: they're integrated with the type system so that the compiler will automatically generate the appropriate code for you without having to go through the trouble of using a separate tool. Having to use a separate tool buys you nothing, as everyone has to learn the tool to write performance-sensitive code, and having to manually request generic instantiations instead of having the compiler do it is a huge nuisance, one that would push people toward not using generics at all and going to virtual dispatch—which brings us back to the performance problems.


Thanks for the detailed answer :) First let me say: I agree, with pretty much everything you say.

The communication issue is, that you seem to equate "generics" with how generics are implemented in rust. I don't see it that way. To me, generics are a language feature, that has multiple possible implementations, one is specialized code generation, as in rust. I think Russ Cox summarises this better than me [0].

And from that point of view, I was surprised to hear, that people thought they would improve performance. Because in my mind, they probably improve terseness and maybe improve productivity, but not performance, if you can write a generic algorithm as a template and do a search-and-replace for pretty much the same compiled result. I think, these difference in viewpoints was, what made this discussion so more lengthy than need be.

And it's important to note (I think) that no one in the world ever doubted the usefullness, of having generics as a language feature (instead of a standalone tool). When gophers say, that rust is overloaden with features, they don't mean useless features, they just mean, that there are a lot of features. Every feature in C++ is usefull. Every feature in python is usefull. But there are just so many of them, which creates a lot of cognitive overhead and always creates the impulse to contemplate "what's the most elegant way to express this", instead of just expressing it and going on to more important things (Mind you, I don't say this is a philosophy that needs to be shared by everyone, but it's the one people have, when they complain about the number of language features in e.g. rust). I think, Gustavo Niemeyer puts this very well [1].

Anyway, I hope you now understand my question better and also understand better, what the philosophy behind go's minimalism is and what people mean, when they complain about too many features :)

[0] http://research.swtch.com/generic [1] http://blog.labix.org/2012/06/26/less-is-more-and-is-not-alw...


  > you seem to equate "generics" with how generics are 
  > implemented in rust
Given that your question was specific to Servo, and given that Rust is largely motivated by Servo, it should come as no surprise that pcwalton's response was specific to the implementation of generics that makes the most sense for use cases like Servo's.

  > I was surprised to hear, that people thought they
  > would improve performance.
Making the compiler aware of generics makes it easier to collapse duplicate implementations, which can have a cascading effect on reducing binary size and thereby reducing icache pressure.


It's all about specializing code to a certain type at compile time and therefore removing any kind dynamic dispatch during runtime.


  > Rust is for people who debate language semantics on 
  > Lambda the Ultimate and program in Haskell for fun. Go 
  > is for people who have a job to do.
This is a mischaracterization of Rust to the point of incredulity. I've been talking to companies experimenting with Rust and all the engineers I've spoken to have praised Rust for its ability to let them do their jobs with confidence. These engineers are in domains where GC is intolerable and C++ is considered too much of a risk (in fact, one of my biggest surprises in this current endeavor is discovering how few people in industry will describe themselves as comfortable with C++ to the point of being willing to use it in greenfield projects with confidence). Without Rust, these companies would be forced to buy more hardware to throw hardware at the problem or hire C++ specialists to throw at the problem; fortunately Rust threads the needle and provides extreme business value.

Rust was created to solve a specific pain point. It's not some language that sprang fully-formed and perfectly-designed out of the ether. It solves problems that no other language even attempts to solve (no, Ada doesn't do what Rust does (and likewise, Rust doesn't do what Ada does)), and the mechanisms that it uses to do that took years of iteration and concerted effort on large codebases.

Not everyone needs to be working at the level that Rust does, and I think that's great. I'm a polyglot programmer myself, and I like Rust because at last there exists a language that lets me perform at the level of C with the same level of memory correctness that I expect from Python (or really, any language designed post-1995).


I never heard that phrase "thread the needle" before that's good


I brought Rust into my job for some non-essential stuff and so far it obliterated my usual tools (Scala, Python to be more specific) in shear speed and low memory consumption. I've written no more than a thousand LOC of it and most of it is still clumsy bearing it mind the fact that I'm new to it, but the potential that it has cannot be denied. To me it's a missing link I was waiting for - a low level language that feels like a high level one.


I'm currently reaching out to people using Rust for their jobs so that we can establish a more formal relationship with corporate users, and I'd love to hear more about your use cases. :) My email is on my profile page here.


> shear speed

Do you write tools for a woollens manufacturer?


> C++ is too complex, too unsafe, and too hard to maintain, and Python is too slow. (Remember that "slow" at that scale means "we have to add another acre of servers.")

Which is why Java gets used instead.


In some situations, yes. But Java can suffer from similar complexity and maintainability issues too.

Go, for all it's short comings and missing features, is closer to the "instant gratification" state that Python and it's ilk enjoy while having performance closer to that of Java.

I'm not trying to say one language is better or worse than the other though. Just my observations as to why Go is gaining popularity.


I think its a bit premature to predict critical mass for Go and maybe your python comparison is a reasonable prediction of where Go will finish up.


> I think its a bit premature to predict critical mass for Go

If Go was only used by it's sponsoring company and a few "language-whores" on non-critical systems, then I might have agreed with you. But in spite of Go being one of the "new kids on the block", there are already quite a few sizeable projects and organisations outside of Google who are using Go for fundamental parts of their software stack (eg Cloudflare, Canonical and Docker).

So like or loathe the language, I'd argue that it's already reached critical mass.


How does go prevent complexity?


Mostly by making abstractions harder. By making it pointless to think about "what is the best type-hierarchy for this software" or "what is the most general way this problem can be formulated and solved", it forces you to focus and solve the problem at hand, which leads to more straightforward and easier to understand code.

Most people I've seen, that are frustrated with go, are people who want to have an impact on the community by writing a package that a) solves a simple-ish problem with the simplest API possible (e.g. "password-hashing libraries") or b) solves a complicated-ish problem in the most general way possible (e.g. "generic containers" or "graph algorithms"). As go makes both of these very hard, these kinds of people get frustrated with it.

go generally agrees with people who want to solve complicated specific problems, e.g. "I want to find all dead links on a website", because it gives you a relatively straight way from A to B.


Is there any detailed article on this topic that you know of?


The canonical answer is [0], though unfortunately, that's not very good to illustrate this specific point :) I came to this conclusion from reading the golang-{nuts,dev} mailing lists and whan pops up in the community. The usual answer to a proposal of a new language feature (most famously some form of generics) is "what real-world problem is this trying to solve and maybe we can solve it in other ways". And "real-world" always means "real-world", i.e. code that is currently running in some real project out there. And the answer of the people propositioning is almost always something in the neighborhood of "I want to write a foo-library, that makes bar simpler".

I remember reading an article a while back by someone explaining exactly that very well, but I can't seem to find it…

[0] https://talks.golang.org/2012/splash.article


I'm not sure it does. On the one hand Go generally requires less boilerplate code than Java does. But that's only if you're writing simple models; once you factor in stuff like generics you can quickly find the simple becomes unnecessarily complex within Go.

Like with most things, it really depends on what problems you're specifically trying to solve.


Often Java is too slow too. (Slow == overhead from GC of unwanted object metadata and heap allocated objects)


In those Techempower benchmarks Java destroyed Go for web app style requests.

And given that the JVM is so dominant in big data (e.g. Spark, Storm), online betting and applications like high frequency trading you could make the reasonable assumption that Java is anything but slow.


Go has a gc. That doesn't seem to be the problem. Google also uses Java quite often.


> program in Haskell for fun.

What about the people who program in Haskell for work?

> Go is for people who have a job to do.

People use Go for fun.


Does Google use Go in any high-load services?


download.google.com is completely powered by Go at this point, iirc.



Vitess (https://github.com/youtube/vitess) scales mysql for youtube level of usage.


> Rust is for people who debate language semantics on Lambda the Ultimate and program in Haskell for fun.

Very smooth. /s


> Other than that, there are few killer problems with the language when doing server-side stuff.

Which ones?


Go succeeds because Google's behind it.

Go certainly doesn't succeed because of smug/boring articles like this one. The potshot at Erlang early on (also cf. slurs on Rust and Haskell in some of these comments) betrays the same old "we like it here in our cave" bias of Go boosters whenever confronted with its glaring warts.

Go is a great choice for certain workloads, is reasonably fun to code in, and has great doc support on the web. I suspect however it's popular also because it isn't FP and doesn't favor immutability. It plays well with the haters who refuse to understand how good GC/list fusion/stronger types/better abstraction can make code easier to understand and way faster.

But the bottom line is no Google, no Go. Just like no Sun, no Java. It's simply unbeatable to have a mega tech corp paying folks to write docs libs and patches. But it doesn't save it from being yet another turing tarpit.


Right, Google just needs to will something to succeed, and poof, the world rallies around it. Like Dart, and Google Wave, and Google+, and Google Glass, and Google Answers, and Google Buzz. It doesn't matter if it's good or bad, because if it has Google's stamp on it, it's destined to be a wild success.

Certainly, having a big corporate sponsor doesn't hurt, but it's clearly neither a necessary nor a sufficient condition.


Yes, but Go solves a real problem for many people and isn't attempting to turn a profit. I wonder when it would be at the point where it could sustain relevance without further funding.


Languages are not products. The analogy is not reasonable.


The analogy holds for Dart at least.


You characterize certain language features as objectively better. Indeed, those who do not use the particular approach you advocate (FP) or the feature you desire are "haters who refuse to understand". Is this really a charitable way to look at other programmers? As people who, because they do not use your preferred language or languages, are apparently full of hatred and -- not a lack of understanding, but a _refusal_ to understand?

How about we consider the author of the blog post, the Go community, and the Go language's designers in a more charitable light. Perhaps the points made in the article are actually valid: that language features involve tradeoffs, some of which are measured not just in terms of performance, and that languages are designed to achieve certain goals that might not align with yours.

Yes, I imagine that "Go certainly doesn't succeed because of smug/boring articles like this one" although I'd remove "smug/boring." Before I used Go I hated it "from first principles", because I had used Scala and Clojure and Haskell and Reactive Extensions and all sorts of FP goodness. But to make a long story short, once I started using Go I really enjoyed it and now I willingly choose to use it to solve problems. It was the use of Go that convinced me that perhaps these absolutes from FP I believed in weren't quite absolutes after all. But this doesn't mean that I consider Go to be some kind of perfect holy grail of programming, either.

Does that make me a hater who refuses to understand? Does it make me some kind of idiot for regressing from FP? Or perhaps the goals of Go aligned with my team's goals, and that was really helpful and valuable to us?


I characterize FP as not worse, which of course implies that it must be better in some scenarios to even compete.

I characterize Go as having glaring warts. ":=" will bomb on reassignment UNLESS you destructure alongside a new variable. Wart. Try to close over a variable in a loop; wince in pain as you make a throwaway anonymous function to do so. Wart. Don't get me started on "interface {}".

Nonetheless, I think Go is a great tool for the right job. I don't think it's "better for open source" (WTF???). I wouldn't want to write a massively-concurrent (not parallel: concurrent) system in such a loose-goosey, non-polymorphic language. But that's just me, knock yourself out.


The article claims, and tries to "prove", that Go succeeds because it was designed from the very beginning to be a mainstream language, trying to stay simple enough to be accessible to most programmers. You're not discussing this in your comment.

You claim that Go succeeds because Google's behind it. Maybe, maybe not. Then write your own article to make your point.

The paragraph about Erlang was not a "potshot". The author is just pointing out a tradeoff, which is real. There is no question that Erlang is a great language and system.


Yes, it won’t always keep you safe from data races as Erlang will, but Erlang keeps you safe by copying your data over and over, making it significantly slower, TANSTAAFL.

Potshot. Defend it at your peril.


Erlang processes are shared-nothing and, by design, data must be copied when processes communicate:

> All data in messages between Erlang processes is copied, with the exception of refc binaries on the same Erlang node. [1]

But I have to agree with you that the paragraph about Erlang in the article overstates the issue. In most cases, messages should be relatively light and then the copy is not issue. It's an issue only when you need to transfer or share a complex data structure.

If I'm not mistaken, in the current implementation of BEAM, each lightweight process has its own heap and this is the reason why data must be copied. But it could be possible to allocate memory from an arena shared by all processes, and because Erlang data structures are immutable, messages exchanged by processes could contain only references. The cost would be a more complex garbage collector, with the related latency issues.

[1] http://www.erlang.org/doc/efficiency_guide/processes.html


Yep, just like Dart... oh, wait.


bingo

Google: Go

Microsoft: C#

Sun/Oracle: Java

almost all others: more on their own merits, from developers eyes (Python, Perl, C++, Ruby, Rust, D, Scala, LUA, JS, etc.)

a language should have innate merits, of course, but never discount the advantages of having a single corporate entity with lots of cash and focus and a built-in install base of eyes


Let me fix that list

CNRI: Python

AT&T: C++

Unisys: Perl

EPFL: Scala

37signals: Ruby

Mozilla: Rust


37signals and ruby? They were involved with Rails, but did they sponsor Ruby?


No, but IIRC Ruby had very little relevance/existence — at least outside Japan — before Rails.


for the point of the parent comment, ruby was chosen for its merits, not designed by 37 signals.


> TL;DR Golang was explicitly engineered to thrive in projects built by large groups of programmers with different skill levels, and there is no larger such group than the open source community.

Very true.

This article hits the nail on the head. Most people say that they cannot "express" certain things in go, or have to jump through hoops to do it. The point of go is not to create a highly expressive language, but rather to create one that has a high enough abstraction to be productive but simple enough so that people coming from different backgrounds can acquaint themselves with it quickly.

In other words, it is a language for teams.


"explicitly engineered to thrive in projects built by large groups of programmers with different skill levels"

Reminds me of Java. Although, Java gets increasingly complex these days. It also started out without generics.


I don't think you can say "Reminds me of Java" with "Simple enough". Java is too complicated now.


Java as a language is still very simple. Frameworks are complicated -- but I doubt this can be avoided in the long run, Go will have similar problems.


I would word it slightly differently--in Go you are free to express yourself in exactly one way: the idiomatic Go way. Anything else will be painful (a good clue is if you find yourself using reflection frequently).


That's true, but it's also (sometimes) liberating. In extremely flexible languages, you can find yourself burning lots of time finding the most "elegant" way to express simple concepts, like "how am I going to write this SQL column to this series of DIVs".

Not coincidentally, Golang sucks at this problem.

But there is something about writing in Golang that makes it easier to dive into meatier code. For instance: I've written programmable assemblers in Ruby and in Golang. With Ruby, I kept refining the assembler until the DSL looked identical to normal X86 assembly (I even hooked the bracket operators to make them behave like dereferences). With Golang, I quickly moved past the assembler into an IR and a compiler.


With Ruby, I kept refining the assembler until the DSL looked identical to normal X86 assembly (I even hooked the bracket operators to make them behave like dereferences). With Golang, I quickly moved past the assembler into an IR and a compiler.

Same experience here. I am working on a neural net dependency parser and pretty much started C++ and Go implementations in parallel, because this was one of my first larger Go projects and I had my doubts about using Go for this.

In the meanwhile, the Go implementation is a complete and fast parser (the number crunching is done using OpenBLAS via gonum), which I now use for research. In C++ I am still tweaking the abstractions for the basic stuff (word embeddings, transition systems). Of course, I could make a simple, straightforward implementation in C++, but the language encourages you to finetune the abstractions and you have to the choice between template-heavy/light code (with its respective downsides).

I also found that Go encourages me more to break stuff up more in different packages. In C++, every separate library means new build machinery, some way to roll it out on systems, etc. In Go it's as simple as creating a new repository and adding imports.


> With Ruby, I kept refining the assembler until the DSL looked identical to normal X86 assembly (I even hooked the bracket operators to make them behave like dereferences). With Golang, I quickly moved past the assembler into an IR and a compiler.

That is a great way to compare languages. Incidentally, that's the same way I feel about Scala vs Python.


I agree that the number of possible solutions is often smaller than in other languages. But there are still often multiple ways which are considered idiomatic Go (in the sense that they are all widely used). E.g. if you build some iterable type, you could provide iteration via:

1. Go channels: send every value over a channel.

2. Callbacks: provide an iteration function which takes a callback function.

3. Closures: let a closure return the next value when called.

4. Iterators: create a separate iterator type with e.g. HasNext()/Next() methods.

In this respect C was much simpler, because only (2) and (4) were really possible (and sometimes indexing).


1 is a misconception. Go channels are fundamentally useless for iteration, because you leak goroutines with break or return inside the loop. Same goes for 3 probably. 2 and 4 are the idiomatic ways (and afaict the only ones used in the stdlib).

edit: Okay, 3 should work too, sorry.


The most pleasant thing about learning Go for me has been that largely, if the compiler is happy, my code works. At times the compiler feels nitpicky, but so far that opinionation has tended to make me write better code that is unquestionably very readable so far.


But you are lucky if your project has a large group of programmers. There is more probably a large group of projects with a small group of programmers. There are also some large projects: Linux, KDE, LibreOffice, VLC, LLVM, etc... and none is written in Go.


>Linux (1991)

>KDE (1996)

>LibreOffice (based on StarOffice, 6.0 released in 2002)

>VLC (2001)

>LLVM (2003)

I think you have a point r.e there being more smaller projects than large projects with large teams. But this is a terrible argument. Go was released in 2007. Are you being facetious or are you suggesting that porting a mature codebase to Go is that easy? CoreOS was released in 2013 and so was Docker. I know that Docker actually ported to Go after the fact, but it was still relatively young and Go was already mature by then.


Go was released in late 2009.


This is a weird argument to make, since Go was first introduced in 2009 and the first stable version was released in 2012. All those projects precede Go by a decade or more.

Also, despite Go's short existence, there are already a surprising number of large Go project (Docker, Syncthing, etcd).


I'm a fan of Go and have been using it for a [relatively] long time across various large and small systems.

I really like it.

To me, what's been abundantly clear is that: it's a horrible choice for types of apps a lot of people are using it for. Specifically, systems where ror/django/express/php have traditionally excelled at. I'd say "CRUD", but that's too narrow. The expressiveness and productivity of dynamic languages continues to awe me. This is particularly true for web systems that, on one end, deal with the object-relational mismatch and on the other transforms and outputs json or html.

Go's great, but it feels like we've forgotten some of the pain-driven lessons Hibernate and their ilk taught us.


This is sort of the conclusion I've come to in the last few weeks as I think about and research in preparation for my next startup. I learned to code with C / Perl in the late 90's, moved to scripted/interpreted "web" languages like ColdFusion, PHP, RoR, JS, and about a year ago I finally decided to build a toy project with Go for Google App Engine. I found the process really instructional, but ultimately pretty frustrating. I fall very much into the author's second camp; it's not the language for me, for what I want to use it for. I'm building a pure web app, with very little systems orchestration need (outside standard devops). Go seems like a great fit for building Docker, but a poor fit for building AirBnB. Especially at first, when I'm likely to be the only programmer for 12-18 months, it seems to me that Go is a poor choice to begin with. It loads too much technical debt (probably the wrong term) onto our startup at a time when we need to move fast and break things. If we are hugely successful and we end up with 20 programmers in 3-5 years, then maybe it'll be time to re-architect key microservices in golang. Until then, I think RoR makes the most sense for us.

I've been looking for someone to verbalize this train of thought for a few weeks.


I keep wondering whether the lack of generics is in part intended to make people not even try and implement Hibernate but to accept using a lower level of abstraction instead.


Please tell me more about the pain-driven lessons Hibernate and their ilk taught us


We learned that you can't configure your way out of impedance mismatches. You can certainly make your life easier, but only at the cost of also making it harder.

You essentially need language-level support for dealing with data at your boundaries. Even with Java's strong reflection (Go's reflection is horrible) capabilities and generics (and C# extending that with lambdas and expression trees), there's still tremendous friction and boilerplate configuration and code.

Consider Dependency Injection, an ilk. In most (all?) dynamic languages, DI is a language concern, as opposed to a library concern. By having support for it within the language, the problems DI frameworks attempted to solve in Java (or C#) via messy configurations, legalese-like unit tests and quantities of code dedicated to nothing but the infrastructure of the codebase, simply vanishes. Now people are going to Go and discovering the awesomeness of interfaces.


>To understands why Go is the way it is you need to know why it came to exist in the first place: "The goals of the Go project were to eliminate the slowness and clumsiness of software development at Google, and thereby to make the process more productive and scalable. The language was designed by and for people who write—and read and debug and maintain—large software systems. source"

The problem with this idea is that, for the exact same goals, there could be a much better design for the language and much better implementation of various details.

You don't need to be Haskell or anything. Just Go + generics for example would result in a much cleaner language (no special casing for things like "make" for example), a vastly improved code library and data structures story, etc. This horse has of course been beaten to death (including by people working extensively with Go, so it's not like some "outsider's misconception" as some dismiss it).

If Go succeeds is because noone else with the same kind of visibility and resources tried to compete in this space (easy concurrency, static builds, fast compiles, static, fast-ish, decent batteries included etc).

You have e.g. Rust which is incomplete and too complex, Nim which is too niche, from very small vendor (a guy) and has some bizarro ideas, and that's pretty much it. That said, Swift might make a dent in this area when its Open Sourced if it has nice tooling.


This was my favorite quote/sentence in the article. For me it feels extremely true. I am one of those people that has to write, read, debug and maintain large software systems.

Sure generic's would be nice, but I do not feel they really would change much. After using and supporting Go for years, I would rather keep it how it is. Simple and verbose.

Getting up at 3am in the morning to respond to a page going off in a production system that you didn't write, there is something extremely parseable with Go. It doesn't hide and abstract things in a way where you have to end up digging.

Often the docs are just not enough to really understand software. In the event you end up having to go read the code to understand it, when things get that far, I wish it was Go every time. There is little in the world more frustrating than having to read 18 java files to understand a simple format of a payload because your coming in late to the codebase.


How is Rust incomplete and too complex (especially "incomplete")?

Compiler-enforced-correct manual memory management may not be the right choice for every project, of course, but I think "too complex" is too strong of a way to say that. That implies there was a simpler way Rust could have achieved the same goals, and I've never seen anyone suggest one that works.


Surely the parent comment only meant that Rust was too complex to use, not that Rust was unduly complex. If Go would be a feasible choice, Rust is probably solving problems that aren't too relevant to you.

I think http://arewewebyet.com/ speaks to the completeness point sufficiently. Rust-the-language is probably complete enough for all but the most serious use-cases, but Rust-the-ecosystem isn't.


I agree. Also, maybe Rust-the-community isn't ready to honor promises (http://blog.rust-lang.org/2014/10/30/Stability.html) it makes, which is critical for enterprise adoption.

Twenty-two days after release, Rust started talking about making breaking changes (https://internals.rust-lang.org/t/pre-rfc-adjust-default-obj...). This conversation killed a Rust project I had pushed for... it played into all the existing negative ideas about Rust (constantly changing, not worth investing in) and gave the doubters all the ammo they needed to kill the project.

The change wasn't yet implemented, and had ZERO impact on our code-base even if implemented. But Rust-the-community seems too clueless on the importance of APPEARING stable and able to follow promises.

I wonder how many other Rust projects died because Rust-the-community appears like an untrustworthy ally (I am speaking of perception not reality).


The promise was "we won't break your code". The conversation was to determine the answer to the question "is there any code out there that this will break", because we take that compatibility promise seriously and want to honor it. If you're unhappy that we're having that discussion, well, I'm sorry, but we need to have these kinds of discussions if the compatibility promise is going to mean anything. The alternative would be to make these sorts of changes without discussion (or to stop making any kinds of changes that could break code at all, which rules out too many benign improvements; see below).

It's untenable to guarantee that, in a strict sense, the universe of all possible programs that run on 1.0 will always have the exact same behavior on 1.1. With any language, there are plenty of ways to break code in theory on upgrades that are very unlikely to lead to problems in practice; as an obvious example, incorrect unsafe code that depends on undefined behavior can break when the compiler starts optimizing based on that undefined behavior. I think that, instead, what we can realistically guarantee is that code that actually compiles in 1.0 compiles in 1.1. If there's no code out there that actually breaks, then I don't see any problem.

Golang has made many changes that could technically, and actually did, break code as well (just to name a recent example, the GOMAXPROCS default bump; there have been several others).


> If there's no code out there that actually breaks, then I don't see the problem.

Exactly, which was my point. Rust-the-community (and you as a member of it) see no problem with it... which for me, IS the problem. The timing, the fact that it played into all the existing narratives about why you never trust Rust, it made it a brutal bit of political weaponry in the hands of those who are pushing against Rust in organizations... and a bit of a kick in the junk to those of us who supported it. You saw it as without impact, when it has already had a huge impact on at least one organization.

> Golang has made many changes that could technically, and actually did, break code as well (just to name a recent example, the GOMAXPROCS default bump; there have been several others).

Rust isn't Go, that might seem "unfair" but that is the way it is. Go does not have the same reputation to fight against as Rust, the same famed history of breaking peoples code who are trying to use it, Rust WILL be held to a higher standard when it comes to breakage than ANY other language I suspect.


> Rust-the-community (and you as a member of it) see no problem with it... which for me, IS the problem. The timing, the fact that it played into all the existing narratives about why you never trust Rust, it made it a brutal bit of political weaponry in the hands of those who are pushing against Rust in organizations... and a bit of a kick in the junk to those of us who supported it.

Tell me what you wanted Rust to do instead. Again, the options seem to me to be either "make potentially-breaking changes silently without gathering feedback" or "make no changes to Rust that could break any code ever". If the latter, realize that this implies we could never add functions to modules (because of glob imports and shadowing), we could never add modules, we could never add trait implementations (because of method resolution), we could never add to the prelude, we could never upgrade LLVM (because of undefined behavior), and probably a whole host of other things I'm forgetting.

> Go does not have the same reputation to fight against as Rust, the same famed history of breaking peoples code who are trying to use it, Rust WILL be held to a higher standard when it comes to breakage than ANY other language I suspect.

I'm not sorry for doing so much development in the open instead of behind closed doors, even if everyone got to see how much the language changed from 0.1 to 1.0 and it acquired a reputation of "changes all the time". The point is, it doesn't change all the time now. From 0.6 to 0.7, for example, all code everywhere broke. Same with 0.7 to 0.8, 0.8 to 0.9, and 0.9 to 0.10 (though the amount of breakage got less over time, as you would expect). Conversely, the amount of breakage between 1.0 and 1.2 (assuming the trait lifetime change goes through) is so minuscule we don't even know of a single crate anywhere in existence that it would break. This is, in my view, so different as to be incomparable.


> Tell me what you wanted Rust to do instead...

Well -- if we are going into what I would have preferred. I would have preferred a rest period after release. No ongoing changes across 3 trains on a 6 week cycle. Give the community time to accept, adapt, bitch, moan, whine, create workarounds, and then better workarounds. Let enterprises have time to buy in, test, accept or reject and give feedback. Deal with critical issues and focus on stability as a deliverable... and don't break anything during the rest period (even if that means being on a single version of LLVM and no new traits or modules or functions or whatever). But, that ship has sailed.

> I'm not sorry for doing so much development in the open instead of behind closed doors

Who asked you to be? I was simply pointing out the reality that Rust has a reputation to contend with -- you can't change that be being righteous about it, it just is.


You appear to have an expectation that the 1.0 release itself is an LTS release. I'm not sure where that expectation came from, but it is not correct. 1.0 is just the foundation for the language's stable evolution, and I don't expect any Rust code to linger on 1.0 in lieu of upgrading to 1.1.

The arrival of the 1.0 release also doesn't imply that the language is "done" or ready to use for anyone's particular use case (e.g. Servo is still on nightly, and will be for the foreseeable future). There are crucially important things that are currently being stabilized, and delaying those for an additional three release cycles would just be an arbitrary obstacle for those seeking to shift their code from nightly to stable.

We also don't need three release cycles to get feedback because we've been collecting feedback all throughout the 1.0-alpha and 1.0-beta cycles. Now would be the worst time to institute a freeze on API additions because of all the APIs that people are clamoring for but that didn't make it to stable for 1.0 (https://github.com/rust-lang/rust/issues/24028).

We're also working closely with several dozen companies using Rust to determine what development to prioritize (if you would like to add your company to this list, then please see the email address in my HN profile). As a result of this collaboration I expect to submit an RFC next week to propose that Rust 1.5 become the first LTS release, with subsequent LTS releases happening every at every fifth release. Do note that this idea is very preliminary (don't take it as gospel), but if accepted it would mean that we have until October 30 to stabilize any features that we want corporate users to be able to take advantage until the next LTS.

(As for that proposed "breaking change" that 1) wouldn't break any code in the wild, 2) would be trivially fixable with a lifetime annotation, and 3) could be opted out of with a single attribute, every company that I have asked about it has said that we should go through with it.)


> if you would like to add your company to this list...

Sadly, in the near term, the Rust boat has sailed. LTS releases would give a real good reason to reconsider if they ever come about. What support durations are you considering for LTS, and where can I read more?


I'm not sure of all the parameters yet, I'm coordinating with our corporate partners to see what they would find most useful. I'll be posting the RFC to the users forum and reddit once it's done. You can also give me your email address and I'll notify you when it's ready. :)


>Yes, there is more of a learning curve, but I think that's a problem with manual memory management in general. To me, that doesn't mean that the language is "too complex"; rather it means that the space Rust is playing in (and which those other languages are not playing in) is complex.

Yes, that's probably the case (Rust caters to more complex needs). Still makes it more difficult to just "dive into it" like you can with Go or Java or Python etc. Of course it's probably much simpler compared to mastering C++ or getting C right without dangerous bugs.


I agree with all of that. :) I don't think it does Rust any favors to pretend that manual memory management doesn't have cognitive overhead compared to pervasive GC, but at the same time, I don't think that it points to anything wrong with the language; "a safe, modern C++" is just a tough niche to fill, and I think (with the obligatory bias) that Rust did it well.


Precisely. I actually just left a reply on your other comment saying the same :P Oops.


Not the parent, but I've read many comments here on HN from users who feel that if a language doesn't include an HTTP server in the standard library, it's not ready for production work. Ridiculous, of course, but that may be what the parent is referring to.


Does Java meet the criterion you're describing here?



JavaEE sure does.


Certainly. I guess I'm not sure if I should call it the standard library or not (and if I should care whether I call it that).


Java SE also does include one since Java 6, but people don't read documentation it seems.

http://docs.oracle.com/javase/6/docs/jre/api/net/httpserver/...


[deleted]


There's a funny story here about how Rails had to keep some patches around because Heroku users were accidentally using WEBrick in production because of defaults...


Well, it's a very common complaint (and I found it to be true when I tried my hand at Rust) that the lifetimes and general scope management can make your life hard -- and certainly harder than conventional GC languages. Rust, as a core language, has a lot more concepts to grok compared to Go or even Java.

As for incomplete, I mostly refered to the tooling and the available library ecosystem. Even Go lacks there, and Go is an order of magnitude better there than Rust. That said, despite the recent 1.0, the language is also heavily worked upon in several aspects (internals etc) and it doesn't seem that it's a "complete" offering that just happens to do incremental improvements, but a "we got an 1.0 out of the door, but we've got work to do to make it more mature".


> Well, it's a very common complaint (and I found it to be true when I tried my hand at Rust) that the lifetimes and general scope management can make your life hard -- and certainly harder than conventional GC languages.

Yes, there is more of a learning curve, but I think that's a problem with manual memory management in general. To me, that doesn't mean that the language is "too complex"; rather it means that the space Rust is playing in (and which those other languages are not playing in) is complex.

> As for incomplete, I mostly refered to the tooling and the available library ecosystem.

I've never found Rust lacking in tooling, with the notable exception of the lack of rustfmt (which is being worked on by Nick Cameron and others). I use native profilers and GDB with Rust almost every day, and Cargo is getting pretty mature. The library ecosystem isn't very mature yet, sure, but I wouldn't say that makes the language incomplete.


For many of us a complete language means the whole lot, e.g. IDEs, visual debuggers, a library for any use case, books.

This is most likely the why of the incomplete remark of the OP.


Rust is certainly harder to pick up than Go (and possibly Java), but I don't think that makes it any more complex than, say, C++.

The difference is in the learning curve. The concepts Rust forces down your throat are the same ones you'd need to learn in some way in C++ anyway (well, not the same concepts, but similar ones having to do with avoiding segfaults). The difference is that you can write simple programs in C++ whilst blissfully unaware of the perils that come later. On the other hand you sometimes need to understand ownership for even the simplest programs.

But for a larger application, you have the same amount of learning required if you want to responsibly write an app in C++ or in Rust.

When we're talking about using a language for something other than teaching programming newbies, we really don't care about small prime number programs being harder in Rust. We care about how hard it is to write large applications, and I strongly suspect Rust isn't harder than C++ for this.

Oh, by the way, for the most part lifetimes work themselves out[1] without effort from your side. And if you find them complicated, you can always compose the relevant wrapper object (like Rc for refcounted memory management -- almost a GC) and use it. It's a bit more verbose, but it's not hard to grok.

[1]: http://manishearth.github.io/blog/2015/05/03/where-rust-real...


> the lifetimes and general scope management can make your life hard -- and certainly harder than conventional GC languages.

Except you have to solve those very same problems on your own with every other type of resource that is not called "memory" in other languages.

Ownership is a huge problem, having built in primitives to handle it is a benefit. Having or not having GC is almost (but not quite!) a separate discussion.


It's rather that Rust's standard library and third party library support is incomplete. E.g.:

- last time I checked there was no option to have non-blocking IO which is a pain.

- custom JSON serialization/deserialization from/into custom data structures is extremely painful (for reference, rustc_serialize's Decodable trait).

- thread::scoped leaking destructors under certain conditions. This is more of an example of how a complex language gives rise to complex issues that very are difficult to debug and fix.

This will get better in time obviously but this is the current state of the language. Nonblocking IO in particular is really unfortunate to see in a 1.0 version tag.


There are mio and serde respectively for your first two points, and mio in particular is really popular.

Regarding thread::scoped, I think that kind of issue isn't unique to Rust (Java, a language with a simpler memory model, has had all kinds of weird corner case bugs, especially around memory and concurrency). It's also, again, more an issue of "safe manual memory management is hard": the simple ways to avoid that issue would have been "GC everything", "sacrifice memory safety", or "remove reference counted smart pointers", which contradict Rust's goals.


>>(Java, a language with a simpler memory model, has had all kinds of weird corner case bugs, especially around memory and concurrency<<

Can you point something in particular?


CVE-2012-0507 for example.


The leakapocalypse is rather blown-up - I don't think you could observe it unintentionally. Besides, `thread::scoped` is something no other mainstream-imperative language tries to offer - parallelism with essentially no risk of race conditions.


> thread::scoped leaking destructors under certain conditions.

Note that this problem is one that has no analogue in other languages.

In most languages, including Rust, you can already "leak" things by putting them into a static hashmap and forgetting about it or sending them to a blocked thread or whatever.

Rust is unique in that it can demarcate types which are bound to a scope. Which gives the auxiliary guarantee that the object would be destroyed in that scope regardless of what happens next (because such objects cannot be returned from the scope or placed into a global hashmap or whatever). There is no analogue for this in other languages. Rust is not "incomplete" for not having this.

The current scoped API depended on this guarantee, but it turns out that there are convoluted ways to bypass the guarantee (so it's not a real guarantee). There's a new design that's been proposed which doesn't need this guarantee.

non-blocking io can be done via mio, and I think using serde for json is easier.


The problem with all statements regarding programming languages is that they rarely have empirical evidence to back them up. Do you have any data showing that generics will lead to a cleaner language? I have seen a study or two that tried to measure productivity, bug counts, etc with regards to generics and what it showed was that writing code using a library that is built with generics was ever so slightly faster. However, it showed that creating or editing a library that used generics took 10x longer.

It seems that you can't really make the claim that adding generics leads to a "much cleaner language".


>Many critics I find though, fall into the second bucket. The answer to those critics is always the same: “Go is just not for you”. Some people see this attitude as stubbornness from the community, aversion to improve which will doom Go in the long run. They just don’t realize that some people want different things.

This trivializes all critique to "to each his own".

That some people "want different things" doesn't mean all things people want are equally valid.


Go seems to be attracting a lot of developers from Python, Ruby and Node because Go offers them the easy path to getting started that they place a premium on, combined with speed, but relatively few people from the order-of-magnitude-larger JVM world. Coming from Java I like that there's a very similar language that I can use for command line applications (a JVM sore-spot) or a simple daemon -- both because it doesn't require warmup and can be delivered as a single native binary -- but I just can't think of giving up the JVM's deep monitoring, low-overhead deep profiling[1], polyglotism[2], dynamic code loading and hot-swapping, and the awesome hacking power that comes with runtime bytecode manipulation[3] for long-running, important server applications.

[1]: Java Flight Recorder is the most powerful low-overhead profiler I've ever seen.

[2]: We use Java, Kotlin and Clojure all in the same project.

[3]: The ability to inject ad-hoc tracing code into your server and then take it out -- all while the server is running at full speed -- or to shadow binary dependencies so they don't clash, or to use (or write) a time-travelling debugger is like having magic powers. Bytecode manipulation is ultimate hackability.


Many of the Java monitoring is only critical because of the garbage collection issues with large heaps. Since switching away from Java we don't miss any of the features you've listed. The problem with Java is the mountain of bloated frameworks which have become standard over the last 10+ years - things like Spring, Hibernate etc. which new developers are expected to learn. With Go new developers which join the team aren't saddled with years of legacy frameworks which are expected as standard knowledge. The JVM is a great platform, but Java the language and to a greater extent its frameworks are a major liability for the future of the JVM. Go and Java (the language) are both incredibly boring to program in (a good thing in if you have developers of varying skill levels), but they are a safe choice with a low bar for learning. Java unfortunately has a mountain of legacy cruft which makes it a pretty terrible choice for new hires to ramp up on.


> Many of the Java monitoring is only critical because of the garbage collection issues with large heaps.

That's not true. All JVM libraries expose a ton of monitoring information through the standard JMX interface at every level of the stack, from deep inside the JVM, through logging framework, DB drivers, schedulers etc., and all the way through the application.

And I can only guess that you've yet to encounter Go's even worse GC problems with large heaps.

> Java unfortunately has a mountain of legacy cruft which makes it a pretty terrible choice for new hires to ramp up on.

True, but only in legacy codebases. A new Java project is as pristine as a new Go project, and new Java libraries are just as lean (because there's a lot of cross-influence between the two environments).


> A new Java project is as pristine as a new Go project

The problem is that most Java developers have become so familiar with and attached to bloated frameworks that they simply aren't interested in trying any other way. They have a lot of time and effort invested into mastering these frameworks. "Let's use Spring for that", and endless talk of the "persistence layer" for even the most basic apps.


The same developers who would be willing to try Go would also gladly use new Java libraries, and they will be able to preserve much of their hard-earned expertise.

You're implying that the mere switch -- all things being equal -- has an inherent advantage, while I say the opposite: all things being equal, switching languages is always a net loss, other than a possible advantage in recruiting in some regions where HN is popular. Of course, all things are never equal, so there are many other considerations.


It's not hard to find people switching from Java to Go (e.g. http://www.infoworld.com/article/2608571/application-develop..., which I found within 10 seconds of searching).

It's true that Go doesn't have a lot of those powerful JVM features that you listed, but as with any engineering trade-off there are lots of people who judge the benefits of Go to be worth the loss of those things.


Of course there are people making the switch, but the numbers are not nearly as substantial at as people switching over from scripting languages (even in nominal figures, let alone percentage) -- which perfectly makes sense.

You'll also note that since that article was published, all the advantages listed in in it have either found their way into Java (lambdas, fibers) or to other similar languages like Kotlin (multiple return values). Go has the undisputed upper hand when it comes to command-line apps (I really like it that I can use a language so similar to Java for stuff I never liked using Java for, and I was never fond of using scripting languages that require tedious dependency management for standalone programs), but is at a fundamental disadvantage when it comes to long-running important servers.


Go is particularly well suited to long-running critical server apps. It has fewer GC issues compared to Java and is also simpler language (making it harder to screw things up - Java generics can get very complex).


> It has fewer GC issues compared to Java

No, it has more GC issues. It's just that there aren't yet enough libraries and big applications to make that apparent. It hasn't been stressed enough just yet.


I think it's likely that Golang apps won't stress the GC as much as Java does, because of the simple fact that you can't realistically use j.u.c-style concurrent data structures, since you don't have generics. Where the JVM GC really shines is when you're using shared-memory concurrent data structures, which are really great things—however, without generics, programmers just won't use them in the first place.

(I'm not saying this is a negative for Java, BTW; making shared memory data structures both fast and idiomatic is really important if you care about performance of parallel code.)


Why do you think generics are more relevant for concurrent data structures?


Because "programs don't need more than one type of dictionary, so the language can just hard code one implementation in" is at least a defensible position in a single-threaded setting (although I don't agree with it), but it definitely isn't in a scalable parallel setting.


Yeah. Go. The concurrent language with a single, mutable, thread-unsafe dictionary implementation.


It may have more GC issues, or maybe it probably has more GC issues.


> Go has the undisputed upper hand when it comes to command-line apps

Only because most developers don't care to look for the JVMs that offer AOT or refuse to use anything other than the OpenJDK.


Maybe it's just that Python/Ruby programmers are more inclined to publicly discuss their switching?


That particular example of someone switching is someone whose background is in Java, but moved to a project implemented largely in Go. He switched because he changed projects.


Sure, there is some nice things about the JVM.

However, for me, Java was the first language to get ditched when I got comfortable enough with Go to accomplish similar tasks.

Reasons are many, but Go definitely wins "single native binary" argument. Java has to be installed, and it has different versions that can be installed. Go you simply compile for whatever platform you want, and you literally have a single native binary. No other dependencies need to be installed.

Hot code loading and swapping is neat in Java, but most places I have worked do not have the operational skill to really take advantage of this, and instead compound that against the JVM's slow startup time, which makes it double bad. With Go, you ship a simple binary that starts up very quickly, and so operationally the effect of faster, more seamless deploys are a much better experience.


I think that those advantages are extremely valuable for command-line apps, and hardly matter at all for servers. Those organizations you've mentioned probably do take advantage of bytecode manipulation (they have undoubtedly used shadowing, and probably some agents) even though they don't write manipulation -- or hot-swapping -- code themselves, and they certainly enjoy the JVMs unmatched monitoring.


I agree that the JVM is way, way ahead when it comes to things like agents and monitoring.

For me personally, those aren't a big of enough of a win. I would rather have simple code that is fast to scale and fast to understand.

Dealing with something like a thundering herd of traffic is much more difficult when your application can take upwards of an entire minute to start up, and to optimize itself to run at decent speeds.

There is likely a sweet spot however. My good experiences with go are working on high scale projects with a handful of other senior level developers. Some other projects I am involved in are with more enterprise shops with many more developers with a wider array of skill levels. In projects like these the other aspects of JVM like how well supported it is and how there is so many other tools for it, it might still win in one of these enterprise environments.

But for many of my use cases, the JVM just feels like it has everything-and-the-kitchen-sink, and sometimes you just want a small, nimble solution that does a few things well.


I can see your point, and it's the best one I've heard so far in favor of Go over the JVM. But I feel that there are two serious fundamental problems with Go -- or rather two classes of problems -- that are likely to hinder progress as a Go project grows:

1. Go's over-fitting to Google's development style, especially the over-reliance on dependencies as source-code.

2. Go's lack of hackability that might bite you down the line when you need something that Go really can't provide. Go's only hack-hook is source-code manipulation (which brings us back to point #1), and at this early a stage we already see too many tools going down that ugly road.

Go is probably the least hackable mainstream language I've encountered. In C/C++ you can always poke around the implementation details when there's no other choice; with Rust there's unsafe; with Java (and other JVM languages) there's full bytecode control; with scripting languages there's metaprogramming. All those "backdoors" should, of course, be used sparingly if not rarely, and then are best done by experts and hidden from sight, but they're always there for when you need them -- and you invariably do for that last 1%.

With Go -- there's absolutely nothing. You can't even drop down to C to muck about because you'll mess up the delicate runtime. So Go is indeed a descendant of C, Java and Python, but neglects to provide the hackable escape hatches from the plain language semantics all of them do.

Those two things scare me (not that I'd give up on deep monitoring or polyglotism otherwise, but still) because not only are they risky, they're exactly the kind of thing that people don't notice when the project is young. I feel like there's a very important lesson here that seriously bit people in the ass that Go failed to learn (well, that and no support for immutability of any kind).


You forget to mention that golang also has an "unsafe" portion, and I've used it to "hack" around several issues before, all the way up to a (very hacky) dynamic code injection. Don't forget that golang also has an escape hatch of assembly.


That's a terrible escape hatch, because it's brittle and very much dependent on the runtime. A new runtime version can break your code and crash your process. It's mostly intended (as is Java's unsafe) to manually manage off-heap memory -- not to hack around language semantics.


I would think that all of your so called "escape hatches" are just as brittle, if not more. Once I compile a golang program, that binary will always run the same, no dependencies on a runtime that could be updated/changed out at anytime. If you aren't testing your code before deployment, that's your fault.

The only one that actually seems decent is the metaprogramming, which, in my experience, tends to lead to overcomplicated code and worse performance.

All in all, the only times I've ever needed an escape hatch is when I've been writing hacky things, or trying to be too clever. Too much "clever" is bad when programming.


> I would think that all of your so called "escape hatches" are just as brittle

Why are they brittle? They're not brittle at all, they just have looser semantics than the core language. They have their own semantics, which the runtime guarantees to uphold.

> that binary will always run the same... If you aren't testing your code before deployment, that's your fault.

Why work in such a primitive way? We're very familiar with what happens when source-code is overly dependent on a specific compiler version. Besides, dropping to C/assembly in a language with such a high-level runtime (not only a GC but its own global scheduler) is not an escape hatch; it's just using power tools to break through a hatch-free thick wall, which might work if you're careful not to break the foundations by mistake. You could do the same in all languages that do provide an escape hatch, too (if you'd rather break through the wall instead of using the hatch).

> Too much "clever" is bad when programming.

Absolutely, but sometimes just the right amount of clever can let you do truly powerful things that would otherwise be beyond the reach of the language. It's there just for those moments when you're stumped[1].

Experience (and I've been doing this for twenty years) shows that this point where some cleverness is necessary, always arrives at some point in the project's lifetime, and that cleverness often saves you a whole ton of work. Remember, the average codebase lifetime is about 10 years.

[1]: Plus some truly powerful stuff, like the ability to inject tracing code into a running application and then take it out.


Interesting points. I guess time will tell. Having used go for awhile now, these points just don't bother me.

Least hackable is a hard thing to define, but as you've defined it I suppose I agree, albeit in this context it often comes across as a feature to me.

Monkey patches are always monkey patches, and in golang your forced to fork a library to modify how it works. To me this is a good thing. It means that as the codebase evolves, the amount of "hacks" (if you will) are more often than not more clearly defined, and to maintain these hacks its easier to collaborate back and make a pull request, rather than just build up a collection of hacks that have to be maintained separately.

The fact that there is a higher barrier to entry to make these kind of changes, is simply not always a bad thing. Choose your poison, I guess. Golang is all about trade offs. In this case the trade off is its harder to simply add arbitrary code all over the place, but in exchange the culture of golang is more simple.


When pron posts on a thread about lang X, it tends to be 30% about lang X and 70% raving about the JVM platform.


More like 90% blindly advocating the superiority of Java. Does he ever sleep?


Without a definition of "succeed", this cannot be argued against or agreed to. Like every other language, Go will be used by some people and not used by other people.


I believe "doomed to succeed" is a reference to language evolution and popularity; discussed by the Haskell community

http://newsgroups.derkeiler.com/Archive/Comp/comp.lang.schem...


Go's success has me confused. My team enjoys using Go, but to me it feels like i'm a prisoner. The designer's slavishly followed opinions are laser focused on reducing variation across go codebases. There's definitely less to learn than most languages. Unfortunately, sometimes the blessed way of doing things doesn't work well for your problem and not only are you left with a hammer to cut the wood, but making a saw is outlawed.


The article hits on this but doesn't bring up Google's high turnover rate.

Google is a resume tick box. Go over to AngelList and look at lists of startups. Take a drink every time you see 'worked at Google' listed as a qualification. You'll be destroyed in an hour or so.

Thus people get jobs at Google, put in a year or two, and go off for a higher paying and/or sexier job or a startup of their own.

Go is laser focused on simplicity, maintainable code bases, and uniformity to allow the next crop of Valley recruits to pick up where the last crop left off.


If this was true, and not a just-so story, then it should be easy to point to several well-known open source projects that started out in Golang and ended up in some other language, or several concepts that were prototyped in Golang and then ported over to some other language.

Like every programming language ever, there are surely many Golang users who've used it solely to add a keyword to their resume. That's not a very interesting observation, because the same thing is true of Rust, Scala, and even Haskell.

Further, that doesn't really address the question of why so many teams select Golang in the first place. A programmer might use Golang to get the keyword on their resume, but a team shipping a new product has no such incentive.


A team might pick golang to check a box. Particularly the "our boss/organization/PR team wanted it" box.

I largely dislike Go but keep picking it because it is the lowest common denominator of languages my team will use and I really like them.

Even the proponents of Go on my team are moving away from it as their preferred choice, but for now it remains the only consensus fallback.


If it wasn't going to be Golang, what's the next most likely choice?


Some combination of Scala and C++ probably. Golang's central value to me right now is that I can keep a team that is split on those lines happy and cohesive. Which is more than enough of a benefit for me to put my own distaste in the background

The next language I want to learn is OCaml, but thats because I'm sort of obsessed with unikernels.


I think people who use Go in the first place are not those who think much about "can this be done in a better way?".

It's quite similar to the notion of "I'm a PHP developer and I don't understand why everyone says it is terribly designed! I learned to work with it and never tried anything else, so it can't be that bad!!!".

Not every developer cares about software development. There are plenty of people who chose this profession after they heard that a random developer can become the next Bill Gates by writing the right iOS app.

Having a language which doesn't require an inexperienced and non-interested developer to reflect on all the lessons learned in the last 40 years of software development and computer science fits the bill of this kind of person pretty well.

Sure, he/she is missing out on 4 decades of improvements to this profession, but who cares? Despite all the medical advances, there is still an economic niche for quacks selling "cosmic crystals" to cure your cancer.

There is nothing wrong with this. People don't pick a job in finance, because "they like to work with numbers" either.

We should just be aware of it.


Your argument seems to rely on go being the first language someone has learned. Very few people learn go as a first language. Most people I know in the Go community have 10+ years of professional development experience in a variety of the popular imperative languages and have used go for a couple years. I'm sure there are probably some people learning go as a first language by now, but I doubt it's a significant number.

So, "not knowing any better" is kind of ridiculous.


There are plenty of people out there which didn't manage or didn't need to advance beyond their first-year experience for the last ten years. "What did X do?" is a much better question than "How long did X do it?".

(For many jobs one year of experience is perfectly fine!)

I think people who can think critically and evaluate various options rarely join personality cults, which kind of explains Go's current community.


I think this comment does a pretty good job of summing up my perception of Golang's opposition.


To be fair, its no more ham-handed or insulting than the common refrain from the Golang proponents: "Go is for getting work done."


Fair point.


Let's not do SEO in HN comments. The language's name is "Go", not "Golang".


It's also useful for e.g. using Ctrl-F on your own comments or similar. Searchability optimisation can be valuable on its own.


By that logic you should also say Dlang, Rustlang, Nimlang and so on. Let's optimize for human readers instead.


Any sources that say Google had a high turnover rate? Only things I can find is that most employees have a short tenure, which seems to be due to lots of hiring.


For any big company, you end up with hordes of lazy or worse, very bad programmers. You need a COBOL-like language to allow them to produce things and not mess up things too badly.

GO fits the bill.


"Go won’t let you abstract yourself in the foot." :)


What a strange idea. The whole point of a programming language is to enable abstraction. I suppose assembler doesn't let you "abstract yourself in the foot" (whatever that means) either.


There is such a thing as too much abstraction. That's partly why Java has now that huge reputation of being a very enterprisey language.


That is actually due to a lack of rich abstraction mechanisms in Java.


I tend to think of abstraction as the price. To see why this is justified, note that you can trivially come up with an abstraction that has no benefit (eg. pointless redirection), but coming up with one that has no cost (eg. developer-, compiler- or run-time) is near-impossible.

It's true that many abstractions pay for themselves many times over, but not all do. For some applications, this means that a language encouraging a more direct solution comes out ahead; for others one looks for languages that make the wanted abstractions cheaper.


The whole point of a gun is to enable shooting.


What a good expression. Did the author originate it?


yes, it's from the article


>TL;DR Golang was explicitly engineered to thrive in projects built by large groups of programmers with different skill levels, and there is no larger such group than the open source community.

I think this premise could not be more wrong. The open source community is not a project team, and open source project teams are very likely much more homogenous and stable than teams working on commercial software.

Yes there may be non core contributors, but if contributions are not up to standard, they are simply rejected. If that means slower progress an open source project can live with that. A commercial project can not, because it has deadlines.


It's an interesting language test, of how easy it is to understand an open source project.

Looking at github, the lines of code are usually easy to understand in C and java. What's difficult is how the parts of the project fit together (which is never documented). Does Go help with that?


I think it can help with that in the sense that Go packages don't have complex boundaries and the type system is simple and self-contained. You don't have to trace an inheritance hierarchy to understand any given type, so a project of multiple packages is generally easy to understand just by reading each piece independently.


Inheritance can be a problem, but I was thinking more of the architecture, what calls what, who is in control, where are the various tasks done, what are the interactions... I'm not sure how a simpler type system would help with that e.g finding out which module does the task of interest, but I don't know Go.

[ Design patterns were supposed to help with this, with recognizable groups of classes. Sounds like a good idea, but I haven't found that, but maybe I don't know them well enough, or projects don't them well enough. ]


Isn't the issue that people who generally like Go read and write articles like this? ;-) The same is said by PHP devs:)


PHP has (sadly) already succeeded.


yet I doubt that if doomed to success has anything to do with doomed to succeed forever


Whether you like Go or not depends on whether you think of software development as engineering or as craft.


This got downvoted but I think there's more truth here than on much of the rest of the thread, though I might use words other than "engineering" and "craft". I'm fond of saying that Golang isn't a particularly great programming language, but is one of the great programming tools.


> I'm fond of saying that Golang isn't a particularly great programming language, but is one of the great programming tools.

Could you elaborate on what you mean here? Why do you not consider Go a language? What do you consider the requirements to be a programming language?


The way I read it, he meant that Go is not a great language. Go is "boring" as a language. However, it actually is a great programming tool. Great as defined by how long it takes to write module X, how well module X performs, how many bugs are in X, and how easy it is for a different programmer to come along and work on X later. In a real sense, the very design that makes Go boring is responsible for the good things.


This is an awesome point. I feel like programmers using Go care less about the language and more about the process of creating and maintaining a product.


I really dislike this description, which you see often in golang discussions because it implies either the people that prefer other languages are dilletantes focused on the wrong things, or the people who like golang are too stupid to use a more elegant language AND do product development.

I don't think either is true. What I do think is true is that every language makes trade offs and golang makes me less productive with it's choices & restrictions. I'm reserving judgement about how it impacts my teams aggregate productivity.


More like "... whether you've used any more modern languages than C" (such as ML and many other functional and research languages).


I have used SML, OCaml, Haskell, and many other languages, and I like Go, and use it for almost anything I do these days. So your statement is false. The only thing I did like more in functional languages was writing compilers (which ironically happens to be what I'm doing now in Go).


I didn't carry out a scientific study -- to my knowledge, no one is bringing any hard facts to the table when they talk about programming language preferences -- so you can't evaluate what I said as logically true or false.

For reference, I have used OCaml, Haskell, Golang and C extensively. I think Golang is a wasted opportunity to replace C. It's a mediocre language with a bunch of annoyances.


What kind of compiler are you writing? For which language and target?


For Go and sparc64, I did arm64 before.


You did the work to compile Go to arm64? Thanks for that then!


Yes I did, welcome!


I like how ML is more modern than C, but they were both released in the early 70s.


Indeed, ML was more advanced at the time of release, and has been improved since. However I won't blame C, since C was much more successful and (as Javascript knows well) it's very much harder to make changes to a language when you have to maintain backwards compatibility with a vast body of code used in production.


Compiled to native binary, garbage collected, no JVM and not object oriented is why I like it.


Very well put. I would also add nice UTF-8 support, easy concurrency and overall simplicity.


All those points along with the parents apply to Haskell too. Yet Haskell does not enjoy the same hype/success.


I think you'll find some people who wouldn't say that Haskell is overall simple, or at least as simple as Go can be.


> I think you'll find some people who wouldn't say that Haskell is overall simple, or at least as simple as Go can be.

You'll also find some people who say the opposite. We need to qualify what kind of simple we are talking about? Are we talking purely about language?

Are we talking about standard libraries? Ease of use of API's? Ease of use in analyzing performance?

If we just compare Go's syntax to Haskell's syntax you'll find they both have few reserved words.


What's wrong with JVM?


The JVM is a piece of software that rivals the kernel in complexity with for the most part redundant functionality (i.e. memory management, monitoring the running program, etc.). It does have the benefit of being uniform across platforms, but if you're dealing with a single OS, then the extra weight and deployment complexity isn't worth it - you're better off learning your operating system and its tools.


Nothing, IMHO. However, I do like Go's much leaner memory footprint for server side software. At least, that's been my experience: the same code doing the same task takes up much less RAM.


Someone correct me if I'm wrong but I think not using the JVM makes deployments much simpler. At least that was one of the benefits a team at Amazon stated about switching to Go while I was there


In practice, it doesn't make much difference.

You install the JVM once and rarely upgrade it.

You build and distribute your Java apps as fat jars (meaning, all dependencies bundled.)


But what happens when some of the apps require different versions of the JVM?


As long as you're using the latest version then this shouldn't be a problem as the JVM is backwards compatible.


Except on those fun occasions when it isn't really. :\


You know you can have multiple VMs installed, with different JAVA_HOMEs, right?

This is a solved problem.


Among other things, an unnecessary VM layer if all you ever run on is x86.


The VM part of the JVM allows for really great monitoring: there are standard ways for tools to hook into bytecode and add instrumentation without needing the source. There are also lots of mature tools available, but that's mostly because the JVM has been around for so long.

We're looking at Go right now, and our instrumentation is currently done manually at the source level. Are there, or will there be, tools to add instrumentation similar to those available on the JVM? I'm sure it's possible...


I highly recommend replacing any occurrence of, “Go is just not for you”, with "Go is probably not the right tool for what you're trying to do."

The former can seem, snide or condescending, even when that is 100% not the intent.

I write both C++ and C# frequently. I love both languages. But I deal with people who use either language exclusively and continually gripe about the other. And the proper response is, "it's probably just not the right tool for the thing you're trying to do."


> accept that they won’t change anything. The Go team has said time and again that the language is done for the foreseeable future. You are too late to the party. Some might cry about this, but this stability promise brings more long term benefits than any language improvement could. Breaking changes, even if for the better, are not always welcome

The promise of stability from a large software corp puts in place a solid language foundation people can rely on when building apps in the language. Someone building a successful app using the language shouldn't be able to dictate future changes to the language based on their own needs only, ignoring smaller or less popular apps. Golang's language spec is a big help with this.

When you've tried working with a language whose backers cancel work on a spec for 10 years, then tailor the language's functionality for the one application they themselves are building, you appreciate the promise of stability. When the language's backers open up their AST to programmer addons via annotations, then later duplicate the functionality of the most popular addon, you appreciate the backing company's understanding that long term benefits come from nurturing the community.

When you see a backing company suddenly retrench all the staff working on a programming language, you appreciate that Google is using Golang internally and is unlikely to do the same. Although Golang was born of a Google internal need, let's hope the needs of their own systems won't dictate future changes at the expense of the external community, and that they keep their stability promise.


> Go won’t let you abstract yourself in the foot.

What a brilliant sentence.


Abstraction if necessary but not necessarily abstraction.


"TL;DR Golang was explicitly engineered to thrive in projects built by large groups of programmers with different skill levels, and there is no larger such group than the open source community."

This would almost be right, but Go has much poorer language interop than C due to the GC and non-C compatible ABI. This means unless we're going to a monoculture of GoAllTheThings (not likely), Go will never succeed C as being the basis of fundamental open source community projects.

For myself, I was and remain mildly interested in Go as my next move off of Python(2). And still believe Go is a better move than porting to Python3- which as an aside makes no sense technically, but the coercion/threats from the Python3istas are beyond reproach (as if the existing Python2 community is the problem), and set me solidly against it. Of this new generation of languages, Swift was always my ideal. Both in language and implementation. Now that it's going to the server I can't help but find the attraction of serverside Swift and getting in on the groundfloor of that ecosystem. While gaining skills in the language of iOS to be irresistible.

Count me in as one eager for Swift 2.0. I believe Swift is the language that is doomed to succeed. http://www.tiobe.com/index.php/content/paperinfo/tpci/index....


Swift has an interesting situation. Within 6 months of its beta release it was already being used to publish iOS & OSX apps.

With it also being open source, and ported to other platforms I can imagine other mobile operating systems also embracing the language in hopes to get more developer traction.

Not to mention that they have taken a little from every language, and server-side swift is a whole different beast.

This is going to be fun ;)


Yes sir. And I'm no "Apple guy". My first computer was a Commodore64, and I own no Mac. Never have. My only Apple products in my lifetime has been 1 iPod Nano, an AppleTV2 (only for jailbreaking/XBMC) and 1 company iPhone 5S (after 5 years and 4 Android phones, some personal, some company, all running CyanogenMod when possible).

I hate how languages like Go get lumped in with "Google", an association which to me, is negative. For many, people fawn over Google, thinking a for-profit like Google does things in their best interests. When in reality it's temporarily mutually aligned interests.

I'm at the core if anything, a Mozilla guy. Not entirely because I'm not too diehard on the JSAllTheThings movement. I strongly lean towards native, even if my work consists mostly of Python2 backend for webapps. At least with native executing code it's possible to be open source. You never know what's executing serverside. So I'm less of a fan of the so-called "open web" (an oxymoron) than most. And that's discounting the difference in end product that exists between native/web. I like my web to be it's original intended usecase- such as how HN is. Nothing too fancy, data sharing.

I think from a language/implementation standpoint that Swift hit it on the money. That's what I would have wanted out of a Python3. If that were Swift, I'd be a huge fan. Swift just nailed what I believe people are really looking for. Go is a little sketchy in ways. I don't hate it, don't actively work against it as I do Python3... well, can't say I work against it but I don't extoll its technical churn. But Go at least is trying to solve a real problem, and solves more problems than it creates. Even if I think it squares up against Java more than it does C or Python.

Unfortunately, Swift is associated with Apple which has its own zealots (and zealous haters). It's regretful that programming is now fashion, hype, trend. But I do think they have the best-of-breed language here for general purpose use.

My money and personal contributions to these new wave of languages will definitely be to work on server-side Swift solutions. The thought of a single-language solution with a single GOOD language from backend to front if you use iOS is pretty amazing and I'm really looking forward to that, and Swift backend / web frontend as well.


Go 1.5 can call C and be called from C. So you can write a Go function to extend your C app.


Although Go was initially marketed as systems language it more often than not eats into Python's market share rather than C++ or Java's - at least in all places that I've seen it 'in the wild' (eg. saw that 1st hand at Google, read about that at Dropbox). Coming from professional Java or C++ development Go feels lacking but it feels like an incredible power-up when it replaces a piece of Python (or Perl, or Ruby, I guess...)


I am not quite sure I agree with this article. It's like saying that C wont succeed because it lacks every single feature that is available in modern languages (I am not talking about C++ and above).

Go was designed to create low-level stuff with high-level language and it does not need features beyond that. It has enough features to satisfy some extreme low level tasks. If you want high-level programs then write them in your favourite scripting language. I prefer coffescript due to its expressiveness but I realise that t is not everyone's cup of tee.

However, for low-level programming and where I know static compilation and performance is a key, I will go with go. Why? Because it will take me 10 times longer to do it in C. And although I like C, I will not kill myself to use it unless I am really have to.

P.S. my company has done some amazing stuff with go, docker, fleet and coreos in a very short time. I have no doubt it would have taken us much more time if we had decided to use something else.


Is there any "best practice" Go, especially in terms of architecturing apps? I come from a long php background, and spent the past 3 weeks learning and prototyping a Go project. Looking at my code, I definitely have "open source stage fright". Any links/advice/books appreciated.


Gofmt your code. Run errcheck, golint, and go vet, and make sure they don't complain. Run go test -race and make sure it doesn't complain.

The best Go code uses built-in types and small interfaces in its APIs. Use interface{} as a last resort, and then only if your function can really take anything. Don't overuse channels. Sometimes a mutex is more appropriate, and that's ok. Rarely use reflect. Don't panic except during package init. Never ignore errors. Don't try to make your Go code conform to the way other languages work. Magic is bad, don't try to make your code magical.

The go community is quite nice in general (there are bad apples in any group). Show off your code, it's the only way to learn, and chances are you'll get some good review comments at least.


I'm curious about two things.

(1) where does Rust fit in this?

(2) and if Go is lacking in the concurrency department and loses to Erlang in latency. Why don't people use Erlang/Elixir for servers and Python/etc for client side?


In reply to your first question, I don't think it does. Go and Rust were both initially marketed as "systems" languages, but in reality they make very different design trades. I would say that Go lines up more with Java or C# than it does with C or Rust. I would guess that having both Rust and Go in your toolkit will be a benefit in the future.


> Why don't people use Erlang/Elixir

Because Erlang is different. It's not just the syntax, even though that throws many people uncomfortable with much that's not a direct descendant of C syntax; it's the whole programming model which requires a real shift in perspective that simply isn't easy.

It's worth it once you start to "get it", but that can take a bit.

I do think Elixir gives the Erlang VM a better shot at the big time, because it lessens the syntax obstacle for many people.


> Because Erlang is different.

I'd say that fails to capture the full scope of the statement.

From where I stand, Erlang is not just a language - it's an extremely robust, highly opinionated event loop with its very own DSL.


> an extremely robust, highly opinionated event loop with its very own DSL

It's very reductive. Erlang is a distributed platform with a functional programming language, lightweight processes communicating through distributed asynchronous shared-nothing message passing, preemptive scheduler, etc.


(2) People tend to follow the path of least resistance even if not the most optimal. Erlang requires more effort in the beginning, but pays off immensely later on. It's easier to start learning go because it's not as strange. This is also why node.js became so popular. It has the lowest barrier to entry.


> (1) where does Rust fit in this?

It doesn't. Not any more than other languages anyway.


This is a very light article with not too much information. Go already succeeded simply because Google uses it. This means all of the problems they need to solve in Go has decent support (net/http etc.) and you can just use in your own projects, and this also means that the out of the box performance is decent. These are good enough reasons to use Go. If you are talking about language features I don't think that Go is that amazing. Supporting CSP is a big win though.


this:

  > Go won’t let you abstract yourself in the foot.
aside from being amusing -- I like this, but can anyone confirm its true in practice with Go?


The lack of generics (and operator overloading and type hierarchies) makes it hard to write grandiose frameworks and all but impossible to write DSLs. I consider this a good thing. You're definitely pushed in the direction of writing straightforward, no frills code that uses boring types with little magic.


In my experience, Go makes it hard to write libraries in the STL/C++ sense (that is, reusable abstractions), while making it very easy to write libraries in the "batteries" sense. So yes I think the metaphore is correct


I just started on my first Go project last night...and yeah, that feels about right.


A language success is largely determined by marketing. Go will succeed because a lot of brilliant people are using it and it's not bad. That's exactly why node.js is where it is now, and PHP was cool back in the days.

That said, I'll just leave this here: http://yager.io/programming/go.html


God, this is a beautiful turn of phrase: "Go won’t let you abstract yourself in the foot."


I don't quite buy that a pretty low level language reduces developer fright. In my mind Go is a replacement for C more than the next Python. In that respect it is still intimidating for developers who have never done or done very little low level programming.


I friend of mine who has dabbled in C for years is still pretty scared of it. He loves Go. He's gotten Go into production where he works. I think there are a lot of people like him.


Plan9's failure payed the karma points for go's success. Duh.


Go is simply the follow on to Limbo. It is the product of many years of experience supporting the construction of large systems. Most of its roots are from Bell Labs.


This article seems to suggest that Go was designed as a language for large teams. Firstly it was designed as an research project and secondly I don't think it does work for large teams.

The simple type system and lack of genetics makes code verbose. The dependency system seems to require everyone is on the bleeding edge, correct me if I'm wrong. The channel based concurrency is very elegant but appears to be too coarse grained for high performance programs that would otherwise use it.

That said I like the languages simplicity and do think it has it's uses in the world. Just not large team, large project development.


Go is not about research in the sense of inventing new things. The holy designers of Go (Ken Thompson, Rob Pike, Russ Cox) have clearly stated that Go only borrows from other languages (C, SmallTalk...). The goal is not to reinvent the wheel in a new, confusing language, but rather to put together parts that have been thoroughly tested. They make sense together and the result is a boring language that is made to be used.


To put it roughly, Go was made to appeal to Java developers as a better Java replacement. In contrast Rust was created to appeal to C++ developers as a better C++ replacement.


Maybe these programming in the large languages don't necessarily have to be fantastic for programming in the large, and in the long term. But they have to be great for this at least in the short term. So imagine that such a language shows itself to be good for making medium-scale applications in the first year (assuming that large-scale applications take longer to become "large-scale"). The code is uniform, people can easily get up to speed with whatever section they are working on, there are no big surprises - great. This language gets adopted in more projects because of the initial rite of passage, and some luck and marketing (hype and random factors seems to be given for new technology, in the short term). So more projects spring up following the same model. These also work great, and by now we have a handful of new, discovered concepts associated with learning and using the language. The language, ecosystem and implementations are still lean and easy to comprehend. And so some years pass.

Now this language is actually used for large applications. It's still all gravy, the code bases are still uniform and easy to understand. People can easily be trained. More projects adopt this language, or even use it to build things from scratch. It gets applied to more domains. Years pass, and things that were unobservable in the beginning start to rear its head. They weren't non-existing, but they were so minuscule in this large landscape (remember - big adoption of this language) that it was unobservable from the bigger picture. Now what was a problem for a few developers seems to be a problem for many people. For a while, they solve this pain point by educating about certain patterns to look out for and solve. This works for a while, but after a while more pain points become apparent. And like for the initial pain point, it is just not a pain point for a small group of ignorable developers, but indeed a systemic one. There seems to be something wrong. We can't simply solve this pain point with education and applying patterns - we need abstractions. There is some murmur about this - the principal point about this language was to avoid over-abstracting things. We need to practice constraint. This works for a while, but after some time the concerned voices of the people advocating this kind of restraint gets drowned out. These limitations are just too much for people to deal with. So people start suggesting and inventing so-called abstractions. And pain points are relieved. After a while you have a whole cottage industry of these abstractions. And people's day to day life with this language and its associated code bases are happier and more productive. On the other hand, there is more to learn now, and things aren't straightforward any more. You can't simply look up a library and have flat, easy to read code. You also need to learn the associated abstractions. You also notice that the technologies associated with these abstractions are getting kind of big. They are starting to take on a life of their own. And it seems like they don't really fit. Some of them feel kind of shoe-horned in, as if there was no general slot for them already installed, it just had to be jammed in there.

Now, is this language good for large-scale development? The language is still easy to learn. Somehow. There was a bunch of additions up through the years to ease some pain points. Not all of jive as well with each other, or with the original language. But with some elbow grease, it is perfectly serviceable. Not to mention all the associated technology that cropped up to assist the language in its ascent - that is the hard part. So the language is not really easy to learn any more, with the associated things. But people know it, there are code bases to maintain and it has proven that it isn't useless.

Is the language good for large-scale development? Doesn't matter. It already won and is here to stay.


Destined to succeed might make better english.


Aw, c'mon - where's your sense of imagination! No one would click on an article with that title (except Go fans). "Doomed to succeed" surprises the reader and entices them to see what it could possibly mean. It's a fantastic title!




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

Search: