syntax highlight

Thursday, 27 May 2010

Template metaprogramming VII: The Enemy Within

Remember where were we last time? We had this code to define a list:

struct NIL {
	typedef NIL Head;
	typedef NIL Tail;
};

template <typename H, typename T=NIL> struct Lst {
	typedef H Head;
	typedef T Tail;
};

template <int N> struct Int{ static const int result = N; };
typedef Lst< Int<1>, Lst< Int<2>, Lst< Int<3> > > > OneTwoThree;

Now, to increase our template-foo, let's practice some basic operations. The same operations you would implement to practice your skill any other functional language. If I remember correctly these where useful when learning Haskel: getting a list's lenght, getting the Nth element, appending and preppending elements... that sort of stuff.

Let's start with the most basic: getting the length of a list. We don't really have a for loop so using recursion is the only way. It gets easier if we think again on our definition of list: "think of a list as tuple, two elements, the first (called head) will be the first element of the list and the second element as another list or a NIL object". Whit this definition of a list, then it's length turns to be 1 (the head) + the length of the remaining list (the tail), with a special case for the length of a NIL object which should always be 0. In template-speak:

template <typename LST> struct Length {
	typedef typename LST::Tail Tail;
	static const unsigned int tail_length = Length< Tail >::result;
	static const unsigned int result = 1 + tail_length;
};

template <> struct Length <NIL> {
	static const unsigned int result = 0;
};

I know. You are thinking "wait, what?". Well, even for this basic case we need to use some esoteric language features:

  • typename is needed to tell the compiler LST::Tail is a type and not a static variable (like Length::result is). Did you remember that from chapter IV?
  • We have to use recursive templates, but you probably already figured that out. You should remember this from chapter II.
  • We can provide a spetialization of a template. You should also remember this from chapter II.

Obviously, you can write it this way too:

template <typename LST> struct Length {
	static const unsigned int result = 1 + Length< typename LST::Tail >::result;
};

template <> struct Length  {
	static const unsigned int result = 0;
};

The rest of the "basic" list-operations are quite similar, but I'll leave that for another post.


Thank you Stéphane Michaut for pointing out typos and bugs in the code listings

Tuesday, 25 May 2010

Deleting > Writing

Perfection is finally attained not when there is no longer anything to add but when there is no longer anything to take away, when a body has been stripped down to its nakedness.

Antoine de Saint-Exupery

Sunday, 23 May 2010

Level up!

Today it’s been 756864000 seconds of uptime since I was promoted from Release Candidate to V1.0. Hope none of you remember I made this same post 31536000 seconds ago.

Thursday, 20 May 2010

Template metaprogramming VI: The Spider Webb

We have been building our template meta-foo for five chapters now, and I think we are ready to move on to more advanced topics. We will be borrowing a lot more from functional languages from now on, so you may want to actually start practicing some template metaprogramming to keep advancing.

In our previous entries we worked with basic building blocks, making it quite easy to keep in mind the whole "program flow". Now it won't be so easy anymore, as we'll be using real metaprogramming (i.e. templates operating on templates) so a lot more thought will be needed for each program.

Another point to keep in mind, you don't have a debugger here. All the magic occurs at compile time so there is no gdb to step through your program to find a logic flaw. There's a little trick to check if you are too far off from the target but, mainly, you'll have to think for yourself.

Let's start with any functional programming course basics: lists. We have to think, first, how can a list make any sense when you only have types and no values. It means you can have a list like "int, char, void**, Foo", and not something like "1, 2, 3". Or, can you? There's a way to trick the compiler into creating a type from a integral value:

template <int N> struct Int {
	static const int value = N;
};

Voila! Now you can create a list of numbers. For our next trick, let's implement the list itself. No pointer magic, think of a functional definition of a list. Come on, I'll wait... ready? OK, a list is a tuple T of two values, in which the first element, called head, is the first element of the list and the second element, called tail, is either a list or the NULL element.

Quite a mouthful... let's go over that definition again:

// A list is a tuple T of two values
List: [ ..., ... ]

// in which the first element, called head, is the first element of the list
List: [ Head, ... ]

// and the second element, called tail,
List: [ Head, Tail]

