Thursday, 11 December 2008

Do we need destructors?

This post is for my honoured, old-time, old-skool hacker colleague Stefan Z. As we were discussing the new and (then) hot Java language, we couldn't accept that it didn't have destructors. I cite Stefan:

The constructor/destructor pair is an incredibly powerful concept!
Well, you can't have everything: either we support garbage collection or destructors, isn't it? But it just one more point where Java sucks: the ugly try/finally block and then the explicit close() call like in the following code:

    BufferedReader reader =
new BufferedReader(new FileReader(aFileName));

try {
String line = null;
while ( (line = reader.readLine()) != null ) {
// process the line...
}
}
finally {
reader.close();
}
Ugly? You bet! And what I really don't like is that you cannot hide all the required handling in a library! In C++ you'd just write:

    ifstream f(aFileName);
string line;

while(f)
{
getline(f, line);
// process the line...
}
That's all, the plumbing is hidden in the destructor* and it is there automatically! It's the reason why Stefan called this concept an "incredibly powerful" one. But that powerful concept can cause problems in a multithreading and garbage-collected environment. As a matter of fact, a recent C++ standard proposal for the multithreading execution model opted for removing destructors from the language (!!!), or at least for not executing the static destructors in a multithreading setting! Of course, it's a shortcut in order to solve a rather complicated problem, but you get the idea, right?

