An experiment with C++11
Bjarne Stroustrup writes: C++11 feels like a new language: The pieces just fit together better than they used to and I find a higher-level style of programming more natural than before and as efficient as ever.
I haven't written much C++ in the past three or four years, so this summer, recovering from an illness, I decided to try an educational hack.
I chose to reimplement a perl blogging engine in C++11, since I wanted something small, complete, useful and above all not C-like, and since I had a candidate: Loathsxome, a cleaned-up reimplementation of blosxom. Both are a few hundred lines, vaguely high-level, hackish in the way small programs can (legitimately) be, and they do a lot of string handling. The loathsxome installation that (still?) runs this blog is about 1100 lines of code including my plugins but excluding templates.
My goal was to write clean code, use some/many C++11 features and generally modern style, and get a comparable line count in C++ for the same features. I didn't aim for performance, but thought the result should perform well because I know big-O notation and the C++ committee has an efficiency fetish.
Code size: The line count is twice as high. I've about 2000 lines of C++ to do the job of 1000 perl lines.
I find the C++ more maintainable, but that may be because the C++ is better documented. It's actually 3000 lines including whitespace and comments, as opposed to 1100 for the perl.
C++ features: I've seen C++11 examples that made me wonder whether I was looking at real C++ or an elaborate prank. But after this experiment I quite like the new features.
The move operator and auto are great. Auto can be misused, there's no doubt about that, but it handles a common case well. (Often good, great potential for misuse — welcome to C++!)
C++ still provides only weak abstractions. The internals of everything are plainly visible, for good and bad. The internals of some things are astonishingly complex.
It's nice to have several compilers, with different diagnostics. Clang is good (so much better than javac).
I really like some of the STL features, but it's still difficult for me to accept the lack of x.contains(key) on the containers. There are workarounds (x.find(key) != x.end(), x[key]), but neither of those really express what I want to do.
The STL and the move operator eliminated delete in this case. I had written a thousand lines before I even noticed that I hadn't needed to delete anything. The only memory leak was related to using a C library.
The code is noticeably short on if/while/try, so I suppose I too find a higher-level style of programming more natural
.
The string handling disappeared. Most of it turned into objects and classes. Loathsxome uses strings for everything, Plusxome starts with a Path and looks up or makes a Rendering, usually based on a Document containing a tree of Nodes and ultimately made from Posts. The STL string may still suck but I've reimplemented a thousand lines of string handling and not felt much pain, so C++11 isn't bad as I thought it would be for such tasks.
I had a look at Boost.Spirit for parsing the postings and templates, but recoiled. Spirit (2.x at least) does too much operator overloading, there's too much magic. It is not for me. I switched to using Tidy to parse posts and templates. However, I don't count that setback against C++11, since one of the Spirit authors is also unhappy with the complexity of v2.x.
Performance: Fine, especially under heavy load. It parses the GET and acquires a shared lock, and under heavy load that's all it does. It also rereads files when inotify() tells it to and eventually regenerates responses, but under heavy load that doesn't even show up on the profiling graphs. (I am not able to benchmark it properly, for lack of fast-enough network and clients.)
The code I wrote is available from my github account. Have a look. Be tolerant. You can tell I was slightly ill, and interested more in trying things than in producing reliable software.
Some notes: I did not implement RSS, because Atom exists and does the same job better. I did not implement any comment plugin, because of my opinions about comment spam, moderation and wham-bam comments. I chose to use HTTP/TCP instead of CGI, because that's the modern way and, yes, because I wanted to play with inotify(). Finally, I used the DOM for templating instead of cloning loathsxome's line-based design. For example, the home page template is an HTML file. Plusxome looks for <div id=foo> and inserts the most recent postings into that node.