// is either a list or the NULL element
List: [ Head, Tail]
Tail: List | Nil

So, as an example, a list of numbers could be expressed as:

	List( 1, List( 2, List( 3, NIL ) ) )

Closing up... how would you define this list in C++? Easy:

template <typename H, typename T> LST {
	typedef H Head;
	typedef T Tail;
};

We need here a NIL type to use as a list ending element. We could also use a default template type, so we won't have to write the last NIL to end a list definition. Thus we have now:

struct NIL {
	typedef NIL Head;
	typedef NIL Tail;
};

template <typename H, typename T> struct LST {
	typedef H Head;
	typedef T Tail;
};

Nice. You should remember the following rules:

  1. We can use template to define a template class, defining a new type based on a number instead of another type ;)
  2. We can't "store" a value in a type... unless we store it as a static value, that is.
  3. Using a convention for defining result holding variable names is very useful, as there are no interfaces and more than once we'll be using a result from an unknown class

With that said, let's translate the list (1, 2, 3) to Tmpl C++

template <int N> Int{ static const int result = N; };
typedef Lst< Int<1>, Lst< Int<2>, Lst< Int<3> > > > OneTwoThree;

Not so bad to start with. Next time we'll be doing something a little bit more useful with this list.

One last note, initializing a static const int in the definition of the class may be non portable (some compilers seem to have trouble with it). An enum may be used instead.

Tuesday, 18 May 2010

Dealing with Office on Linux

Seen @ bash.org:

< adamkuj> are there any good open source tools for working with Access DB's (mdb files)? <@Dopey> rm Comment: #evilgeeks

True, so true... It's been said a thousand times, but I kinda like ranting... like it or not Office files are a majority out there. If you work with Linux, using it in a real enterprise environment, sooner or later you'll run into someone using a propietary Office format. You'll also run into someone who doesn't know that you need OOO to open those weird odf files. You may need to produce an adecuately formated document sometime, and LaTeX may not be an option.

Deal with it. Install a VM, or Wine, and a copy of MS Office. Resistance is futile.

Wednesday, 12 May 2010

Template metaprogramming V: Face to face

By now we have learned the basics for a nice template metaprogramming toolkit:

  • Loops with recursive template definitions
  • Conditionals with partial template specializations
  • Returns using typedefs

Unfortunately that's all you need for a Turing complete language, meaning now we have the power, bwahahaha! Mph, I'm sorry, back on topic, it means we can now create a fully functional and useful template metaprogramming device... for approximating e, nonetheless. Oh, you think that's not useful? Well though luck, that's all you get for now:

template <int N, int D> struct Frak {
    static const long Num = N;
    static const long Den = D;
};

template <class X, int N> struct ScalarMultiplication {
    static const long Num = N * X::Num;
    static const long Den = N * X::Den;
    typedef Frak<Num, Den> result;
};

template < class X1, class Y1 > struct SameBase {
	typedef typename ScalarMultiplication< X1, Y1::Den >::result X;
	typedef typename ScalarMultiplication< Y1, X1::Den >::result Y;
};

template <int X, int Y> struct MCD {
	static const long result = MCD<Y, X % Y>::result;
};

template <int X> struct MCD<X, 0> {
	static const long result = X;
};

template <class F> struct Simpl {
	static const long mcd = MCD<F::Num, F::Den>::result;
	static const long new_num = F::Num / mcd;
	static const long new_den = F::Den / mcd;
	typedef Frak< new_num, new_den > result;
};

template < class F1, class F2 > struct Sum {
	typedef SameBase<F1, F2> B;
	static const long Num = B::X::Num + B::Y::Num;
	static const long Den = B::Y::Den; // == B::X::Den
	typedef typename Simpl< Frak<Num, Den> >::result result;
};

template <int N> struct Fact {
	static const long result = N * Fact<N-1>::result;
};
template <> struct Fact<0> {
	static const long result = 1;
};

template <int N> struct E {
	// e = S(1/n!) = 1/0! + 1/1! + 1/2! + ...
	static const long Den = Fact<N>::result;
	typedef Frak< 1, Den > term;
	typedef typename E<N-1>::result next_term;
	typedef typename Sum< term, next_term >::result result;
};