So maybe the destructors are a little bit outdated, what do you think Stefan? All the more was I pleased as I recently stumbled on a Smalltalk pattern called "Execute Around Method" pattern** (to be true, I don't do any Smalltalk and have seen it in some Groovy example code). It's another possiblity to hide the plumbing in the library: you just define a static method doing all the dirty work and accepting your "payload" code - just like in an IP packet: we have the framing and the payload, and the user is only delivering the payload! Well, an example explains it best:
    def static use(closure)
{
def r = new Resource()
try
{
r.open()
closure(r)
}
finally
{
r.close()
}
}
The closure parameter stands for our "payload" code. This code is the hidden in the library. An application of this is the following Groovy code:

    new FileReader(aFileName).withReader
{ reader ->
reader.readLine(line)
// process the line...
}
// no need to close()!!!
We create a new reader, give it to the static withReader() library method, and provide a "code block" (as you'd call it in Perl) for execution. This code block (called closure in Groovy) gets as the parameter the ressource which will be closed at the end, just like the use() method shown above!

A destructor for the modern times! So the "incredibly powerful" idea can be saved?

---
* this is called a RAII-pattern in C++, see: http://www.hackcraft.net/raii/
** Kent Beck: "Smalltalk Best Practice Patterns", Prentice Hall, Englewood Cliffs, NJ, 1996.

Wednesday, 26 November 2008

C vs C++ and some celebrity gossiping

Every time I read a post of Linus "Linux" Torvalds I can't help thinking "what a smug, assumptuous, xxx-yyy-zzz!". Well, I don't know the man personally, but I certainly wouldn't like to have him as my boss in any project, betcha! The first quote is a couple of years old (I cite from memory as I cannot find it anymore) and was a reply to some proposal Linus didn't like :

....go and play in your little world...
It looks innoculous enough here and now, but in the context it was realy ugly. And now, for some time everyone seems to feel obliged to speak about Linus' C++-hating post*, so I had a look at it myself. OK, nothing changed, it goes in the same vein:

*YOU* are full of bullshit. ...... is likely a programmer that I really *would* prefer to piss off, so that he doesn't come and screw up any project I'm involved with. ...... the end result is a horrible and unmaintainable mess. But I'm sure you'd like it more than git.
... etc, etc, etc. OK, maybe it's only his personal creative writing coach who's to be blamed, or perhaps it's the macho Linux kernel developer culture? But, aside of personal dislike, what the man says got a bell ringing with me. Why? Read on:

C++ leads to really really bad design choices. You invariably start using the "nice" library features of the language like STL and Boost and other total and utter crap, that may "help" you program, but causes:
  • infinite amounts of pain when they don't work (and anybody who tells me that STL and especially Boost are stable and portable is just so full of BS that it's not even funny)
  • inefficient abstracted programming models where two years down the road you notice that some abstraction wasn't very efficient, but now all your code depends on all the nice object models around it, and you cannot fix it without rewriting your app.
In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C.
Whoa, that man is really hardcore! What he's actually saying is: don't trust any code you didn't write by yourself! And on a higher level: any abstraction we are using is a trap, lulling us in a false sense of security. And more: we can really build big, fast, complex systems without using OO abstractions!

Didn't I feel the same before? That for the efficient, near system level code we can take C, and that all the fancy object thing, where the is better done in Ruby or (even) Java? So no place for C++ here? Take Wireshark protocol analyzer as example?

Gossiping

Well, the story doesn't end here. First, there are some entertaining comments on digg**. My favourites are:

  • Linus codes a kernel for a living, so its not that surprising that he hates C++.
  • Linus is an *****, he lives here in Beaverton and the man has a big ego for someone nobody outside of the Linux community cares about.
  • Ok... Who cares if Linus Torvalds hates C++. I don't really give a damn.
  • another episode of "I am Linus and hate everything"

  • funny that linus prefers kde when it is programmed in C++
  • Personally I've evolved thinking in OO abstractions, so working with C++ is much more natural for me than C. Does that mean I'm a crappy programmer? Only Linux Torvals knows

  • The STL is the biggest piece of crap I've seen in 40 years of programming. It's a graduate students project to prove one can write a totally orthogonal, yet totally inefficient, impossible to maintain, piece of crud.
Well, as it seems, first: people aren't taking Linus such seriously, and second: STL ist the culprit!

Living in the past?

So, as to begin with something, what's the matter with STL? As we are gossiping in this installment, it's perfectly fine for me to say that the prevalent opinion on the Web (for example ***) is that Linus is referring to a problem from the past (around 2001 or so), when he's speaking abot the non-portability of C++. At that time the support for the C++ standard, and especially tempaltes, was very unconsistet across the compilers, and so the STL implementations could be nonportable between compilers! But nowadays even Visual C++ is quite up to speed here!

Then the inefficiency allegation. I don't even want to discuss it here, because it's so old (back in time to 1998 or so). There's long refutation along classical lines from that time to be found****, if only not very entertaining, and a shorter one*****, from a practitioner's point of view - Steven Dewhurst actually wrote low level code with C++ and templates:

Just to annoy people like Linus, I've also used typelist meta-algorithms to generate exception handlers with identical efficiency to hand-coded C. In a number of recent talks given at the Embedded Systems conferences, I've shown that commonly-criticized C++ language features can significantly outperform the C analogs.

Who's incompetent?

Next comes the critique that C++ tends to attract substandard programmers, and that:

... limiting your project to C means that people don't screw that up, and also means that you get a lot of programmers that do actually understand low-level issues and don't screw things up with any idiotic "object model" crap.
The first thought that comes to mind is Linus' "software Darwinism": in 2000 he lambasted people wanting a debugger in the Linux kernel. His argument was: I don't need any sissy that needs a debugger! I want people who understand the code as a whole! Any higher level abstraction or language (i.e. STL or C++) will make you a wimp and not careful enough!
The fact is, that is *exactly* the kinds of things that C excels at. Not just as a language, but as a required *mentality*. One of the great strengths of C is that it doesn't make you think of your program as anything high-level...
But isn't this just another management whip for the programmers to keep them under pressure, so they are more obedient? A manager's trick? The Linus' software management process? I'm most hardcore of you all, so I'm the overlord ;-). In that light Linus' diatribes are only politics: he's defending the status quo.

There's also a diffrent response to the "substandard programmers" reproach I must mention here. Steven Dewhurst broght in the point, that for a C programmer C++ is so complex because there are alien idioms, methodologies, tricks, and so on*****. You would be tempted to say it's to difficult for the average C coder, but there's something else! C++ isn't just C, it only happens to be backwards compatible! When you switch from C to Common Lisp you won't be an expert instantly, but the C folks assume they can just come and start programming C++. And then they cry that it's too difficult and complex.

Summary

This time there's no summary. I was just gossiping...

---
* Linus original post (admittedly taken out of context!): http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918, but I must admit, when he's speaking, he does make a much better impression!
** Digg gossiping: http://digg.com/linux_unix/Linus_Torvalds_hates_C
*** Hacker News discussion: http://news.ycombinator.com/item?id=51451
**** A typical reply: http://warp.povusers.org/OpenLetters/ResponseToTorvalds.html
***** Steven Dewhurst's reply: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=411


Wednesday, 19 November 2008

A letter from DLL hell: msvc60.dll and msvcr80.dll

This is only a short technical note - for those who (like me) first check the Internet for solution to weird programming questions!

The Problem:

Locally everything worked fine: I could install my old (VC++ 6.0) Windows application and start it without a hitch. But at client's site (1000s of miles away) Windows refused to start as it couldn't find the msvcr80.dll library.

What the heck, I link against msvc60.dll but Windows complains about msvcr80.dll which I don't use, don't link, and don't need??? I that black magic? Help!!! That was the problem I was fighting for the best part of one of last weeks. Welcome in the manifest/DLL hell. Well, I tried first to reproduce this locally: it didn't work (i.e. it did work ;-))) on my develpoment Widows XP machine, as well as a freshly installed Windows Server 2003 Std. Edition (SP2), a running Windows Server 2003 Web Edition (SP1), and it always worked! No probs at all when starting the app!

