# Effective Qt in Ruby (Part 2)

In the first part of this series, I listed some of the reasons why you should consider writing your Qt/KDE applications in ruby. This post details some of the technical differences between writing Qt code in C++ and in ruby.

One of the first problems that pop up when starting a new Qt/KDE project in ruby is how to use it in such a way that your code doesn’t end up being completely unidiomatic. This can happen very easily if one tries to stick to the usual conventions that apply when writing Qt code in C++.

If you take any piece of C++ code using Qt, you can very trivially translate it into ruby. That works, and sometimes it’s useful, but writing code in this way completely misses the point of using a dynamic language. You might as well write directly in C++, and enjoy the improved performance.

So I believe it’s important to identify the baggage that Qt brings from its C++ roots, and eliminate it when using it from ruby. Here are some ideas to achieve that.

## Use the ruby convention for method names

A minor point, but important for code readability.

Qt uses camel case for method names, while ruby methods are conventionally written with underscores. Mixing the two styles inevitably results in an unreadable mess, so the ruby convention should be used at all times.

Fortunately, QtRuby allows you to call C++ methods by spelling their name with underscores, so it’s quite easy to achieve a satisfactory level of consistency with minimum effort.

## Never declare signals

The signal/slot mechanism is a very important Qt feature, because it allows to work around the static nature of C++ by allowing dynamic calls to methods. You won’t need that in ruby. For instance, you can use the standard observer library to fire events and set callbacks. It’s completely dynamic and there’s no need to define your signals beforehand.

## Never use slots

Slots are useless in ruby. QtRuby allows you to attach a block to a connect call, and that is what you should always be using. Never use the SLOT function with a C++ signature.

## Avoid C++ signatures altogether

This seems impossible. It might be easy to use symbols (without using the SIGNAL “macro”) to specify signals with no arguments, like

but if a signal has arguments, and possibly overloads, specifying only its name doesn’t seem to be enough to determine which particular overload we are interested in.

Indeed, it’s not possible in general, but you can disambiguate using the block arity for most overloaded signals, and add type annotations in those rare cases where the arity is not enough.

Here is my on method, which accomplishes this:

The Signal class maintains the signal name and (optional) specified types. The method lazily creates a signal map for each class, which maps symbols to C++ signatures, and proceeds to disambiguate among all the possibilities by using types, or just the block arity, when no explicit types are provided. If no signal is found, or if the ambiguity could not be resolved, an exception is thrown.

For example, the following line:

is referring to currentIndexChanged(int) and not to the other possible signal currentIndexChanged(QString), because of the explicit type annotation.

The advantage of this trick is that I can write, for example:

without specifying any C++ signature, which in this case would be quite hefty:

## Conclusion

QtRuby is an exceptional library, but to use it effectively you need to let go of some of the established practices of Qt programming in C++, and embrace the greater dynamicity of ruby.

In the next article I’ll show you how I tried to push this idea to the extreme with AutoGUI, a declarative GUI DSL built on top of QtRuby.

# Effective Qt in Ruby (Part 1)

As some of you might know, I’m working on a generic board game platform called Kaya. Kaya is a Qt/KDE-based application to play chess, shogi and variants thereof, and easily extensible to all sorts of board games (Go is in the works, for example). Kaya is written in ruby, and I have learned quite a few things about writing non-trivial GUI applications in ruby while working on it, so I decided to share some of my experience and code in the hope that it might be useful to others, and possibly inspire other Qt/KDE developers to try out ruby for their next project.

## Advantages

Here is a list of what I think are the most important points that make programming GUIs in ruby so much more productive than in C++. I’ll leave out subjective arguments like “it’s more fun” or “it has a nicer syntax” because I think that the actual facts are more than compelling already.

### Fast Prototyping

This is not specific to GUI programming. It is greatly aknowledged that ruby is orders of magnitude more convenient than C++ for throwing quick scripts together and in general for trying new ideas out. This turns out to be very important in a GUI context as well. For example, it is very easy to write setup code for a single component of your application so that you can run it standalone and test it more efficiently. I have found myself resorting to this kind of trick very often, and it sometimes makes debugging a lot less painful. In C++, it would be unreasonable to write a new application skeleton (and alter your build scripts) just to test a new dialog you are developing. Another example is “fancy logging”. If something breaks in the middle of complicated or highly interactive code, sometimes printing to the console or setting breakpoints doesn’t quite cut it. In these cases, it is a very good idea to hack together a simple but powerful visualization tool to show the internal state of the application in real time, and that is usually very helpful to identify the issue. Again, since this is basically throwaway code, ease of prototyping is very important.