template <> struct E<0> {
	typedef Frak<1, 1> result;
};

int main() {
    cout << (1.0 * E<8>::result::Num /  E<8>::result::Den) << endl;
    return 0;
}

Looking nice, isn't it? You should have all what's needed to understand what's going on there. Even more, almost everything has been explained in previous articles, with the exception of EqBase. But that's left as an exersice for the reader because the writer is too lazy.

If you think any part of the code requires clarification ask in the comments. Next, a long overdue topic: lists using template metaprogramming. Guaranteed to blow your mind into little pieces!

Monday, 10 May 2010

Random WTFs

Random WTF 1

Note: Use dapper instead of edgy to use Ubuntu Dapper

Thank you captian obvious.

Random WTF 2

I've been working with a big-co supplied ACS server, but it's IE only. WTF!? Aren't ACS all XMLy so they can work everywhere? I hate you all.

Thursday, 6 May 2010

Template metaprogramming IV: Nightmares to come

By now you should have noticed the warnings were not in vain: we are exploring a bizarre side of C++ here, a side many people prefer to, wisely, ignore. Luckily it probably is too late for you, there is no way back. Only a long spiraling way down into the arms of despair and cryptic compiler error messages... mwahahahaha. But now, let's see where we are.

In previous entries we learned how to return values, how to define recursive devices and how to provide a partial specialization. Let's see know how can we use partial specialization and complex return type definitions for some more fun template metaprogramming tricks. We had a fraction and a ScalarMultiplication operation for Frak:

template <int N, int D> struct Frak {
static const long Num = N;
static const long Den = D;
};

template <int N, class X> struct ScalarMultiplication {
static const long Num = N * X::Num;
static const long Den = N * X::Den;
};

Let's try to add an operation to simplify a Fraction. Simplify< Frak<2, 4> > should return 1/2. Mph... simplifying a fraction means dividing it by the MCD. A quick trip to Wikipedia reveals a nice recursive way to implement an MCD device:

template <int X, int Y>	struct MCD {
static const long result = MCD<Y, X % Y>::result;
};
template <int X> struct MCD<X, 0> {
static const long result = X;
};

I won't get into much detail as the link explains it a lot better than whatever I could try, but do take a look at the definition of MCD: that's a partial specialization. No magic there. Back to our simplifying device, we now have all the parts for it. Going back to it's definition we can see that simple(fraction) = fraction / mcd(fraction). Then:

template <class F> struct Simpl {
static const long mcd = MCD<F::Num, F::Den>::result;
static const long new_num = F::Num / mcd;
static const long new_den = F::Den / mcd;
typedef Frak< new_num, new_den > New_Frak;
typedef typename New_Frak::result result;
};

Quite a mouthful, but a lot simpler than what you think as there is a lot of unnecessary code there. Until new_num and new_den, no surprises. Typedeffing a Frak is not new, either. typedef typename is something new: typename tells the compiler you're referring to a name inside a template class, otherwise it'd try to refer to a static variable inside said class (*). Knowing what each thing does we can simplify it:

template <class F> struct Simpl {
static const long mcd = MCD<F::Num, F::Den>::result;
typedef typename Frak< F::Num / mcd, F::Den / mcd >::result New_Frak;
};

It is a matter of style really. In this case I'd rather use the second one because it matches better its colloquial definition, but if you think the first one is more readable go with it... it doesn't really matter though, no one will ever even try to read this kind of code if you intend to use it in a real application.

Next time: a "useful" (**) and complete template metaprogramming device, using the complete toolset we've been learning in this crazy templating series.

(*) Think of it this way:

struct Foo {
   typedef int Bar;
   Bar bar;
};

In a template you don't know if Bar is a typename or varname because there's no access to the specific template definition. As a rule of thumb, if the compiler complains then add typenames.

(**) Results may vary according to your definition of useful.

Tuesday, 4 May 2010

Ubuntu: Sound still FUBAR'd

Remember my problems with dual screen support in Ubuntu? Well, I still love bashing Ubuntu, and the sound system in Linux is certainly a topic to rant a lot. Making the sound work fine in Ubuntu is an odyssey in pain and frustration, unless it works fine out of the box. And even if it does, it may still have it's kirks. Lots of them.

