3 ms·
C++, Java and JavaScript each have their own different kinds of complexities. The complexities of C++ almost always arise out of the extremely high degree of p
by PommeDeTerre 13y ago
C++, Java and JavaScript each have their own different kinds of complexities.
The complexities of C++ almost always arise out of the extremely high degree of power and flexibility it offers programmers.
The complexities of Java end up having to do with hyper-"architected" class libraries, rife with excessively-used design patterns to the point of being incomprehensible.
JavaScript's complexity arises due to core functionality that's missing (such as proper class-based OO, namespaces, and proper support for modularity), or core functionality that's limited in practice (like it's prototype-based OO), or core functionality that's unjustifiably broken (its comparison operators, semicolon insertion, its scoping, its type system, its awful standard library, among others).
Out of those three, JavaScript's complexities are by far the worse. The flaws are outright stupid to being with, and there's nothing that can really be done to avoid them in many cases. At least Java programmers can choose not to create and use bloated class hierarchies, for instance. And at least C++'s complexity offers superbly powerful features and excellent performance, and at least it's understandable how and why this complexity thus arises.
- mwcampbell 13y agoYou seem quick to denigrate JavaScript, and programmers who willingly choose it, wherever you can. But with regard to the kind of complexity the OP discusses, which roughly translates to added cognitive load, it's not at all clear that JavaScript is worse than C++ -- and I have real experience with both. To avoid dismissing C++'s complexity too easily as simply the price of flexibility and performance, let's review what C++'s complexity looks like in practice. For example, read this: http://simpleprogrammer.com/2012/12/01/why-c-is-not-back/ http://simpleprogrammer.com/2012/12/01/why-c-is-not-back/ Memory stomping bugs; all the ways to initialize a variable of a primitive type; copy constructors; overloaded assignment operators; move semantics; smart pointers; value versus reference semantics; the list goes on. Against the cognitive load imposed by complete control over memory management, and lack of verifiable memory safety, JavaScript's warts seem quite minor to me. I imagine that many programmers who work in "managed" languages would agree.
- thebear 13y agoAuthor of blog post here: Thanks for your lucid remarks. JavaScript certainly has its share of annoyances, but likening those to the complexity issues of C++ seems inappropriate to me.
- thebear 13y agoAuthor of blog post here: I believe JavaScript is another example where the problems (not sure if I'd call it complexity, but problems they are) can be understood by looking at the history of the language. Brendan Eich himself has said: "I created JavaScript in 10 days in May 1995, under duress and conflicting management imperatives."
- PommeDeTerre 13y agoTrue, that could very well explain its horrid state in mid-1995. But that was 18 years ago, and things really haven't gotten any better since then. The Harmony work is somewhat of a step in the right direction, but its impact will still be quite limited, assuming it ever does become a standard. C++, on the other hand, has seen significant improvement over the past two decades. Much of its complexity can now be avoided when using a "Modern C++" approach, all without losing access to its powerful functionality in those cases when it truly is needed. C++ has evolved in a way that makes it more usable. JavaScript has merely stagnated, without the community showing any real interest in cleaning up what's a very unjustifiably bad situation.
- betterunix 13y ago"at least C++'s complexity offers superbly powerful features and excellent performance, and at least it's understandable how and why this complexity thus arises" There are certain aspects of C++'s complexity that are inexcusable, especially in C++11. Why force programmers to figure out how to break cyclic references in their reference-counted smart pointers instead of just providing a real (but optional) garbage collected pointer type? Why force programmers to figure out how variables should be captured in a lexical closure instead of just always capturing by value (if you want capture by reference, why not just capture a reference by value?)? Why is there still no reliable way to report errors that occur in destructors? Why is error recovery still so problematic in C++, when other, older languages manage to provide useful facilities? Most of C++'s problems are the result of the attempt to satisfy everyone's needs simultaneously. Rather than doing one thing well, C++ does many things poorly.
- pcwalton 13y ago> Why force programmers to figure out how variables should be captured in a lexical closure instead of just always capturing by value (if you want capture by reference, why not just capture a reference by value?)? I agree with most of the points but this one seems suspect to me. This would break code like (forgive the possibly wrong C++11 syntax): auto sum = 0; std::for_each(my_vector.begin(), my_vector.end(), [](x){ sum += x; }) We actually made the mistake in Rust of making closures capture by reference or by value depending on what type of closure it is, which confuses newcomers immensely. It's scheduled to be fixed by making all closures capture by reference (and if you want to capture by value, use an object instead).
- rayiner 13y agoC++'s complexity does not arise from its power. With the exception of templates, C is just as powerful but far more orthogonal and simple. E.g. the difference between references and pointers. E.g. the phenomenally baroque template syntax. E.g. phenomenally complex rules for multiple inheritance. Slicing problem. Syntax so hard to parse only a couple do it right. Lots of features that just don't carry their weight (operator overloading).
- pcwalton 13y ago> Lots of features that just don't carry their weight (operator overloading). Operator overloading is crucial for things like graphics and bignums—basically, heavy math operations over anything that isn't a primitive.
- rayiner 13y agoIts a trick pony. I don't think that use is enough to carry its weight. Also, abusing it immediately in the streams library just encouraged people to find elaborate nonsensical uses for it.
- mpyne 13y agoOperator overloading is very useful in the context of generic code though (through templates). I've programmed C++ for probably more than a decade now and I've been bitten by many of its features at some point, but operator overloading would rank right near the bottom of my burn list. It can be abused, that's for sure, but so can many C features.