7 ms·
Rob Pike's confusion about why C++ programmers didn't want to move to go is partially explained by his focus on a particular problem domain at the time Go was b
by emtel 9y ago
Rob Pike's confusion about why C++ programmers didn't want to move to go is partially explained by his focus on a particular problem domain at the time Go was being developed. Google in those days was primarily concerned with writing highly concurrent request processing software, and at that time the vast majority of that software was written in C++. Writing highly concurrent C++ in the days before the language had things like lambdas, std::function, std::future, etc was definitely gross. In practice, a lot of the concurrent C++ code from that time period took on the callback-hell flavor of node.js code, but without the concise nature of JS. It was gross.
Go is obviously a superior language to C++ for writing concurrent programs in every way except possibly when you need to achieve maximum possible throughput (as in google's search clusters) or minimum possible latency (are HFT shops switching to go? I honestly don't know). However, outside of a few companies that have huge capacity problems, people weren't writing concurrent request serving programs in C++. They were using Python, Java, etc., and later, Node.js. So its no surprise that people flocked to Go from those languages and not C++, because there wasn't a huge population of C++ programmers in this problem domain looking for a better language in the first place.
The other C++ programmers were down the hall, working on Chrome and Android (which has a ton of C/C++, despite Java being the primary app development language). The reason they didn't, can't, and won't switch is that managed languages like Go are not well suited to highly resource constrained environments like phones, or browsers that are supposed to run on win XP machines. (To say nothing of games).
The advantage of C++ is not, as Pike pompously suggests, that C++ programmers have too much fun playing around with templates and other navel-gazing pursuits. The advantage is that it is a high-level language that lets you do what you need to do with very, very close to the minimum possible resource usage. And there are programming environments where that really matters, and those environments are never going away.
- segmondy 9y agoI don't think I will say that's the advantage of C++, but rather the perceive advantage of C++. Anytime I've met a great C++ programmer, they start off by ratting of a list of C++ features they don't use.
- Retra 9y agoAt my work, we don't use the standard library and we don't use references. And it's the only C++ code base I've ever liked working on.
- gowld 9y agoHow can you write efficient programs without references? And why are references so painful for you anyway?
- 0xcde4c3db 9y agoA C++ reference is basically a pointer that pretends to not be a pointer. If they have any efficiency advantage over const-correct pointers, I've never heard of it (though I'm at best an intermediate C++ programmer). Points often cited as disadvantages of references include: - There's nothing that clearly distinguishes them from regular variables at the point of use. They can therefore obscure the fact that you're not passing by value or mutating a local/member variable (particularly if you don't have good IDE support, and good IDE support for C++ is damn hard for some environments/toolchains/targets) - There is no concept of a null reference, which can create friction with interfaces that use NULL for optional parameters These points are also often cited as crucial advantages of references. So it goes.
- yuushi 9y agoThe second is absolutely an advantage of references, and other than having to use (if I'm being honest, legacy and/or bad) interfaces, there is absolutely not a downside in this regard. The first can be a legitimate complaint, although I find it's rarely an issue in practice.
- stevedonovan 9y agoContrast with Rust references, which are very much their own type (they more resemble pointers in their behaviour, with explicit dereferencing and address-of needed). As a C++ dev, this took some getting used to! But I never was a fan of how passing-by-reference was invisible at the call site.
- millstone 9y agoI agree your points regarding C++, but it's not true that Pike was focused on the request-processing niche. Go was specifically designed to be suitable for programs like web browsers, compilers, IDEs, maybe even OSes. We know because Pike said so - see the "Systems Language" page at https://web.stanford.edu/class/ee380/Abstracts/100428-pike-stanford.pdf https://web.stanford.edu/class/ee380/Abstracts/100428-pike-s... (warning, PDF).
- emtel 9y agoI know Pike _said_ that, but I think the differing level of success of the language in these different niches speaks louder. In particular, I think the idea that anyone serious is going to build a large desktop application like a web browser in a language that doesn't expose OS-level threads to the programmer is pretty laughable. Similarly for the idea of building an OS (or at least an OS kernel) in a garbage collected language. edit: I realize I didn't really respond to your point. My point is that regardless of what Pike said, request processing permeated the atmosphere at Google, and deeply influenced the design of Go, whether Pike realized it or not at the time.
- millstone 9y agoThat's really interesting! Go gravitated towards request-processing services in part because that was the largest audience in the immediate environment, which in turn gelled Go's future. We can imagine Go with the same engineers but at Microsoft or Apple or Mozilla, and its evolution would have been different because its first clients would have been different. The times make the man, and the language!
- geokon 9y agoBeing a C++ dev, I think you're on-point about the reason people still choose C++ but my suspicion is that it part truth, part group-think and it won't really hold out. I could be totally wrong, but have you had to optimize a tight loop in C/C++? It sucks and a lot of stuff is missing : simd, likely/unlikely branches, the compiler has a lot of trouble knowing when lines of code are independent and can be done in parallel (b/c const =/= immutable), in-lining can't be forced when you know it gives better performance (if you use GCC extensions you can alleviate a lot of this..but that's tying you to a compiler). Yeah C++ is generally faster than Go, but there is a lot of performance typically left on the table. The language kinda start to work against you when you start to dig down. So you slap some shit together and the compiler will do a decent job, but most C++ devs aren't even looking at the compiler output But the elephant in the room is that more and more of our available flops are on the GPU and C++ isn't helping you there at all. Not only that, but the GPU is giving you way more operations per Watt (and that's what a lot of those people care about). And finally, when you throw stuff onto the GPU you are also leaving the CPU available to do other things. So there are a lot of "wins" there. As you illustrate, the areas of C++'s relevance is shrinking, and shrinking into the area that is very GPU friendly. So the way I see it, C++ folks will start to write more OpenCL kernels for the performance critical pieces and the rest won't matter (Go or Clojure or whatever). The GLSL is kinda lame and too C99ish... so maybe someone will write a better lang that compiles to SPIR-V, and it's not exactly write-once-run-everywhere, but it could be much better than writing optimized C++ and it can run everywhere. It's more of the cross-platform-assembly C/C++ wants to be
- yuushi 9y ago> SIMD Intrinsics are directly callable from C++. > likely/unlikely branches Most compilers have extensions that will allow you to do this (__builtin_expect and so on). > in-lining can't be forced when you know it gives better performance Again, most compilers have this, not just GCC, e.g. __forceinline. > the compiler has a lot of trouble knowing when lines of code are independent and can be done in parallel (b/c const =/= immutable) This is true, as aliasing is a real issue. The hardware itself has some say over this anyway, dependent on its instruction scheduling and OOE capabilities. What you don't mention, however, is the fact that almost no other languages offer any of these, let alone all of them. Rust may be the exception here, although some of this is still in the words (SIMD, I'm not sure about the status of likely/unlikely intrinsics). For GPU programming, if you're using CUDA, you're almost certainly using C or C++, or calling something that wraps C/C++ code. Not everything is suited to GPU processing anyway, there's still a lot of code that's not moving off the CPU any time soon that needs to be performant.