Swiften on Lambdas

One of the cool new features of the upcoming C++ (0x) standard is support for lambda expressions, providing functional-style inline function declarations. After seeing Herb Sutter’s PDC 2010 webcast on lambdas, I wanted to try this out on Swiften, the XMPP library behind Swift. I adapted the introductory EchoBot example from XMPP: The Definitive Guide, and ported it from Python to a C++ application using Swiften. The result is surprisingly clean.

The purpose of EchoBot is simple: connect to an XMPP server, log in, send out a status message to announce you’re available, and then wait and respond to all incoming messages with the exact same message. Translating this into C++ code, with lambdas, gives us the following:

#include <Swiften/Swiften.h>

using namespace Swift;

int main(int, char**) {
    // Set up the event loop and network classes
    SimpleEventLoop eventLoop;
    BoostNetworkFactories networkFactories(&eventLoop);

    // Initialize the client with the JID and password
    Client client(
        "echobot@wonderland.lit", "mypass", &networkFactories);

    // When the client is connected, send out initial presence
    client.onConnected.connect([&] {
        client.sendPresence(Presence::create("Send me a message"));
    });

    // When the client receives an incoming message, echo it back
    client.onMessageReceived.connect([&] (Message::ref message) {
        message->setTo(message->getFrom());
        message->setFrom(JID());
        client.sendMessage(message);
    });

    // Start the client
    client.connect();

    // Run the event loop to start processing incoming network events
    eventLoop.run();
    return 0;
}

The flow of the code follows the description of the bot quite closely. Before connecting the client to the network, we declare the actions to be taken on different events: when connected, send out presence, and when a message was received, send it back. Swiften uses signals to notify events, and instead of having to declare slot methods and using boost::bind to connect signals to slots, we can now use lambdas to directly specify what should happen. (for the curious: [&] means that all variables outside of the lambda, i.e. client, are passed by reference)

The great thing about this is that this works out of the box with recent compilers: I tried this code with Microsoft Visual Studio 2010 and GCC 4.5.0. (unfortunately, CLang doesn’t support this feature yet)

If you want to try building your own XMPP applications using Swiften (with or without C++0x), grab a development version from the Git repository, and consult the Swiften Developers Guide and Swiften API documentation to get started.

This page was posted in Programming with tags CLang, Herb Sutter, C++0x, Lambdas, Swiften, Swift, GCC, XMPP, Jabber, C++, Visual Studio .