### Declarative GUI Definition

Ruby has very powerful metaprogramming facilities that make creating an embedded DSL extremely straightforward. I use a simple mechanism in Kaya that allows me to write things like:

I find it very convenient to define GUIs at this slightly higher level of abstraction, plus you have none of the boilerplate code typical of GUI construction in C++. Defining GUIs in this way is so quick (and it’s easy to run them to immediately see the results), that it makes tools like Qt Designer completely redundant, in my opinion, except possibly when GUI design and coding are done by different people.

### Using Closures for Slots

Take a look at this simple example, and try to imagine how many lines of code would be needed to implement it in C++:

Here win.display is a QTextEdit and win.button is a QPushButton. What the example does is count up seconds in the QTextEdit, and toggle between that and counting down when the button is pressed. Pretty trivial, granted, but in C++ you would need to define two slots to do that, plus keep track of the direction in which you are counting by using a member variable. In ruby you can just use local variables without littering the parent scope.

### Toolkit Independence

If you write your application in C++, once you’ve decided that you are going to use KDElibs (or Qt), that decision is pretty much set in stone. You can’t even switch from KDE to pure Qt very easily, and it’s so hard to support both environments in a single code base, to make it almost completely not worth the effort. Of course, this might not seem that big of an issue, given that KDE is now a lot more portable, but not many people are running KDE SC on Windows or Mac at the moment, and if you want to reach as many users as possible, having a Qt-only version of your application is going to help a lot. So Kaya can currently run on Qt-only as well as KDE. When in KDE mode, all the usual KDE goodies are running under the hood: KPushButtons, KDialog, K-everything, and of course KXMLGUI and all the good stuff that comes with it, but it can switch to plain Qt classes and a simplistic replacement for the XML GUI if you don’t have KDElibs installed.

### Easier Automatic Testing

Dynamicity, mock objects, plus the whole culture of test-driven development that characterizes the ruby ecosystem make it a lot easier to devise automated tests for your application. Effective GUI testing is still basically an open problem in software engineering, so don’t expect it to be a piece of cake, but in my experience, you can definitely reach a considerably higher test coverage with ruby than with C++.

### Trivial Extensibility Through Plugins

KDE really shines when it comes to making applications easily extensible via scripts or plugins, but it can’t compare with ruby. The distinction between plugins and user scripts is now nonexistent, and loading a plugin is just a matter of calling the ruby load function. Creating a sensibly extensible application still requires careful planning, of course, but it’s a lot easier when you can directly expose application functionality to plugins, without creating tons and tons of interfaces for even the most trivial uses. In Kaya, the use of a dynamically typed language turned out to be key: the flexibility required to make its plugins easy enough to write without knowing much about the application internals is pretty much impossible to achieve in a statically typed context.

## Disadvantages

Of course, like everything in software engineering, choosing ruby over C++ for GUI development involves a number of tradeoffs.

### Performance

Everyone knows that ruby is slow. Painfully slow sometimes. That seems to be improving with 1.9, but ruby isn’t going to get faster than C anytime soon. Now, the good thing is that its poor performance is almost always completely irrelevant. A typical GUI application is nowhere near being CPU bound, and the few computationally intensive parts are usually in the GUI library anyway. That said, if you have performance critical sections in your application, you are better off writing them in C/C++ and accessing them from your ruby code using the ruby extension API. For example, Kaya includes a small C++ extension to supplement the missing blur functionality in Qt < 4.6. Writing it and integrating it was trivial.

### Testing is Essential

Automated testing is very important for software written in any language, but for dynamic languages you simply can’t do without it. Untested code will inevitably contain silly typos and type errors which will cause it to crash in your user’s faces, or in the best case will make your testing sessions painful and slow. So you don’t have any choice but to add lots and lots of unit tests, integration tests and the like. Units tests for pure GUI code are not really effective, useful or easy to write, but you can settle on smoke tests that will cover the most common mistakes and be pretty confident that no silly errors will pop up that a compiler would catch.

