Tuesday, 28 July 2009

Two C++ curiosities with a deeper meaning

Lately, I was quite surprised by two things in the realm of programming, both of them C++ related. The first one is the new attribute syntax for C++09*, which I curiously failed to notice in the new standard proposal as I first had a look at it.

1. The first one


What are attributes? No, they aren't class data members with a convenient access syntax in this case (like Groovy's attribute syntax - or was it Python?).

I personally only knew attributes as an ugly Microsoft Windows COM-specific hack, by virtue of which you can inject COM related information into C++ code. Look at this example:

  #define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include <string.h>
#include <comdef.h>
  [module(name="test")];
  [ object, uuid("00000000-0000-0000-0000-000000000001"), library_block ]
__interface IFace
{
[ id(0) ] int int_data;
[ id(5) ] BSTR bstr_data;
};
  [ coclass, uuid("00000000-0000-0000-0000-000000000002") ]
class MyClass : public IFace
{
private:
int m_i;
BSTR m_bstr;
  public:
MyClass();
~MyClass()
    int get_int_data();
void put_int_data(int _i);
BSTR get_bstr_data();
void put_bstr_data(BSTR bstr);
};
Doesn't it send shivers down your spine? You might say I'm not consequent, because I just lashed out on excessive XML configuration files (here), but when presented with the alternative, I don't like it either! And now, there are annotations in Java too, doing a similiar thing... What I can say, I was growing up with the classical paradigm of the standalone programm using external functionality through libraries. But nowadays you don't program just for the machine or the OS, you program for same giant framework! Did you hear the phrase "programming by bulldozer"? And to my mind there's no satisfactory model of how to do this! For me both the configuration file madness and mixing code with meta information are both somehow unsatisfactory. Look at this example JBoss Seam action class:
  @Stateless@Name("manager")
public class ManagerAction implements Manager {
@In @Out private Person person;
@Out private List<Person> fans;
}
Well, what do you think, does it look OK? We have (nearly) POJOs here (i.e. no framework class derivation) which is the Holy Grail in Java programming lately, but the code is littered with annotations. To me they are no better than the old C++ event macros used in some very old Windows frameworks!

Now the question arises: is that a cognitive bias caused by the preceeding simple (and thus elegant) programming model? Remember, even Herb Sutter, when charged with the task of making .NET programming possible with C++, didn't embrace the traditional program + library model! He rather created a language extension, the C++/CLI langauge dialect. Maybe he was constrained to do so by his commision of getting Managed C++ up to speed, but on the other side, in the design paper he argued it's the natural way and compliant with the spirit of C++. Personally I didn't like this language extension a bit, opting for a carefully designed library or framework oriented solution, but maybe it's simply not possible???

Sorry, I digressed. So back to the subject!

The second species of attributes I knew were the Gnu attributes, looking like that:
  void kill(int) __attribute__((__noreturn__)); //GCC specific
but I never used them either, because I thought they were only of any use with som Gnu-specific langauge extensions, which is always avoided like the plague. And do you know how the new standard compliant attributes look like now? Look ("C++09 Working Draft n2798", 10.2008, Chap. 7.6.):
  class C
{
virtual void f [[final]] ();
};

It's a crossbred of Microsoft an Gnu annotations, isn't it? That's why everyone is happy, and why the syntax is really ugly. And do you know what? There are a fistful of annotations defined in the standard (but vendors are allowed to add new ones) and one of them is, you guess it, final! Could someone tell me why should this one be an annotation and not a keyword - is it supposed to be matter in specific environments? Or are we making the way clear for vendor specific language extension? So maybe the whole annotation thing is in there to placate the major vendors: Microsoft and Gnu? Because as I got it (correct me please if I'm wrong!) there isn't a mechanism to plug in an attribute processor as in Microsoft COM-attributes or Java's annotations, so the whole construct is aimed at the compiler writers.

Summing up: first, Java annotation syntax, as seen in the Seam example above, seems to be more pleasing to the eyes, and second, I didn't really grasp the need for standardized annotations, except for vendor's conveniency.