At the client there was the Windows Server 2003 Web Edition (SP2), with "nothing installed" (as asserted by my colleague at the client' s site) except for our product and Oracle! What's going on? There are no dependencies to msvcr80.dll in my code (I checked with the Dependency Walker) and the installation worked for years before I made that last bugfix!

In the last attempt to reproduce the error I found a running installation of Windows Server 2003 Web Edition (SP2) at my client's company local site and could at last see it with my own eyes: "Cannot start application, msvcr80.dll not found".

The Solution:

It's elementary: if there's no static dependency, ther must be a dynamic one! The Process Explorer has shown, that the process has really tried to load the msvcr80.dll! How? Through the Qt plugin mechanism:

"Qt applications automatically know which plugins are available, because plugins are stored in the standard plugin subdirectories. Because of this applications don't require any code to find and load plugins, since Qt handles them automatically.

The default directory for plugins is QTDIR/plugins*, with each type of plugin in a subdirectory for that type, e.g. styles..."

Although I used the Qt version 3, this generic mechanism pulled in all the plugins found, which were OK, except for the styles plugin qtdotnet2.dll. Because of course "nothing else installed" wasn't true: the Base package of my client was there, and it had various plugins installed, including the culprit: qtdotnet2.dll, which was written for Qt version 4 and pulled in the Visual C++ 2005 runtime support!

---

Saturday, 25 October 2008

Erlang and Map-Reduce

I was a fan of Google's Map-Reduce for a quite long time, as I was first doing my PhD research in distributed systems and then was working in some high-availability projects, so such interest emerged somehow naturally.

Their (i.e. Google's) achievements quite impressed me: first the whole infrastructure (lot of C++ coding - they simple wrote their own filesystem and database!!!), but equally the level of abstraction used when working with distributed data. I wrote about the superiority of that model over the SOA model before, although the SOA model is probably the best you can achieve in a heterogenous environment (and I was probably wrong there...).

So every time I see a map-reduce implementation I can't help reading about it: Hadoop is the most known open source implementation, but there's the QtConcurrent::mappedReduced algorithm in the new Qt 4.5* as well. You see, the idea seems to be catching on.

Now to the news: there is a Map-Reduce implementation in Erlang (!!!)** which runs Python scripts (!!!) and it's called Disco***! And if you don't have a massive parallel cluster at home, you can run it in the Amazon's Elastic Computing Cloud! I don't like Nokia very much, but I must admit that this one is rather cool: you simply write scripts to manipulate your data, much in the vein of UNIX shell programming, only infinitely scalable! And we know that scripting languages are much better for data manipulations than Java or C++. According to its homepage, Disco is quite a success too:

This far Disco has been succesfully used, for instance, in parsing and reformatting data, data clustering, probabilistic modelling, data mining, full-text indexing, and log analysis with hundreds of gigabytes of real-world data. ***
Wow! I like te idea of Erlang and Python working unisono!

---
* Qt 4.5 docs: http://doc.trolltech.com/main-snapshot/threads.html#qtconcurrent
** a small itroduction to Erlang: http://ib-krajewski.blogspot.com/2007/08/erlangs-change-of-fortunes.html
*** Disco's homepage: http://discoproject.org/

Tuesday, 7 October 2008

C++ servlets - again

It looks like it's getting to be a new hobby of mine: collecting C++ web application frameworks. After the first one* (a simple HTTP server and session classes) and the modern one (Wt aka witty)**, now the "missing link" was found: the classic Java-like Servlet container implementation in C++! This was made possible by a friendly fellow blogger Eduardo Zea.

Eduado was kind enough to give me a link to the DDJ article describing such an implementation by Rogue Wave named Bobcat***. It's quite old (by SW-industry standards) and the link to evaluation downloads doesn't work anymore, so I think, it didn't quite catch on. But it's another one in my collection! So the actual counters are C++=3, Java=googol.

PS: To be more precise, Bobcat functionality is now part of the Hydra Express****, a Rogue Wave's SOA publishing framework. So are we all going SOAP?

---
* see: http://ib-krajewski.blogspot.com/2007/09/servlets-in-c.html
** The Wt-framework: http://www.webtoolkit.eu/wt/
*** John Hinke, Implementing C++ Servlet Containers, April 01, 2002: http://www.ddj.com/184405023
**** http://www.roguewave.com/blog/so-what-is-it-with-rogue-wave-and-xml-soa/

Monday, 29 September 2008

Beautiful code

What is beatiful code? The shortest answer (which I've read somewhere but can't remember where) is:

we all know what "ugly code" is: code that someone else wrote...
But beautiful code? Isn't it in the eye of the beholder? Well, for me, beautiful equals readable. You have to see on the first sight what the overall idea of the piece of code is. On the other side, the idea itself might be crap (!!!) but then we should ask the next question: what is a beautiful design/architecture?

I, for my side, am thus a proponent of writing aesthetically appealing code. And I'm not alone! Read this:

Whether it is a natural occurrence, a quirk of human languages, or conditioning, most people find while (x==3) significantly simpler to read than while (3==x). Although neither is going to cause confusion, the latter tends to slow people down or interrupt their train of thought. In this book, we have favored readability over safety—but our situation is somewhat different than that of normal development. You will have to decide for yourself which convention suits you and your team better. *
Here we've got it: the eternal problem with the coding guidelines forcing me to write a plug-ugly (3==x)! The question is: should we write ugly code as to be on the safe side? I admit, that I never wrote such an ignominious line of code in my life. You expect trouble? Nope! I've never had any problems at this point! Well, one single time I mistyped it, but found it out in an instant! In C++ you have to develop certain sensitivity for that construct, that's all.

As for practical examples (instead of dull theoreticizing) - some time ago I asked myself: what is the most cool/beatiful piece of code you eve wrote, what would you show to others in order to impress them or to show them how crystal-clear ;-) your style is? As it was even before my lambda library, and only had plain production code on my disposal, I settled on the following piece:
/*------------------------------------------------------------------------*/ /**
* @brief configDelta
* @descr
* This function compares two configurations and returns the differences.
*
* @param[in] other - the other configuration
* @param[in] scope - what delta requested: all the new entries, all the deleted
* entries, or all changes altogether?
* @param[out] delta - the calculated diffrence
*
* @note Assumption: both configurations must be sorted!!!
*///--------------------------------------------------------------------------->

void SimpleCfgFile::configDelta(const SimpleCfgFile& other, CfgDelta scope,
vector<string*>& delta) const
{
TRACE_FUNC("SimpleCfgFile::configDelta");
delta.clear();

switch(scope)
{
case addedDelta:
TRACE_DEBUG("addedDelta");
// all in this but not in other:
set_difference(begin(), end(),
other.begin(), other.end(),
inserter(delta, delta.begin()),
less_then_deref<string*>());
break;

case removedDelta:
TRACE_DEBUG("removedDelta");
// all in other but not in this:
set_difference(other.begin(), other.end(),
begin(), end(),
inserter(delta, delta.begin()),
less_then_deref<string*>());
break;

case completeDelta:
TRACE_DEBUG("completeDelta");
// all in this but not in other + in other and not this:
set_symmetric_difference(begin(), end(),
other.begin(), other.end(),
inserter(delta, delta.begin()),
less_then_deref<string*>());
break;

default:
TRACE_ERR("Unknown scope requested for configuration delta!!!");
}

TRACE_VALUE(delta.size());
}
You see, it's not a rocket science. What I liked in this piece of code was it's conciseness, readibility and (though it's of no real importance for workings of the code) its symmetry. And moreover, I was amazed how a judicious usage of the standard library simplified the task which at first seemed to be rather a daunting one!

An lastly, it's an illustration for the fact that you don't have to use a lambda library to obtain a clear code: I just wrote the following trivial functor:
  template <class T> struct less_then_deref : binary_function<T,T,bool>
{
// OPEN TODO ---> constraint: isPtrType(T)...
bool operator() (const T& x, const T& y) const { return *x < *y; }
}
instead of the lambda expression (*$1 < *$2) and it is still readable. Or even more readable by using a telling name?

---
* taken from the following book: Groovy in Action, Dierk König et al., Manning 2007, page 157-158

Wednesday, 17 September 2008

Google's technology stack

Well, I said I wouldn't write any knee-jerk reaction posts on this blog, only well thoght-through, throughly researched, and insightful entries. Certainly, I have some entries I should be rather working on, like mutithreading testing or lock-free synchronization... But I must admit, that was a bit over-optimistic, as you'll see in a second...

Recently, I stumbled across this one:
Google has recently launched the Google App Engine. From an Java enterprise developers point of view it is shamelessly easy to use, deploy, etc. Well, unfortunately it only takes Python apps for now, but it is stated that there will be more languages supported in the future. But it’s Google again putting its finger into the Java EE wound (first GWT with webapps, then Android shaking the Java ME world, and now App Engine showing how runtimes should look like).*
I blogged before about the "Google phone", which came out not as a phone, but as an SDK (BTW: do you want to make your 1st milion? Take part in the Android Developer Challenge, no kidding!). The local german "Java Magazin" published on this ocasion (i.e Android's release) an editorial, accusing Google of attacking Sun, Java, splitting the Javaland and whatever. What the fuss?

I cite Wkipedia**:
Dalvik is often referred to as a Java Virtual Machine, but this is not strictly accurate, as the bytecode on which it operates is not Java bytecode. Instead, a tool named dx, included in the Android SDK, transforms the Java Class files of Java classes compiled by a regular Java compiler into another class file format (the .dex format).
So you are writng Java code, but it's not running on the JVM! Is that forbidden?
"...some have related Dalvik to Microsoft's JVM and the lawsuit that Sun filed against Microsoft, wondering if a similar thing might happen with Google, while others have pointed out that Google is not claiming that Dalvik is a Java implementation, whereas Microsoft was."***
I don't know. But I think it shouldn't be!

Now for the Google App Engine. As I had a look at it some time ago, it didn't ring a bell with me. I rather though about it as of another grid computing offering, like Amazon's Elastic Cloud: just write your app locally and ther throw it on the grid and it will scale automatically with your needs. But when a Java person sees this, it sees Java technology attacked. The same for GWT: it is JSF as it should always has been. But come on, you are still writing your programms in Java, the difference is that the ideas don't come from Sun! I'd rather say Google is giving a second life to Java by providing new ways for using it. I wouldn't have though that 5 years ago, when they were essentially a C++/Pythonn shop!

Additionally, I can't help feeling that the Java poeople are thinking in an "imperialistic" way: boasting about their superiority, but on the other side always suspicious that someone may have try to challenge their (self proclaimed) supremacy. Like the late USSR...

But on the other side, when you look at Google, you could be tempted to think, that they are writing everything new: newly they published an own C++ test framework**** and an own (C++) transfer data encoding****, just as example. So maybe it's not an assault on Java iteself, but just a manifestation of the "Not Invented Here" syndrome? Now, the employees must do something in their 20% project-free time, so they programm every conceivable thing anew (and better?).

---
* http://adminsight.de/2008/05/05/springsource-announces-an-application-plattform/
** http://en.wikipedia.org/wiki/Dalvik_virtual_machine
*** http://www.infoq.com/news/2007/11/dalvik
**** Google test framework: http://code.google.com/p/googletest/wiki/GoogleTestPrimer, Google transfer encoding: http://code.google.com/apis/protocolbuffers/docs/overview.html, and now they even wrote their own browser: Google Chrome (ok, you knew that already...)