4 ms·
Better than C#? Better than Python? I think your definition of "mainstream" might be a little narrow, or else you have a very odd understanding of what makes
by betterunix 13y ago
Better than C#? Better than Python? I think your definition of "mainstream" might be a little narrow, or else you have a very odd understanding of what makes a good high-level abstraction.
Also, why limit ourselves to "mainstream" languages? Once upon a time C++ was not mainstream. Why should we shy away from Lisp, OCaml, or Haskell just because they are not popular? In every discussion about C++ and its technical ups and downs, someone points to its popularity, as if that were some kind of justification. The history of computers is overrun with examples of popular-but-inferior technology.
- SamReidHughes 13y agoYes, better than C#, and waaay better than Python. Similar to but slightly better than Haskell, too. I don't know about OCaml. (edit: C++'s main deficiency against C# and Python is its lack of a reflection system. Against Haskell, C++ is well known for being similar, but templates in C++ are more flexible and less constraining than Haskell's type system features -- for example if you want to overload + you don't have to buy into the entire Num typeclass.)
- betterunix 13y agoI would say that the lack of a standard garbage collector ("smart" pointers do not count since programmers must manually break cycles and decide among smart pointer types) is a pretty serious deficiency. I would also point to the abysmal error-handling support in C++; you do not even get a reliable way to report errors that occur in destructors. Really though, my big issue with C++ is that the high-level features are bogged down by low-level details -- if I wanted to deal with low-level details I would not be using high-level features in the first place. Why should I have to manually determine how to capture variables in a lexical closure? Why should I have to manually declare "virtual" inheritance to deal with the multiple inheritance diamond? Why are destructors not virtual by default? Why are string literals still pointers to character arrays, why are arrays still not bounds-checked, why are integers still fixed-width (and why are integer overflows not reported as errors?)? Yes, these things all make sense sometimes but in most cases they are the opposite of what you want -- you should have to write more code to get this behavior than to avoid it.
- SamReidHughes 13y agoWell, I agree with your complaints about the annoyance of lacking garbage collection, but not everything you complain about. The only nit I really disagree with you on in this post is that it's certainly reasonable that you should have to manually determine how to capture variables in a closure, in C++, because of the nature of the language. Also, many other languages avoid the multiple inheritance diamond simply by not allowing multiple inheritance (and others do it a bit better). The other questions, you know the answer to, and the answer is very obviously performance or compatibility with C (or just bugs in the language). But I'm not claiming that C++ is less annoying to use. I'm saying it has better facilities for making high-level abstractions. That's because of its type system, and you have to go to something like Scala, Haskell, or other statically typed languages, or maybe something homoiconic like Lisp, or something odd like Oz, to really beat. You can make better, more accurate abstractions in C++ than in other mainstream languages, and they're safe and solid, while in languages like C# you often end up having to resort to unsafe conversions.
- betterunix 13y ago"The only nit I really disagree with you on in this post is that it's certainly reasonable that you should have to manually determine how to capture variables in a closure, in C++, because of the nature of the language" I disagree here. First, the nature of the language is no excuse -- I am criticizing the nature of the language to begin with. Second, in this case, there is a sensible default: always capture by value. If you need or want to capture by reference, create a reference and capture that -- which is already what people have to do when they return a closure and use smart pointers to maintain the lexical environment. "The other questions, you know the answer to, and the answer is very obviously performance or compatibility with C (or just bugs in the language)." Except C++ does not maintain compatibility with C, and "performance" is not an excuse either. If performance is a concern, create a keyword to disable default behavior; e.g. if you want to not have a particular destructor be virtual, then there should be a keyword for that. Even compatibility with C is not an excuse -- already the extern "C" syntax is used to disable the name mangler, so why not go all the way and have it also disable things like array bounds checking and creating string objects for string literals? Basically, C++ is a language that makes unsafe code easier to write than safe code; this is the opposite of what a high-level language should do.