2. The second one

The second curious thing I stumbled upon is the removal of Concepts (or should say of the "Concepts" concept?) from the C++09 standard proposal. As I read**, it was the standard library where the Concepts were first removed from. Come again? As I had a look at the draft, all the std library chapters were strewn with concepts, every one of them in pretty blue (or was is green?) colour.

And wasn't the Concepts supposed to be the best thing since sliced bread? I mean not for me, as I had a look at it one, and didn't want to learn it (in patricular the whole concept_map stuff!!!), but for the compiler writers - they could at last avoid the horrendous error messages for type errors in the template instatiations. Beside of that, it was Bjarne's pet project, and I thought that all Bjarne's PhD and post-doc students were working at it!

And now, out of the blue, the whole feature was cancelled! So maybe there's a limit to the pushing of the type system? C++ is a relentless type-monster already, and sometimes programming it feel like writing a mathematical proof to me. Thus building another level of type definitions on top of the generic meta types is maybe too much of the good thing. But, OK, the idea is not to take out the "duck typing" altogether from the templates, but to strike a delicate balance: add an minimum of concept decalarations and get the best error messages and type security possible. Is that task simply to complicated and too big or is it only the current design of the mechanism which is flawed?

As Bjarne said in the paper which finally did the deathly blow to the Concepts***:

Concepts were meant to make generic programming easier as well as safer. It is part of a whole collection of features aimed at simplifying GP, together with template aliases, auto, decltype, lambdas, etc. However, "concepts" is a complex mechanism and its language-technical complexity seems to be leaking into user code. By "language-technical complexity" I mean complexity arising from the need of compiler/linker technology rather than complexity from the solution to a problem itself (the algorithm).

My particular concern is that in the case of concept maps, in the name of safety we have made templates harder to use. We require programmers to name many entities that would better be left unnamed, cause excess rigidity in code and encourage a mindset in programmers that will lead to either a decrease in generic programming (in favor of less appropriate techniques) or to concepts not being used (where they would be useful). We have overreacted to the problems of structural typing. ***
This means that exaclty what I wasn't willing to learn leaked out into the user space! Bjarne made a series of proposals how to avoid it, but my general feeling after having read the paper was that the concept's design is somehow flawed, and cannot be fixed by some quick workarounds. So it's no wonder that the commitee had to make a tough decision. And that after years of work! And nobody have seen it coming all these years? Don't you think it's unacanny - how little we can do as to design a complicated language feature and to avoid mistakes? Or maybe we see here how badly the standardisation process is working. These problems were there for a much longer time and nobody said a word! Because of lack of time, because of politics, or simply because noone really understood that topic? So it had to be the creato of C++ himself to blow the whistle:

The use of concepts is supposed to help people write and use a wide range of templates. The current definition of concept maps and the philosophy that seems to go with them makes it harder.

Addressing this is important. I suspect that the alternative is widespread disuse of concepts and libraries using concepts. I would consider that a major failure of C++0x. ***

I'd say he killed his pet project out of sense of responsibility.

And where is the promised deeper meaning? As I said previously: there's maybe a limit to the type system. Because for me it felt sometimes like constructing inaccessible cardinals on top if the regular ones (wiki) in the set theory - just very, very subtle. And maybe the horrendous error messages for templates are just the proverbial price of the (type) freedom, and we have better to pay it? When you read Bjarne's article*** you see, that the gratest problems are encountered in sublassing and conversions - so C++ is much more "modern" a language than most of us would like to believe, as it allows us so much of the type freedom using the type system itself to achieve it!

And maybe the design problem relatively simple to solve, but the archaic linker technology we inherited from C is simply too old for that? As it reads:

"... complexity arising from the need of compiler/linker technology rather than complexity from the solution to a problem itself (the algorithm)"***
---
* Danny Kalev "Introducing Attributes", http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=440
** Danny Kalev "The Removal of Concepts From C++0x", http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=441
*** Bjarne Stroustrup "Simplifying the use of concepts", 2009-06-21, http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2906.pdf