In my case the sound starts in mute. I know it's a problem with pulse (which is a WTF in itself) and alsa, I don't really care what's the problem though, I just want to play my mp3s collection without having to carefully turn the knobs up to eleven in alsamixer.

After trying a lot of the "solutions" found on the internets I've decided the best thing to do, short of switching back to windows me, is adding the following to my "fix_ubuntu_fuckups.sh" start script, which already contains my dual-screen pseudofix:

amixer -c0 -- sset Master playback -0dB unmute
amixer -c0 -- sset Headphone playback 0dB unmute
amixer -c0 -- sset Front playback 0dB unmute
amixer -c0 -- sset PCM playback -16dB unmute

This sets alsamixer to normal volume levels. As for the real fix, I'll wait till the next Ubuntu version. I wonder which sound subsystem will they chose next time.

Friday, 30 April 2010

Buguntu family album

This is a very cool family album: http://blog.nizarus.org/2010/04/ubuntu-the-family-album

Can't wait to upgrade to 10.04, my current install (9.10) is working like crap.

Thursday, 29 April 2010

Template metaprogramming III: Entering Pandemonium

If you are here and you have read the previous two parts then you are crazy. If you haven't then go and read it, then never come back if you value your sanity at all. We saw last time an example of a factorial using template metaprogramming, now it's time for something a little bit more fun. I was thinking on lists, but that's a bit too much for starters: let's do some more math. Now with fractions!

So, how would you express a fraction? The fun part, and you already know this, you have only types (*), there are no variables. Luckly static const int saves the day:

template < int N, int D > struct Frak {
	static const long Num = N;
	static const long Den = D;
};

Woo hoo... how boring, let's do something on those Fraktions, so they don't get bored... like multiplying:

template < int N, typename X > struct ScalarMultiplication {
	static const long Num = N * X::Num;
	static const long Den = N * X::Den;
};

Well that does the job, I guess, but it's ugly. Too ugly... why would we redefine a Fraction when we already have a great definition? Let's try again:

template < int N, typename X > struct ScalarMultiplication {
	typedef Frak< N*X::Num, N*X::Den > result;
};

OK, now you think I'm pulling your leg, but, promise, I'm not. This actually works, and it looks nice! Check out that sexy typedef: you can't have variables, we said, so instead we return types. Frak is a type when binded to two concrete values, so Frak is a type too. Just typedef it to a result and be done with it.

How do we test if it worked? Easy:

int main() {
	typedef Frak< 2, 3 > Two_Thirds;
	typedef ScalarMultiplication< 2, Two_Thirds >::result Four_Sixths;
	std::cout << Four_Sixths::Num << "/" << Four_Sixths::Den << "n";
}

Nice! By now you should have learned how to return new types, which are the result types for template metaprogramming devices. You should have also learnt how to write a device which operates on another template device... congratulations, that's metaprogramming. Next time, something a little bit more interesting.

(*) Boring theory rant: What do I mean you can't have return values so you must use types instead? Let's see: a variable or an attribute are both parts of an object. If I have a variable named height in a class named Person, then each person gets his own height. Even if the numeric value is the same there won't be two shared height attributes. On the other hand static const vars are defining parts of classes, not objects; stupidity could be static const var of Person (only in this case we'd all be equally stupid... this is were the analogy falls apart, I'm sorry).

Knowing the difference between an object and a class defining characteristics, it is clear we can only use static const stuff - it's nonsense talking about template-objects, it's all about template classes.

Tuesday, 27 April 2010

Ubuntu: Dual screen still FUBAR'd

I'm quite sure I have written about this before but I'm too lazy to search for the article right now. Well, dual screens in Ubuntu still sucks. Much less than ever before, granted, but it still works quite bad. In my specific case the whole desktop is shown, in both monitors (which by itself is a huge improvement over previous versions) but the working area is clipped to the notebook's monitor size. Not nice.

To fix this problem (more like hacking it away, actually) I keep a handy bash script in the top left corner on my desktop:

xrandr --output HDMI-2 --right-of HDMI-1 --mode 1680x1050 --rotate normal

