Why C++ Is Not "Back"
simpleprogrammer.com
simpleprogrammer.com
I write games, mostly, so performance does matter to me, though I'm not trying to squeeze "every last bit of performance" out of a chip. I just want some parts of the code to be entirely predictable in performance. So C++ and OpenGL are still my tools of choice. Been using C++ for years and would ace that set of interview questions (except possibly the list of algorithms in <algorithms>). And yet...I actually hate C++. It just happens to do the job better than anything else.
And it also happens to interface really well to a REALLY good scripting language, Lua.
To some degree I wonder why everyone focuses so much on Java or C#, when the amount of overhead code you have to write is similar in both cases to C++. Yes the languages are easier to understand, which is good, and they're often wrapped in IDEs that make it easy enough a monkey can produce code that will compile, but it still requires a lot of boilerplate to do just about anything. More than C++ in some cases, though not always. So much that they make the IDEs write a lot of boilerplate for you -- but the overhead is not only in typing out the lines, but in screens and screens of code that distract you from the actual problem you're trying to solve, and that you have to sift through to find the code with the bug you're looking for.
So I stick with C++ for things that need speed, and I use Lua for things that don't -- and I promise you that I can write just about anything in fewer (legible) lines of code in Lua than it would take to do the equivalent in C# or Java. And since # of bugs is proportional to the number of lines of code, I end up way ahead.
Quite true, thankfully WP8 supports native now. If portability is not a big deal, I prefer C# and DirectX (via sharpDX). It's much less code than C++, and just not as insane.
> And since # of bugs is proportional to the number of lines of code, I end up way ahead.
Can't tell if you are being serious here. That's just not true at all; it's well known that LOC is a poor indicator of bug occurrence.
If I create an algorithm in X lines of code in one language, and I can create the same algorithm in another language in X/10 lines of code, it will be easier to understand the latter IF ONLY because it's more concise. And easier to understand means that, given a spec, it's easier to see that it's been implemented, special cases and all.
And easier to understand also means the bugs will be more obvious, easier to prevent in the first place -- and easier to find and fix when they do occur. Q.E.D.
If you want to see an example, check out this benchmark -- the Lua code [1] and the Java code [2], with Java at 9x the Lua. Can you seriously claim it would take the same amount of time to debug both, and that they have an equal opportunity for bugs?
[1] http://shootout.alioth.debian.org/u32/program.php?test=knucl...
[2] http://shootout.alioth.debian.org/u32/program.php?test=knucl...
Then not all defects are created equal. Can the defect be easily detected via static analysis or unit testing? Those defects will wash out during the dev process, but the time needed to find and fix them has to be considered. We also have to apply more weight to wicked defects that are not easily detected (say memory corruption in C++ that causes bad behavior away from where the defect actually originates).
I don't have any papers though I believe this style of thought originates from the 70s (like everything else in our field).
There is always the folktale about Simoni: some PM at early MSFT instituted a lines of code metrics to measure and rate programmer productivity. The first week, Simoni wrote down something like -10000 LOC for the amount of code he deleted that week. The PM was pretty silent after that. I'm sure I've got this story completely wrong, but the point is that LOC are a crude and crappy metric in any case.
Edited to remove dumb generality.
Please think about what you are saying. Such an overly broad statement is so easy to shoot down, I'm sure there are plenty of other ways of minimizing bugs. NASA and Boeing have this figured out, for example, although it is incredibly expensive (formal verification, independent redundancy, extensive testing, static analysis, etc...).
I looked for the reference but couldn't find it, but there was a meta-study of lots of different papers claiming that this or that new programming methodology would reduce the number of bugs in code, and the meta-study came to the conclusion that, in fact, if you just count the lines of code in similar implementations, you find a correlation between LOC and number of bugs that explains all of the claimed methodological improvements.
So yes, fewer LOC (for implementing a particular problem) IS a good indication you will have fewer bugs.
I didn't find the reference, but I thought it would simply be obvious that if it took many more LOC that there would be more opportunities for a bug to hide out.
Your reply to another question about LOC seems to indicate that you think I'm making a claim about LOC as a measure of productivity or of absolute # of bugs created per LOC.
This couldn't be further from what I'm saying. I've also taken great happiness out of deleting lines of code -- especially other people's code ;) -- and so measuring productivity in LOC is insane. At the same time, can't you see that if I delete 10000 LOC, then I've deleted a huge number of potential bugs in all that deleted code? I've CERTAINLY reduced the maintenance costs of the code, no matter how you slice it.
I'm also not talking about comparing MY code to anyone else's, but rather how many bugs I'm going to write if I have to write 400 lines of code in Java vs. 40 lines in Lua, and I am going to tell you right now that it's far less likely I'll write a bug in those 40 lines of Lua -- I almost don't care what a study alleges, I'd need iron-clad proof with REALLY specific results before I'd believe otherwise. It's pretty obvious to me that there are fewer chances to make a mistake, static analysis in Java notwithstanding.
And if I do end up with a bug, that looking at those 40 lines on one screen it will be easier to see what's happening and FIX the bug than if I have to jump all over the place to see what's happening in 400 lines of code.
And a 10-1 ratio of code size may not always be true, but it does happen. Java is VERY verbose compared to Lua.
And you can use NME to create compelling (performant) applications on those platforms you have listed and more. Recent builds have included support for qnx/bb10 and I think they are working diligently towards win8.
Since the underlying enabling technology is haxe[1] you can use macros[2] to create more abstract DSLs specific to your use. Someone created a shader language for incorporating vertex and fragment shading into your code for example[3].
[0]: http://www.haxenme.org/documentation/about/ [1]: http://haxe.org/doc/features [2]: http://haxe.org/manual/macros [3]: http://haxe.org/manual/hxsl
For example how could I have done anything of this in another language like C#/Java?
- Writing a Video on Demand streaming library that was using the torrent protocol and unicast sockets. Required to be platform independent.
- Writing a web browser plugin for all webkit browser and IE that interfaced with OpenNI and Kinect SDK, using ffmpeg to stream RGBD video to a server. The plugin was based on Firebreath which is a C++ library for making portable plugins.
- Developing a high-performance iOS/Android app which requires a lot of OpenGL graphics and computer vision algorithms.
I don't particularly like C++, but I don't see how anything of this could have been done with another language. If so, please educate me!
Admittedly for Lua the increase in size is not so big, what is the compiled interpreted now, like 200kb? In any case, it is certainly longer than the comparable C++ program.
I agree with you completely that a more significant factor to correctness is in the "legibility" of the code to the author/maintainer. If you can read Lua better than you can read C++, one should by all means use Lua whenever possible because you will produce fewer defects.
I think your point about why the industry focuses on java/c# when it requires the same overhead in code to c++ is exactly why there is a recent "resurgence" in c++ . The whole back to native is a recognition that java (especially j2me) and c#/.NET has failed to deliver on most of its marketing promises. It isn't to say they don't have compelling visions, but in the end they don't offer any more than C++ and you get alot more portability and predictability.
Just my $0.02.
> C# on either platform requires you to ship an extra 10Mb of libraries, and (especially on older phones) adding C# overhead on top of everything else just doesn't make sense.
These sound like two different problems. I think C++ is much less portable than C# but you might be right about the code bloat problem. Though C++ apps also quickly pick up bloat.
Are you saying there is a common set of C++ libraries that ship with both iOS and Android that you could dynamically link to in your app portably? Or are you saying that you can get by with shipping less library code on C++ because there isn't a single big interlinked standard library?
I do link in some of my own libraries, but the code compiles to less than 1Mb.
Mostly what I link to is OpenGL, which is available on iOS and Android, and a few standard Posix APIs.
I am a good C++ developer but my dislike for the language has grown ever since c++11. Many parts of the language are arcane and unfortunately these parts are used over and over again by many programmers either to show of their 'coolness' or because it's the only possible way.
Here try this for size: https://github.com/boost-lib/bind/blob/master/include/boost/... (sorry if that blurb made you blind)
I also dislike perl. A large amount of perl code contains shorcuts - like $^p or %#p (not real perl patterns but I hope you get the point). These patterns are ungooglable and hard to remember. The only people who know them are those who have spent a lot amount of time with the language.
The result is code that is extremely hard to understand and read.
Languages must be optimized for reading and not writing. Of course, nobody is asking one to go overboard (like COBOL) but reading a computer program should not hurt the brain and should not require years of training.
This is why I will not advocate C++. I would advocate C, Python or JavaScript (yeah javascript, it has it's pitfalls but it's very easy to master). There are possibly other languages like Ruby but I haven't taken the time to learn them.
(BTW, If you want to see how C++ could be done right, look at something Qt from an API point of view).
I find it ironic that you dislike C++11 but the example you link to is only bloated due to the lack of the very same features that C++11 adds (in this case variadic templates would make that file 10 times smaller).
And it only really exists in the first place to paper over the lack of lambda functions, which C++11 also added.
Modern C++11 code is much easier to read and understand. The majority of added features are all about promoting that very ideal.
http://qt.gitorious.org/qt/qtbase/blobs/59fb0328392a5fc47e3a...
(search for the #else bits)
Why? It's so damn easy for me to understand.
> I also dislike perl. A large amount of perl code contains
> shorcuts - like $^p or %#p (not real perl patterns but I
> hope you get the point).
Well, that's not so fair - as that's... not (capital "P") Perl. That's like mimicking how a foreign language sounds like to you, (without context)http://www.youtube.com/watch?v=Q1VGoKBKR3I
and declaring that language unreasonable. So no, I don't understand :)
I owe quite a bit to Perl. I couldn't, ever, learn C++.
Like I said, writing code in any language is easy. Making it readable for others is the hard part.
Sadly, that was also the day I gave up on learning Perl, since I am the maths kind of guy and I get hopelessly lost if my programming language isn't built on solid logical ground, with few "core" features that I can actually aim to master.
Some of the boost libraries actually demonstrate this very well. If you look at the implementation of the library, you may be intimidated by its complexity (as you have shown with bind), but if you look at examples of its usage, you will often find it a lot cleaner than other languages.
Imagine what you would have to do in Java in order to do what bind does:
int diff(int a, int b) { return a - b; }
auto reverse_diff = bind(diff, _2, _1);
assert(diff(5, 2) == 3);
assert(reverse_diff(5, 2) == -3);
(Obviously, this particular example is trivial in any dynamic language, but that's a different debate)I'm not saying C++ is the only or even the best language for creating statically typed DSLs. But it is a language in which you can optimize for readability in a much more radical fashion than in some other mainstream languages.
In Java, however, lots of things are done outside of the language to solve similar meta-programming issues. For instance, many of the new annotations are only available within a suitable container that interprets them at runtime. Some of these things even need byte code manipulation. The resulting system is not generally simpler than C++ in my opinion and you have the same separation between library/container/runtime makers and mere users.
A lot of the code that tries to showcase new C++ features often falls short on some of the intricacies of the language or doesn't embed it into a larger scheme of a library. If my library offers customization via ADL across the board that kind of coding goes right out the window.
I'm aware of the proposals to make function objects through ADL, but this is but one example where the complexity of C++ comes to the surface.
That said, I don't like the fact that each and every feature of C++ comes with a really long list of weird special cases that are impossible to keep in your head.
And you WILL have to debug it. Even if your code is perfect, one day someone will stomp on your memory and you'll be looking at this stuff in gdb, cursing the day you ever heard of Boost.
Assuming this is a real problem for you, and you aren't just looking for arguments to validate your dislike: `perldoc perlvar` and then search for the variable.
When I was doing perl, I used a lot of special variables. I don't see why you shouldn't know what $_, $!, $0, $? do when you are programming perl. I avoided the lesser knowns, but that is how it is in every language - there always are obscure features and it's the programmers responsibility to write reasonable code.
C on the other hand comfortably fits in my head. It might be possible to declare several complicated declarations (especially with pointers) but the language is still largely readable. I would argue that many of the extensions that C++ provides over C feels bolted on (as it was originally) and still not organically part of the language.
The addition of classes and objects in C++ was seen as the most significant addition to C. But over time, I have learnt that sophisticated static type systems like that of ML or Haskell are much more useful and expressive.
At the end of the day we don't need a C on steroids with every feature on the wishlist and a 2000 page reference manual. We need an easy to use expressive systems language. I would rather call it "C with some chosen features" rather than "subset of C++".
If this[0] is a valid copy of the spec and my calculation is right [1] then it's 1360 pages. Seems a lot, but I have no idea what the length of ANSI standards is.
[0] http://quimby.gnus.org/circus/cl/ansi-cl/ a draft but i think close to the final thing
[1] for i in `ls *.ps`; do gs -q -dNOPAUSE -dBATCH -sDEVICE=bbox $i 2>&1 | grep -c HiResBoundingBox; done | awk '{ sum += $1 } END { print sum }' , and each ps page is actually two
The spec covers not just the language itself, but the whole standard library.
> The R5RS Scheme specification is 50 pages.
And with those 50 pages, you can not do anything useful out of the box. Yeah, you can solve SICP excercises, but thats essentially it. All useful features are implementation specific, and the Scheme ecosystem is more fragmented than the Balkan. Scheme code is essentially non-portable amongst the 1001 existing implementation. You dont write "Scheme" directly. You write code either for "Guile" or for "Chicken" or "Bigloo". PLT doesnt even call their implementation Scheme any more, they call it Racket. You dont write Scheme, you write Racket.
This leads to the question of why a standard was nescessary at all, if youre not standardizing a critical amount of features to enable portable code.
"The C++ programming language", third edition, starts its appendices on page 791, its index on page 869, and ends on page 910.
Both use about the same line spacing; the C++ book is about 10% wider and its lines are about 15% longer. It also has fewer comparisons with older omplementations such as MacLisp and Lisp Machine Lisp, and maybe a tiny bit less verbose.
I do not think either is THE standard, but they should be representative. So, there is nowhere a factor of ten.
Common Lisp is large partly because it has everything you would ever need (print the integer 4 as 'four', as 'fourth', as 'IV' or as 'iiii'? You got it. Pluralizing strings? You got it). The loop macro (a for loop on steroids, with all its positive and negative effects)? 38 pages. Pretty printing? 22 pages.
Did they? Somehow I didn't notice everyone moving to other languages :) C++ has its obvious strengths and is a widely used language. So it doesn't need to come back - it's already here.
> C++ is the wrong direction for the future
I could accept this argument only if author would focus on fundamental features that C++ doesn't readily provide - inherent concurrency safety for example and so on. So languages like Rust can be considered a better direction for the future which lies in massively multicore architectures. But C#? No, it's not a direction for the future in comparison to C++.
[1]: http://www.oracle.com/technetwork/java/intro-141325.html#334
And while as general purpose language Java is used quite a lot, it can't replace C++ for applications which require best performance. So Java really fills its own niche, and I wouldn't consider it as a full blown successor of C++, even if it was intended to be such.
As a related aside, Microsoft recently enabled us to use C++ for WinRT UI apps; keep in mind that WPF (WinRT's predecessor) only supported C# and VB (well, their was the CLR version of C++, but who used that?). So now you can write your Win8 metro app in C++ if you want, but why go through the pain and misery of doing that? Why choose C++ if C# is good enough for what you are doing?
C++ can't be fixed by adding to it. That's how it got so unmanageable in the first place. Personally, I just write in C when I need performance, but then again, I don't work on large projects that need raw speed.
For me, D and Go are good enough. They beat the pants of any interpreted language, and they offer compelling features not found in C++ (like simplicity, have you seen D's templates? Work of art...).
Now, D and Rust are another story. After doing a bit of reading, I'm actually very excited about Rust. For me, Go is essentially completely useless: it fills the same niche as Java, C# or--far more importantly--Haskell or OCaml. If I need code that's relatively fast but don't want to sacrifice memory safety or the convenience of a high-level language, I can do much better than Go.
On the other hand, if I want really low-level access to the system, for whatever reason, I don't have many good choices. I could do C, but that's rather unsafe and unpleasant; I could do C++, but it's a gigantic, overly complex language and also rather unsafe and unpleasant and I could do D. (I've actually heard good things about D but have never tried it.)
Rust gives me the perfect alternative--a simpler, higher-level language that's more pleasant to use but still lets me operate at a relatively low level. So next time I need to do something like that (which, honestly, probably won't be soon), I'm almost definitely going to use Rust, even if it's in active development and changing all the time.
EDIT: In re-reading this comment, I have realized that "high-level" and "low-level" really aren't great terms (at least the way I'm using them). Particularly, they're not mutually exclusive: a language can both support a high level of abstraction and provide low-level systems access where needed. Of course, I can't think of any language that actually does this, but Rust seems very promising.
I'd vote for D.
There will still be churn, but it's much smaller nowadays; once we hit 1.0 we will be committing to backwards compatibility.
C changed going to ANSI C, and C++ change a lot from "C with classes" to the first standard. And D, the one you would "vote for"? Wasn't there the whole mess between 2 versions of the language and libraries?
So, why should Rust be any different, considering it's still in design and pre-stable?
When the spec freezes and Rust hits version 1, it would be a fully suitable language for his needs.
Since you cannot easily use Rust libraries from C -- where is the .h header file generator? -- you cannot easily use it from any scripting engine either. How would its language constructs carry across on the C ABI anyway?
So, Rust also accidentally becomes a final, top-level language, competing in that space with Javascript, Python, Ruby, PHP, Perl, Lua and so on.
Rust does not stand a shadow of a chance in that space. Therefore, it can only suffer a fate worse than C++, which in spite of all problems can still be accessed from scripting engines.
I also like Rust, but I'll wait until it's more stable and we have a couple of books to learn from.
Java compilers to native code:
- VMKit
- gcj
- Excelsior JET
C# compilers to native code:
- Windows Phone 8 deployment
- NGEN
- Bartok
- Mono with -aot
Additionally C# has control over memory layout via pointers, aligment attributes, marshaling, structs and generics.
> Additionally C# has control over memory layout via pointers, aligment attributes, marshaling, structs and generics.
This is not true. The level of control you get is extremely limited due to the fact that very few types are values in C#.
So is C#, bytecodes are only used as a storage format.
With Microsoft tooling you can JIT at load time, NGEN at installation time, convert to MDIL when uploading to Windows 8 App Store, or convert to pure binary with Bartok in Singularity.
With Mono tooling you can JIT at load time or generate binaries with mono -aot.
With Cosmos OS , it gets compiled to native code.
> This is not true. The level of control you get is extremely limited due to the fact that very few types are values in C#.
Please provide an example where Go compilers offer more control than C# ones.
type T struct {
X, Y P
J *Q
Z [42]struct {
A R
W [100]S
}
}
Please note that P, Q, R and S are arbitrary types, not just a subset of value types, and an instance of T is contiguous in memory.I was actually under the impression that any value type could be used in fixed buffers.
You can however workaround that by using fixed byte buffers with serialization, but it is not so programmer friendly.
Neither did the FORTRAN and COBOL programmers back in the days. The reason is that there were plenty to do (and still is) for those already involved. That is also the case to a less degree with C++. It is just that most of the growth has been elsewhere. You won't find much web programming in C++, which is the area where the largest growth has been. There sure is some, I even have encountered web application in FORTRAN, but most web applications are written in PHP, Java, Ruby, Python and others, not C++.
If C++ had never been considered for new projects, it would have been in sharp decline, which it is not. What I said was that most of the growth has been elsewhere, like in web where there is hardly any C++, and mobile apps, where there is relatively little C++ (some on iOS, but Objective C dominates there).
My main point was that as long as the whole industry is in growth, you may not notice that the world has moved on, at least not if you measure the health of X by the "still new projects in X".
It really helps to know what goes on under the hood. For that, I'd say C++ has strong didactic value.
Lucky are the ones who have someone to teach them this stuff. If you have to find it out yourself it is an endless pain.
I think I could handle the Great Old Ones. But C++, never again.
"How many ways are there to initialize a primitive data type in C++ and what are they?"
I guess the answer is two: implicitly at program startup or through assignment. But then, maybe he wants to differentiate between int j=0, int j(0), what constructors do in x::x : j(0){}, and whatever.
"What is name mangling in C++ and why is it used?"
There is no name mangling in C++. Some compilers do map names to C-compatible identifiers, but that is not C++'s business.
"What is a copy constructor and when is it used, especially in comparison to the equal operator?"
I do not have the standard at hand, but I would guess it has an equality operator and an assignment operator, or maybe even just 'assignment'.
"What is a Vector?"
What is that capital 'V' doing there? Should I assume a "using namespace std" and an "#include <vector>"?
"Why should you never throw an exception in a destructor?"
There is nothing wrong with throwing an exception in a destructor (well, it is a bit weird). Throwing one from a destructor is the no-no.
"What is the proper way to perform a cast in C++?"
Another trick question or badly phrased. What are the ways to cast values in C++? When are they appropriate?" or something like it would be better.
"What is a vtable?"
My answer was that it was the way in which a C++ compiler makes it possible to do polymorphism (calling base member methods through pointers to derived classes; virtual functions). The interviewer didn't agree with me and said that vtables have nothing to do with polymorphism and moved on to another question (about :: scoping). I didn't start to argue with him, and I got the job.
Btw I assume you meant "calling derived member methods through pointers to base classes" instead.
I do have a certain amount of nostalgia for the days when all programming was pretty much "close to the machine". Now we spend our time gluing frameworks and libraries together to create apps.
The actual C++, while, indeed more complex than Java, is nowhere close to the rumored complexity. Say, compared to Common Lisp with 40+ special forms and things like "loop" and CLOS, it's just too easy (not that I mean CL is "unlearnable" it's just more complex than C++). Somebody with a STEM degree could learn C++ better than many self-proclaimed "C++ masters" if just read a book and then looked over the standard. But very few people do that, the myth is just too strong.
It's sad because nowadays it gets to the ridiculous point when people will imagine something about the language rules (something very far from the reality) and will refuse to write few lines of code to see the stuff just does not work how they imagined.
The only thing worse than ignorance is false knowledge.
Just by having templates and classes doesn't make it higher level. It just means it has more feature parity. More higher level is when you can say "aspect X of the execution environment is barred from the language for the sake of abstraction, such as Java's garbage collection or Python's list comprehensions or dynamic types." You can't chose an alternative, so the level is raised on those issues since the language deals with them for you.
Kinda falls apart in some cases. For example the standard says with respect to inline functions that:
An inline function with external linkage shall have the same address in all translation units.
So I guess for the purpose of not having to worry about comparing the values of a function pointer to an inline function or worry about assignment semantics? Actually I have never really understood the point of this part of the spec.
Anyway, the cost of this is not negligible, since the linker has to maintain state for those cases where inline replacement is not an option[0]. As a result, even if you don't use this feature of the language, you pay for it with increased link time and object file sizes. But this is a pretty arcane corner case to pick on.
It feels you are trying to find a language that will fit all problems. What happened to using the right tool for the job? C++ is one of the best language choice for a large amount of problems.
Nowadays I won't change the power and extra safety given to me by C++ with C, unless requested by customers, which no one was made since 2001 in my case.
"Eke out every bit of performance"
If there was one language to rule them all, then that's what we'd all be using.
That's very charitable to programmers. I don't think it's fair to assume that most--or even many--people choose their language on entirely rational grounds or the quality of each language.
If you just followed popularity, you'd probably end up using Java, and nobody wants to go there.
C + any scripting/dynamic/embedded language is probably a better choice for future development than C++.
I friend of mine published long time ago in Gamasutra (or was it Gamedev) a material on.... ahem scripting with C++ - I've talked to him that this is utter non-sense - scripting is possible in C++, but with thnings like UnderC++, Ch (only C), Cern's CINT, etc. His material was on implementing a script-like system using C++ directly.
Then comes boost (he's a big fan of it) - Just a month ago we decided not to use thrift, but google protobuf simply because it wanted boost. We didn't want to litter our perforce with tons of files, much bigger increased linking times, and harder setup. Unfortunately lots of graphics/game /animation oriented houses/studios use it, so there must be something to it. For me plain old STL is good, but the best so far has been write C or C++, but do all your interface in C, only exception being certain hard to make nowadays interfaces like GUI for example (GTK is example where this is gone wrong too, but with C - the API is just too big, and lots of macroses).
Python
Java
C
Fortran
platform languages: the web browser† = Javascript††
apple = Objective C
microsoft = C#
google = Go
unix = C
† the web browser is most importantly platform agnostic†† Javascript and Java are two different languages. Java is more like C.
Java was once the platform language of now defunct sun.
I consider the language of the linux kernel to be C and i386 assembler. Linux itself is too much of a bazaar to have a "platform" language.
and a table:
lambda calculus | machine memory |
----------------+----------------+--------------------
Haskell | C | language as given
----------------+----------------+--------------------
Common Lisp | Forth | language as medium
and others: Python vs. Ruby
Assembler
HTML
CSS
SQL
PHP
Perl
Prolog
Basic
Erlang
and yet another...But it'll always be useful in the stack, because like the quote goes its much harder to shoot yourself in the foot than C is, but with much bigger risks. It's easy to mitigate those risks and write clean code, but it basically comes down to only using some subset of the features, C++ sucks the most where it's in template hell.
It's easy to read all the bad about C++ and avoid it, but its something that's reasonably easy to pick up and try, and there's a lot of learnable experiences you can take with you.
And if your software is slow, blame it on a slow computer, these days there are fast computers much more faster then the old days when speed and short code where seen as an art. The slow computer is a customer cost upgrade, while taking extra weeks of coding is a softwarehouse cost upgrade.
C++ plus scripting is the best way to go, IMO; you get object-oriented abstractions, better type safety at compile time, and yet you still get speed. Destructors alone make it worth using C++ over C, so you can ensure stack structures clean up on return from a function and can avoid using a "goto exit" model.
And if you need every last percent of speed, you can write that code in a "C" subset of C++. C is still completely there under the covers. Except you have to do more casting.
C is really not much better than a portable assembly language. And I should know, having written commercial games entirely in assembly language.
Sometimes the VM gets in the way, sometimes the library, or bit of hardware you need to use, only has a C or C++ interface library.
Learning C++ is still important, because, developers who don't understand how C++ works have little chance of knowing how to find an entry in a COM export table.
C++ isn't coming back, it never really went away.
My style there was somewhere between civil and uncivil. This never harmed my karma. I was blunt and/or pointed in my mockery of reasonably smart people tossing off their pet clichés with their brain on dial-tone. I tried to toe the line on sharp yet not vindictive. Usually my posts digressed with a vengeance from an initial sharp retort to something original or constructive. Writing has always been a thing for me that releases frustration when technologies are _unnecessarily_ bloody-minded. I wasn't using /. to establish rapport. But recently the story summaries are achieving new heights of vagueness. I'm like the old dog who finally caught his tail, and noticed the smell.
I clearly recall when Paul Graham became a bit of a meme at /. circa 2004. I still remember the desk I was sitting at when I first read Paul Graham's comments on LISP. So here we go, wading into the C++ bash-fest for old times' sake. (Is it permissible to compose in full paragraphs around here? I guess I'll soon find out. The Y/Z/omega generation's allergy toward paragraphs made reddit a total non-starter.)
I've definitely let my C++ skills languish for the past few years. It's an awfully demanding language if it's not your bread and butter.
One way to characterize C++ is that it's an elegance inversion. Most languages are founded on the assumption that beauty is transitive. If you start with beauty at the bottom and stay true to your aesthetic all the way up, the beauty will bloom as a mature rose. The C++ design aesthetic is that the language designer should not be refactoring his language user's problem domain in order to shoehorn simplicity (and elegance and glory) into his solution domain. There were no end of frameworks back in the 1970s and early 1980s that promised vast productivity increases, and delivered these for the most part, until the dread day came "oh oh, we have a new requirement and this tool we've chosen just won't go there, and backing out now is too painful to even contemplate". (Think Rails, back when every country was laying down a different rail gauge.)
I find it amusing to read the experience of people deploying MongoDB. The thing is, regret has a different price than it used to. A few startups report rapid development on MongoDB for an initial year, then jumping to a different approach when some of Mongo's design eccentricities became problematic. Jumping is a lot less hard than it used to be. This might even have been a good overall development path. Few said that about a major misdirection in the 1980s.
The comment over at the TFA that caused me to sign up and post was a guy saying that every piece should occupy a limited depth of the abstraction stack. He took offense that the language should have high level abstractions and still be able to specify execution details at almost the machine level.
This was actually an almost explicit language design goal. This sentiment is reminiscent of the old "Worse is Better" debate. (Do I have HTML here? No info from the UI. Activate telepathy module: throw ("does not compute"). catch ("induction from sparse"): I guess I'll just post the author's name of the piece I'm referencing: Richard Gabriel.)
C++ doesn't believe that great programs are written on the principle of "no ugly". Ugly happens. This is a property of reality, is it not? Or am I way too old for my own good? The premise in C++ is that low level library implementers have the gory power (pages of closely debated language specification) to conceal some (or even most) of the ugliness they face. Library implementers working at the next level up similarly have the gory power to conceal some of the ugliness they inherit, and also some of the ugliness their own layer introduces. This continues until the final consumer ends up working at a fairly high (and reasonably clean) level of abstraction. The ugliness propagates, but doesn't explode. Incompetence explodes, however, so there is that.
Of course most casual users of C++ don't appreciate the substrata. They get buried in the arcane and baroque syntax required to make this magic work. (C++11 tries to redress this.) This is a whole different tranche of ugliness that stems from the original decision to keep the C language as a proper subset (plus a few design missteps along the way that are deeply regretted, but hard to reverse). Usually on the short list of toxic inheritance from C is the clever declaration syntax. This didn't generalize to OO without introducing some ugly ambiguities. Much baroqueness of the language still stems from this. It's an old language with history, much like Perl. Every new language arrives with a fresh face. A few get used enough to accumulate wrinkles. And we've even learned a few things over the years at how to avoid the worst wrinkles of all. It's nasty, but not ultimately toxic in its own right.
Not so often admitted by these fresh-faced languages is the relief and freedom that accrues to not having to profess to solve every possible problem. Why? Because either C or C++ can be hauled out with a fair certainty that there's no ugliness so great it can't be captured and expressed well enough.
My own opinion is that C++ has faded into its sunset years by finally buckling under its own weight. The baroqueness of the syntax is a finite burden, much like decoding the x86 instruction set as compared to RISC (the amount of circuitry needed to accomplish fit quite easily into a 386, yet we still complain about this overwhelming burden 15 die shrinks later). Nevertheless, it all adds up. I don't think the ROI of learning C++ in a deep way makes sense for younger developers. It's a complex world. There's too many other demands for that cognitive space.
That said, I know that if I run into a problem where turning my back on ugly is not a viable option, C++ is still there for me, with a proven ecology of ugliness containment. In C++, one can always push ugliness from the problem domain back into the solution space, at the expense of some source code eye bleed--supposing your developers are well enough versed to distinguish incompetent solutions elegantly expressed from competent solutions with an ugly expression. This is why I described C++ as an elegance inversion.
There are many languages more beautiful where that isn't true. Think of yourself as a plumber. There's a dirtiness to your world that's simply inescapable. This doesn't stop plumbers from implementing vacuum reflux hoses for optimal sewage containment. Then along comes Fritz Haber who declares sewage obsolete. Be thankful another language built those reflux hoses so your language doesn't have to.
[Shit, no preview! Edit boxes are pathetic for tweaking paragraph flow. Who ever looks at their prose any more as others will see it? WTF. Fire and forget. My first lesson here in the new culture.]
There's so many analogies that one could use that I dare not attempt one. Like if C is like metallurgy, the C++ is like alchemy. I should stop before it appears foolish.
I've moved from C and C++ in big systems feeding financial instruments at hundreds of thousands of items a second through rooms full of computers to PHP and Go and back to C for embedded, where I spend all my time at the moment. So I fit into one of this articles categories. I had a dirty little problem with multiple devices sharing a single bus, with all its chip select and clocking issues, and mutual exclusion with near zero wait states was the problem to be solved. C++ to the rescue. Not because it couldn't be done in C ( or assembler for that matter, an even more magic approach ), but because inheriting the bus made architectural sense.
It isn't hard to read, document or maintain, because the code structure maps well to the underlying fixed hardware. In this case, the language suits. And it all has to happen in less than 32K with all the rest of the code.
There's always a lot of discussion about this language versus that. Generally, I'll use whatever suits, and Javascript and PHP required no learning at all, and I already knew Java to a degree. They are C'ish enough to pick up without effort if one already knows C. Objective-C and Go and Java where the shoe fits, and from what others are saying, Rust is one I need to know.
Independently of Microsofts policy in Windows 8 with IDL and .NET changes, or tossing the idea around as to whether C or C++ should go in the Objective-C mix with XCode and Apple, the thing I can use C++ for is making the best solution possible for fundamental problems with machines, where implementing a concept over a base or virtual machine facility is efficient. In those cases, the argument against efficiency fails.
But it's really a specialisation given the volume of solutions that are needed in the current state of userland software. Horses for courses. There's a lot more volume now, and managed languages are a better fit in that environment. This is the house that Jack built. You don't need a hammer and nails. You want a paint brush.
People still like Java Minecraft better than thousands of its C++ clones.
I don't get it, isn't that win-win is many situations. I'd rather have a solid developer who can master C++ or at least understand the concepts when explained to him/her, than someone who can't. Basides dealing with compiling/linking (but scons greatly simplifies this), I really don't feel like it limits me much compared to other languages like Python once you know a bit of STL.
Now the real part : Is haskell difficult or is it strange?
So for most of your code--the parts that aren't tight and performance critical--it's good enough as is and you can just stick to writing normal, concise and (at least in my experience) very readable Haskell.
However, there are always going to be the sections of code that you absolutely must optimize. And this is certainly not trivial. However, even this isn't too bad, for two reasons.
The first is that much of the difficultly comes with a lack of familiarity: you may know how to optimize C++ or C well, but that knowledge is not going to apply too much. Haskell is very strange, but some people clearly manage to make it perform well consistently, so it's probably a matter of experience. A new C++ programmer will find writing heavily optimized C++ code difficult as well.
The other reason it isn't as bad as it could be is that it's possible at all. You simply can't write very performant Python, so you essentially have to drop down to C. In Haskell, this is also always an option; however, even the hard-to-optimize Haskell is still usually friendlier and easier to work with than C!
In some cases, by using the right libraries and rewrite rules, you can actually maintain most of Haskell's elegance (like being able to express your program as composed maps and folds) while still getting good performance.
I find Haskell's syntax very elegant and concise, but I am scared about performances. Often, I read about three or four different ways to do one thing. If I were to pick Haskell as my go-to language, and let's say I wanted to build a performant (memory wise and speed wise) program, would I have a hard time?
Now obviously, for day to day applications, the performance topic is irrelevant, but how would Haskell compare for the example above instead of, let's say, Ocaml?
That said, as I noted, the performance is usually good enough even with naively written code; you would only have to spend time optimizing a few select parts of most programs.
Another little problem is that there are not many resources on how to optimize Haskell code. This is a little annoying if you're learning on your own; however, I think it's offset by the Haskell community. I've seen some of the best Haskell programmers give very detailed responses on StackOverflow and the mailing list, so there is always somebody to help you while you're learning.
There are also some advantages to OCaml--it's a very fast language itself and it behaves in a way that's easier to predict especially since you can leverage more of your existing experience. OCaml is also a very nice languages; while I prefer Haskell, I would be perfectly happy with OCaml (and, in fact, I've only used OCaml and not Haskell in production).
I should add a big caveat to this whole post: while I've used both Haskell and OCaml a fair bit, I've avoided doing anything super performance sensitive. I usually care more about having correct, readable code quickly than I do about how fast it runs. So I am definitely no expert on optimizing either Haskell or OCaml!
One could argue that many developers know better than taking the productivity hit of C++.
Disclaimer: I do C++ as my day job, and my MS thesis was in metaprogramming. I still think C++ usually doesn't apply, even though in some important cases, it very much does.
If that's the case, I wish Microsoft would bite the bullet and come up with a new native language. Microsoft programmers are for the most part happy C#/.NET and trying to pull them back to C++ is a losing proposition.
Languages are not native or managed, implementations are.
The way .NET is currently deployed on Windows and whatever else might be happening, is a result of internal politcs at Microsoft.
If they wish to do so, they could go fully native with lets say .NET 5.