## Conclusion

I hope this gives a nice overview of the benefits you can get by switching from C++ to a dynamic language for your KDE (or general GUI) development. I used ruby as the main example, because that’s what I have experience with, but most of the points probably apply to dynamic languages in general (python, perl, clojure, etc). In the following posts, I will dig a little bit more into Kaya’s code to show the kinds of tricks that I employed to better exploit the advantages that I discussed, and offer even more ways to get the most out of ruby for GUI programming. Stay tuned!

# Monads for Markov Chains

Suppose you need to model a finite Markov chain in code. There are essentially two ways of doing that: one is to simply run a simulation of the Markov chain using a random number generator to obtain dice rolls and random cards from the decks, the other is to create a stochastic matrix containing the transition probabilities for each pair of states. In this post I will show how a single monadic description of the Markov chain dynamics can be used to obtain both a simulator and the transition matrix.

> {-# LANGUAGE MultiParamTypeClasses,
>     FlexibleInstances,
>     GeneralizedNewtypeDeriving #-}
>
> import Control.Arrow
> import Control.Monad
> import Control.Monad.State.Strict
> import Data.Array
> import Random

Let’s start with an example of Markov chain and how we would like to be able to implement in Haskell. Consider a simplified version of the familiar Monopoly game: there are 40 squares (numbered 0 to 39), you throw two 6-sided dice each turn, some special squares have particular effects (see below), if you get a double roll three times in a row, you go to jail. The special squares are: 30: go to jail 2, 17, 33: Community Chest 7, 22, 36: Chance Community Chest (CC) and Chance (CH) make you take a card from a deck and move to some other place depending on what’s written on the card. You will find the details on the code, so I won’t explain them here. This is of course a Markov chain, where the states can be represented by:

> type Square = Int
> data GameState = GS {
>       position :: Square,
>       doubles :: Int } deriving (Eq, Ord, Show)

and a description of the game can be given in a monadic style like this:

> sGO :: Square
> sGO = 0
>
> sJAIL :: Square
> sJAIL = 10
>
> finalize :: Square -> Game Square
> finalize n
>     | n == 2 || n == 17 || n == 33 = cc n
>     | n == 7 || n == 22 || n == 36 = ch n
>     | n == 30 = return sJAIL
>     | otherwise = return n
>
> cc :: Square -> Game Square
> cc n = do i <- choose (1 :: Int, 16)
>           return $case i of > 1 -> sGO > 2 -> sJAIL > _ -> n > > ch :: Square -> Game Square > ch n = do i <- choose (1 :: Int, 16) > return$ case i of
>                      1 -> sGO
>                      2 -> sJAIL
>                      3 -> 11
>                      4 -> 24
>                      5 -> 39
>                      6 -> 5
>                      7 -> nextR n
>                      8 -> nextR n
>                      9 -> nextU n
>                      10 -> n - 3
>                      _ -> n
>     where
>       nextR n = let n' = n + 5
>                 in n' - (n' mod 5)
>       nextU n
>           | n >= 12 && n < 28 = 28
>           | otherwise = 12
>
> roll :: Game (Int, Int)
> roll = let r1 = choose (1, 6)
>        in liftM2 (,) r1 r1
>
> markDouble :: Bool -> Game ()
> markDouble True = modify $\s -> s { > doubles = doubles s + 1 } > markDouble False = modify$ \s -> s {
>                      doubles = 0
>                    }
>
> goTo :: Square -> Game ()
> goTo n = let n' = n mod 40
>          in modify $\s -> s { position = n' } > > game :: Game () > game = do n <- liftM position get > (a, b) <- roll > markDouble (a == b) > d <- liftM doubles get > if d == 3 > then do markDouble False > goTo sJAIL > else do let n' = n + a + b > n'' <- finalize n' > goTo n'' As you can see, Game is a state monad, with an additional function choose that gives us a random element of a range: > class MonadState s m => MonadMC s m where > choose :: (Enum a) => (a, a) -> m a This can be implemented very easily using the (strict) state monad and a random generator: > newtype MCSim s a = MCSim (State ([s], StdGen) a) > deriving Monad > > instance MonadState s (MCSim s) where > get = MCSim$ liftM (head . fst) get
>     put x = MCSim . modify $\(xs, g) -> (x : xs, g) > > instance MonadMC s (MCSim s) where > choose (a, b) = MCSim$
>                     do (xs, g) <- get
>                        let bnds = (fromEnum a, fromEnum b)
>                        let (y, g') = randomR bnds g
>                        put (xs, g')
>                        return . toEnum $y > > -- type Game a = MCSim GameState a > > runSim :: StdGen -> Int -> s -> MCSim s () -> [s] > runSim g n start m = fst$ execState m' ([start], g)
>     where
>       (MCSim m') = foldr (>>) (return ()) $replicate n m The runSim function runs the simulation and returns the list of visited states. This is already quite nice, but the best thing is that the same code can be used to create the transition matrix, just swapping in a new implementation of the Game type alias: > newtype MC s a = MC (s -> [(s, Double, a)]) > > instance Monad (MC s) where > return x = MC$ \s -> return (s, 1.0, x)
>     (MC m) >>= f = MC $\s -> > do (s, p, x) <- m s > let (MC m') = f x > (s', q, y) <- m' s > return (s', p * q, y) > > instance MonadState s (MC s) where > get = MC$ \s -> return (s, 1.0, s)
>     put x = MC $\s -> return (x, 1.0, ()) > > instance MonadMC s (MC s) where > choose (a, b) = let r = [a..b] > p = recip . fromIntegral . length$ r
>                     in MC $\s -> map (\x -> (s, p, x)) r > > type Game a = MC GameState a The idea is that we keep track of all possible destination states for a given state, with associated conditional probabilities. For those familiar with Eric Kidd’s series on probability monads, this is basically: type MC s a = StateT s (PerhapsT [] a) Now, how to get a transition matrix from such a monad? Of course, we have to require that the states are indexable: > markov :: Ix s => > MC s () -> (s, s) -> Array (s, s) Double > markov (MC m) r = accumArray (+) 0.0 (double r)$
>                 range r >>= transitions
>     where
>       mkAssoc s (s', p, _) = ((s, s'), p)
>       transitions s = map (mkAssoc s) $m s > double (a, b) = ((a, a), (b, b)) So we iterate over all states and use the probability values contained in the monad to fill in the array cells corresponding to the selected state pair. To actually apply this to our Monopoly example, we need to make GameState indexable: > nextState :: GameState -> GameState > nextState (GS p d) = if d == 2 > then GS (p + 1) 0 > else GS p (d + 1) > > instance Ix GameState where > range (s1, s2) = takeWhile (<= s2) . > iterate nextState$ s1
>     index (s1, s2) s =
>         let poss = (position s1, position s2)
>         in index poss (position s) * 3 +
>            doubles s - doubles s1
>     inRange (s1, s2) s = s1 <= s && s <= s2
>     rangeSize (s1, s2) = index (s1, s2) s2 + 1

then finally we can try:

> monopoly :: (GameState, GameState)
> monopoly = (GS 0 0, GS 39 2)
>
> initialState :: Array GameState Double
> initialState = let n = rangeSize monopoly
>                    p = recip $fromIntegral n > in listArray monopoly$ replicate n p
>
> statDistr :: Int -> [(GameState, Double)]
> statDistr n = let mat = markov game monopoly
>                   distributions = iterate (.* mat)
>                         initialState
>                   st = distributions !! n
>               in assocs st

where .* is a simple vector-matrix multiplication function:

> infixl 5 .*
> (.*) :: (Ix i, Num a) =>
>            Array i a -> Array (i, i) a -> Array i a
> (.*) x y = array resultBounds
>               [(i, sum [x!k * y!(k,i) | k <- range (l,u)])
>                | i <- range (l'',u'') ]
>         where (l, u) = bounds x
>               ((l', l''), (u', u'')) = bounds y
>               resultBounds
>                 | (l,u)==(l',u') = (l'', u'')
>                 | otherwise = error ".*: incompatible bounds"

Calling statDistr 100 will return an association list of states with corresponding probability in an approximation of the stationary distribution, computed by applying the power method to the transition matrix. The number 100 is a pure guess, I don’t know how to estimate the number of iterations necessary for convergence, but that is out of the scope of this post, anyway.