2008-11-19
ZML
Fire and I are proud to introduce ZML.
Basically, ZML is a markup language with a C-style syntax and lots of syntactic suggar. Furthermore the ZML toolchain provides a ZML to XML compiler, which means that ZML is a convinient way of writing XML. So you could regard it as an alternativ to a feature rich XML editor.
But ZML is more. It is also a technique of code generation, thus an alternativ to Model Driven Architecture. These two aspects fit together when you know that ZML code generation is done with XSLT. Using the ZML syntax instead of the XML syntax for XSLT stylesheets makes it very easy to write a code generation tool whenever approriate. No BNF, flex and bison, no theoretical knowledge about gramar and parser classes. Just some XML, XSLT and XPATH, denoted in a convinent way.
2008-10-30
Mailfilter
Ever tried to do something advanced with procmail? I did. Enough pain to sit down and find something better.
So fire, who is a friend of mine, and I came together one afternoon to write Mailfilter. This enables you to do your mail filtering with Python.
I really like the result. Check out this few lines which automatically result in one folder for each mailinglist I am subscribed at.
@filter("List-Id", "(.*)$")
@filter("List-Post", "<mailto:(.+)>")
@filter("List-Id", "[^<]*<([^>]+)>")
def mailinglists(mo):
return "ml." + esc(mo.group(1))
@filter("Mailing-List", "contact (.*)-help@(.*); run by ezmlm")
def ezmlm(mo):
return "ml.%s-%s" %(esc(mo.group(1)), esc(mo.group(2)))
2008-10-25
secrets
Only the small secrets need to be protected. The big ones are kept secret by public incredulty.Marshall McLuhan
2008-10-25
economy
Anyone who believes exponential growth can go on forever in a finite world is either a madman or an economist.Kenneth E. Boulding
2008-10-25
const or not const
From the C++ FAQ:
const identifiers are often better than #define because:[...] There are cases where #define is needed, but you should generally avoid it when you have the choice.
- they obey the language's scoping rules
- you can see them in the debugger
- you can take their address if you need to
- you can pass them by const-reference if you need to
- they don't create new "keywords" in your program.
Nice said, and everybody believes it. Util you realize that these "const identifiers" in real are "const variables" which is an oxymoron. Already the fact that const variables have an address shows that they are no identifiers.
"Distinction without difference.", you think? Well, then look at this example:
const double FACTOR = 0.75;
const unsigned HEIGHT = unsigned(FACTOR * 5);
unsigned char a[HEIGHT];
which let's the compiler dump the following error
error: array bound is not an integer constantAh, yes, an unsigned const variable is no integer constant, right.... wtf?
As far as I understood the standard the compiler does not have
to calculate the value of HEIGHT at compiletime. This
is allowed because const identifiers are nothing but
read only variables. So this simple example already is a case where
you have no other choice but use the good old C style:
#define FACTOR 0.75
#define HEIGHT unsigned(FACTOR * 5)
unsigned a[HEIGHT]; // unsigned a[unsigned(FACTOR * 5)]
This example compiles. The C++ compiler is now forced to do the
calculation at compile time.2008-06-11
default arguments and name lookup
from fefe's blog two C++ gotchas about default arguments and name lookup rules.
2008-05-26
template type arguments
To gain code locality I often use local types. I really like this feature as it allows me to define a type a the location where it is needed.
A frequent use for this would be compare or ordering functors
for standard algorithms like sort or standard
containers like hash_maps. This look's like this:
Other languages have code blocks or other features which allow you to write the sort criteria straight away. Local types are an tolerable alternative to this in my eyes.void foo(const std::vector<Bar> bars) { struct Sort { bool operator()(const Bar& lhs, const Bar& rhs) const { /* ... */ } }; std::sort(bars.begin(), bars.end(), Sort()); }
Ähm, I mean, they could have been. But the standard prevents this. Section 14.3.1.2 says:
A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.
Oh my nudels. Why? Does anybody know a good reason for this? I can't imagine any. Furthermore I wonder how the syntax would look like when using an unamed type as a template parameter.
To make the confusion complete the GNU C++ compiler (version 4.2.3) dumps the following error when compiling the above example.
error: no matching function for call to 'sort(__gnu_cxx::__normal_iterator<Bar*, std::vector<Bar, std::allocator<Bar> > >, __gnu_cxx::__normal_iterator<Bar*, std::vector<Bar, std::allocator<Bar> > >, foo(std::vector<Bar, std::allocator<Bar> >&)::Sort&)'Yeah, right.
2008-05-26
anonymous classes
Recently I tend to group semantically related members into nested classes or structs. For instance imagine a class with concurrent access:
class Foo { public: int getSomething() { Lock l(purpose.mutex); return purpose.something; } private: struct { Mutex mutex; int something; } purpose; };
To avoid redundancy I don't name such nested structs. Why should I? C++ provides the feature of anonymous classes and structs and this technique is a good example why one would like to have it.
But as often with C++ this language feature collides with others and makes it less usable. In this case you are getting problems when the grouped members need to be initialized. As a constructor must have the name of the class anonymous classes can not have constructors.
Orthogonality must definitly be a design goal for usable general purpose languages. And this property is greatly missing in C++ which is the matter for my blog entries.
2008-05-26
signed or unsigned
I'm programing in C++ for years now and I still experience frequent surprises. Even on topics where I was dead sure.
Is an int signed or unsigned? The standard clearly
says (section 3.9.1.2)
There are four signed integer types: "signed char", "short int", "int", and "long int."So writing just int means the same as signed int which is as expected.
And here is the surprise: this is not always true. Section 9.6.3 says:
It is implementation-defined whether a plain (neither explicitly signed nor unsigned) char, short, int or long bit-field is signed or unsigned.
Unbelievable... It would have been too easy otherwise, I guess...
Thanks, Roker