Also, as I have two nice rotable monitors at work it's nice that now Ubuntu supports actually rotating the picture displayed in the monitor (thanks Ubuntu for coming up to speed... with windows 98, that is). Obviously I keep another script for this, as it doesn't really work by default:

xrandr --output HDMI-1 --left-of HDMI-2 --mode 1680x1050 --rotate left
xrandr --output HDMI-2 --left-of HDMI-1 --mode 1680x1050 --rotate normal

Even though I love bashing Ubuntu (and bash) I'm quite confident most, if not all, of this issues will be gone in future versions of the OS.

Thursday, 22 April 2010

Template metaprogramming II: Openning the box

We saw last time how to print a factorial using only template metaprogramming, but didn't explain anything about it. I promised to fix that in this article. Starting by the very beginning:

template <int N> struct Factorial {
	static const int result = N * Factorial<N-1>::result;
};

template <> struct Factorial<0> {
	static const int result = 1;
};

int main() {
	std::cout << Factorial<5>::result << "n";
	return 0;
}

Why static const?

Templates get evaluated on compile time, remember? That means all that code actually executes when compiling the source, not when executing the resulting binary (assuming it actually compiles, of course). Having as a constraint the fact that all your code must resolve on compile time means only const vars make sense. Also, as you're working with classes (templates are applied to classes, not objects) only static objects make sense.

That explains the static const thing, what about the Factorial<0>? Well it's obviously an edge case. It describes a specific case of a Factorial. It's a specialization! Why do we need it? Take a look again at the definition of struct Factorial: it's a recursive definition. How do we break from the recursive loop? With a base case, obviously.

If this is starting to remind you of anything then you are crazier than you think, and you already know some Haskel. Indeed, template metaprogramming has some resemblance to Haskel programming: no const "variables", no for-loop (only recursion), base cases (pattern matching), and cryptic error messages which makes you want to jump of a cliff.

A useful trick I learned when working with Haskel (many many years ago) is to declare the problem, instead of thinking it. For our problem the factorial of a number is defined as said number times the factorial of that same number minus one, being the factorial of 0 always 1.

Translating:

// the factorial of a number is defined as said number times
// the factorial of that same number minus one

template <int N> struct Factorial {
	static const int result = N * Factorial<N-1>::result;
};

// being the factorial of 0 always 1.
template <> struct Factorial<0> {
	static const int result = 1;
};

That's good for a first approach... next time something more complex (and less theory, promise).


Thanks to Stéphane Michaut for reporting broken code in this page.

Tuesday, 20 April 2010

Vim tip: Word count

Trying to count words is a common task. Whenever you're writting a report for class, that is. There are some legitimate reasons but they don't matter now: it's a great chance to show off how great Vim is.

First method: Type ggVgY"*p to copy the whole text. Then paste it into word and use word count.

Second method: Type %!wc -w, which executes wc on each line.
Third method: Type g^g (g, CTRL+g) and watch the bottom of your screen.

As ussual, Vim rocks.

Thursday, 15 April 2010

Template metaprogramming: A slow descent towards utter maddness

There have been some articles dealing with template metaprogramming over here. Things like template <int n>, which look really weird (but behave in an even more bizarre way). This post starts a series of articles following the contrived and tortuous path down insanity lane and into the mouth of the beast. When we are done things like typedef typename should be clearer than i=i++, should you dare to keep on reading.

First things first: Why TF would I...

Instead of explaining why let's start backwards: assume you already want to start learning some template metaprogramming. Yeah, I'm sure there are many legitimate reasons, like job security or job security perhaps, but if you want to learn template metaprogramming the most likely explanation is you are nuts. Plain and simple.

Practical uses? Not really. Yeah, there are some (if you are a boost developer) and lets you write some neat stuff, but in your every day job you are most likely never going to use them. And that is a good thing (tm), for mere mortal programmers tend to like getting their jobs done. Having said that, let's learn some template metaprogramming!

Metawhat?

First, we need to start with a little clarification: using template to parametrize a class, something like std::vector does, is not template metaprogramming. That's just a generic class (Java-pun intended). That is indeed a useful case for templates, but it has little fun in it.

Template metaprogramming is much more fun than mere generic classes. The template processing in C++ is a language on it's own (no, really, like a Turing complete language and everything), though a language with very weird syntax and a very strange "design". Design between quotes because there was no design in its initial stages, template processing is a sub-language organically grown as a side effect of adding partial templates specialization (more on this later), so don't expect a nice language. Here, let me show you an example of another organically grown language: Microsoft's .bat scripting. You can imagine now what kind of beast this is if we are comparing it to bat scripts, right? (Nitpickers note. yup, I do know bat scripting is not a real language as it's not Turing complete. The comparison still stands though).

First step

Enough chatter. Let's start with an empty program and work our way down from there:

template <int N> struct Factorial {
 static const int result = N * Factorial::result;
};

template <> struct Factorial<0> {
 static const int result = 1;
};

int main() {
 std::cout << Factorial<5>::result << "n";
 retrun 0;
}
Whoa. Lots of magic going on there, on the simplest of all template metaprogramming tricks. But I don't feel like explaining it right now, I'm too sleepy, so I will leave that for next post.

Tuesday, 13 April 2010

Changing default file associations in gnome

It's been a long time since I posted a Linux related tip. Not in the mood I guess... well, this is one which really annoyed me, until I found out how easy it is: I hate some of the default file associations in gnome. Movieplayer, for example, is a horrible choice. Breaking and devolving with each new distro release, I have decided to settle with vlc as my default movie player, yet I couldn't easily change the default file type association. After fiddling around with the thingy in gnome resembling a regedit (ugh) I found out the easy way:

* Right click the file for which you want to change default associations and click properties
* Select "open with" tab
* ...
* Profit!

Saturday, 10 April 2010

I hearth Berkeley

error: cannot convert ‘Db**’ to ‘DB**’ for argument ‘1’ to ‘int db_create(DB**, DB_ENV*, u_int32_t)’

Thank you very much, Oracle Berkeley, for having a type named Db and another one named DB, and for never using namespaces. It makes my work a much more interesting challenge (*).

(*) Yeah, I know, Db is for the C++ wrapper and DB is for the plain C API (**). So what, I hate you all anyway.

(**) I'm working on a project with Berekley DB and it has enough WTF moments for a complete blog... I may post some of them, as a catharsis method. (***)

(***) Or because it has some interesting stuff too... who knows. Recursive note FTW (**). I think I have already done that, haven't I?

Friday, 9 April 2010

Fixed string: POD String datatype

We saw in POD types in C++ the difference between a POD and a non-POD type but the question of how to apply this knowledge to persist an std::string-like object remained open. This problem is a specific version of how to persist an object from which you know the size but has internal buffers using the heap instead of using only stack memory.

The best example for this case is, perhaps, a column from a table. You know the upper limit of the string's length but using std::string is clearly much better (easier) than a char[N]. Yet you'd be loosing the ability to persist this object in a generic way (i.e. copying memory instead of knowing the object's internal structure).

Well, there's an easy solution (though more than a solution I'd call it an acceptable trade-off) in which you can create a char[N], a char buffer, with std::string-like behaviour and yet POD-safe (almost POD safe actually, as we'll see now).

What's a POD?

POD datatypes, though informally explained in "POD types in C++" have a formal definition which you can look in Google. For practical terms a POD is a trivial object: no custom constructors, no virtual functions, nada of the fun stuff C++ can give you (or a native type, obviously).

Although this definition gives us quite a hard constraint we can create a quasi POD object (!) that does not conform to the standard definition of POD, yet has all the properties of one. This is the kind of struct we'll be creating. It would crash our program if used in a printf, but resides completly on the stack.

Implementing a POD string

A word of warning: ignore for now the "template " part; that's a template metaprogramming technique which we'll discuss some other day.

template  <int N> struct FixedString {
   mutable char str[N];
   FixedString() { str[0] = 'X'; }
   FixedString(const char* rid){ memcpy(str, rid, sizeof(str)); }
   FixedString(const FixedString &rid){ memcpy(str, rid.str, sizeof(str)); }
   operator const char*() const { return str; }
};

You can see now why I called it a trade-off: it works as we intend it to work but it does have its rough edges (most notably the const char/mutable part). It'll allow you to use a char[N] with some behaviour of an std::string; use it with caution.