Saturday, 28 May 2011

Don't Decay your Arrays!

OK, that's nothing new, the technique is old, will be obsolete soon with the new std::tr1::array, and why should we use naked arrays anyhow? But recently I couldn't write it down as easily as I would like to, and as it's useful in the pre C++2011 code, why not discuss it shortly here?

Imagine you have to implement a Netbios/SMB remote file access protocol. The problem we are faced with while doing this is trivial but important - we need to log different packet types, operation codes and command options for debugging. They are all defined as integer type values and C++ doesn't (nor does any language I know) offer much support in that respect. So we define our own mini framework using macros. Don't panic, macros aren't that bad as they are told, and in our use case they are a perfect fit: translating between code (integer value) and strings (its descriptions). It's like eval() but in the other direction :). And it is working like this:
  // trace helper tables
  #define DEF_DESCRIPTION_ROW(a) {a, #a}
  struct CmdNameEntry { int cmdId; string cmdName; };

  const CmdNameEntry g_cmdNameTableNetbios[] = {
      DEF_DESCRIPTION_ROW(SESS_MESSAGE),
      DEF_DESCRIPTION_ROW(SESS_REQUEST),                             
      ...
  };
  const CmdNameEntry g_cmdNameTableSmb[] = { 
      ...
  };
  const CmdNameEntry g_cmdNameTableTrans[] = { 
      ...
  };
  const CmdNameEntry g_cmdNameTableTrans2[] = {                 
      ...
  };    
Got it? We use C's stringize operator (#) to convert a constant's name to a string in compile time. You see, we need quite a couple of tables, and each of the tables has many entries (you have to believe me, Netbios & Co are rather a chatty bunch). So why are we using naked arrays? Because the std::vector class didn't have a convenient initializer before C++2011*, a shame! Alternatively you could copy the array's contents to a fresh vector just to pass it to futher processing, but how ugly is that?

Now you'd need to write something like this to translate between integer codes and their descriptions:
  getCmd(g_cmdNameTableSmb, sizeof(g_cmdNameTableSmb)/sizeof(CmdNameEntry)),
because in C/C++ you cannot define a true function on arrays like this:
  getCmd(CmdNameEntry table[N]).
Well, it seems you can after all, but it's of no use anyway because (as you know) inside of the function the array will decay to a pointer and the size information will be lost. I don't know how other people may feel about it, but after some time I got pretty annoyed with that. Couldn't we wrap this in a macro, or even better, use some template trickery? Let's try and write a small utility:
  template<typename T, size_t N>
    string SmbProtocol::getCmdName(int code, T(&table)[N], const char* errorStr)
  {
      for(size_t i = 0; i < N); i++) // <- oops!!! compile error!
      {
          if(table[i].cmdId == code)
              return table[i].cmdName;
      }    
      return errorStr;
  }
Uh-oh, that doesn't compile, but frankly, how should it? N isn't a runtime construct, it is type information, and it lives only at the compile time! What we need is something to translate between type and value, i.e. a bridge between compile and run time. It appears that's not so complicated as it sounds, just write**:
  namespace util
  {
  template<typename T, size_t N>
    size_t array_size(T(&)[N]) { return N; }      
  }
As we are in a template, we can access the type information, and as we are a function, we can return a value. Bridge ready! Now we only need to replace the incorrect line with:
  for(size_t i = 0; i < util::array_size(table); i++)
and now we are ready to go:
  string SmbProtocol::getNetbiosCmdName(int code)
  {
      return getCmdName(code, g_cmdNameTableNetbios, "UNKNOWN_SESS_MSG");
  }
Now we can define new description tables, forward them to functions using the pair of T(&table)[N]and util::array_size() and let our pre C++2011 code look a little more elegant.
--
* You can have a look at this previous installment of this blog for the new C++0x initialization syntax .
** if you wonder about the array parameter syntax look here for an explanation: template-parameter-deduction-from-array-dimensions

Thursday, 26 May 2011

Bad Case of Code Reuse

Bug story!

We all strive to write elegant, concise and clear code. One of the tenants of this pursit is the "DRY" principle - don't repeat yourself! But as usual you shouldn't always follow a principle blindly. Take for example the following bug which caused me some problems at customer's premises.

I just extended the client library of the system I was in charge of at that time to suppport parallel requests, as the legacy server code would would be too risky to be refactored. Why? Well, not everyone has the luxury to have (or even sometimes to be able to define) a comprehensive set of unit tests. In case of the legcy product there were none, and worse, the sheer number of possible inputs (any satellite data, corrupted or not) does not allow the system to be wholy tested!

I decided to supervise long running tasks and send a short running ones in parallel, so the concurrency level would be bounded by 2.  At two points in the code I have got to check if the next task is a long-runner or not: when a single new task is submitted for processing, an when I need a second, parallel task (which cannot be a long runner again!). As I (true to the agile) first wrote the new task submission code, I defined the:
isLongrunner(filename)
method, which looked up if the input data file could be a potential long-runner. This method was used to check if a newly arrived request should be run in parallet to the currently running one. Then the library was tested and the first version was finished.

In the next test iteration I added pulling of the requests from the input queue when a short-runner gets ready and the long-runner is still busy. So I had to check if a request sitting in the input queue were a short-runner. But wait, our requests are files, and we already have a method to check for it! DRY baby! Elegant code! I tested it locally, and then it was deployed to our customer on the other side of the globe, namely in Asia. Mission acomplished, no problems expected... You wish! Of course, in Asia the new client library didn't quite work as expected, and the problem that had to be corrected still showed up. Embarassement, client unhappy! After many calls and emails I had at last the logfiles with the error showing clearly up.

What was the problem? In the parallel task submitting code at the end of a short running request I DRY-reused the
isLongrunner(filename)
method, I should rather use:
isLongrunnerSession(sessFilename)
What's the difference? Well, in my client library there is one: the filenames waiting in the input queue will be processed and can be renamed in some specific cases. The isLongrunner() method will check the already processed filenames, as it's passed as paramether to the WorkerThread::process() method*. Unfortunately, in the second case, we are already in the process() method, and are looking directly into the input queue, where the raw file names are to be found! Bugger! And the local test worked, because..., well I can't remember the reason now, probably I didn't test the interface variant (there are two, legacy and modern one - it's a real, living and growing system) the asian client was using. Ooops :(

So what do we learn from this story?
  1. If I wasn't so obsessed with code elegance and DRY, I wouldn't be lured into bad reuse, and then the omission to test the right interface version wouldn't have such unpleasant consequences.
  2. If I'd care about the naming of the methods and its parameters to the point of obsession, I wouldn't settle for the first name which somehow filled the bill. It was sloppy!
 So the advice is as with the optimization: first get the code right, that get it DRY! And sometimes the techniques we are eager to use are more of hindrance than of help in a subtle way.

--
* WorkerThread is a part of my portable (as it's Qt-based) worker library, maybe I'll find the time to blog about it. At least the title is already chosen: "Are workers actors?".

Wednesday, 22 December 2010

A Little Agile nad XP Rant


The title of this blog is "On Languages ... etc etc ... Systems and Proceses", but utill now I never said anything about processes (or did you think I meant UNIX processes?) so let us write something about the latter now. As lately everybody seems to be happy with Agile/XP (like here and here), let's rant about that a little. So beware, it's (at least partially) a #RANT#, so don't try to kill or evangelize me!

1. The Gripes


The one single thing you encounter today in the process land is the Agile. Well, I have a few gripes with that, which I should have wrote up earlier (and I wanted to, really, for the last 3 years or so), but now the time has come. On the other side, now when Agile is mainstream, maybe my points aren't valid anymore? You know, "the normative force of the factual"* :(. Maybe, but let us begin from the start of all that:

As I read the "Agile Manifesto" and the XP explanations some 10 years ago or so, I was just amazed. It was the liberation! And what I particularly liked were things like pair programming, test driven design, and iterative deleopment. But today I must realize that I was somehow mistaken - maybe did I get it all wrong? Somehow it's all different from what I imagined it'd be, and I don't like it very much. Two examples:

a) the pair programming
In my eyes it was all about two people caring about a piece of code, discussing its design, reviewing main rewrites, just because discussing something with another person can show you another perspective on the problem.

And now? The reality? It is crazy, it's about keyboard swapping, and two people doing coding at the same time. For 15 minutes it's my keyboard, and then it's yours. Come on, are we in Henry Ford's car factory? Or were we supposed to be doing some creative work? #RANT#

But there are people who actually like that (here, here) aren't they? I'd say this could work, but only if you are paired up with someone on your level. Not just another beginner guy with a big ego, thank you very much! Even then I find it to be an overkill, 2 people doing work of 1? Aren't there people able to be doing decent work by themselves anymore? #RANT#
b) test driven development/design (TDD)
I liked this idea very much. OK, I've only seldom written the tests before code myself, but there always have been tests for a new feature: either before I coded it or after that. Because really, that doesn't matter if you know what a feature you are going to implement.

But now? The reality? You should always write tests first. Or you are not agile. And why that? It comes even better - TDD can mean test driven design! A good example of this was to find in a blog posting** of the venerable Uncle Bob where he develops a prime factorization algorithm by TDD, i.e. by writing a series of increasingly complicated tests and reworking the algorithm accordingly. That looks for me like crazy, groping in the dark for the right solution, excuse me?! #RANT#


Why should we waste time and rework our solution on and on? The received answer is: because it results in decoupled code. Come on, aren't there other ways to write decoupled code? Like old and unfashionable thinking about its design a little? #RANT#

2. Some Summary and More Gripes


So meanwhile the XP is for me not the freedom, bur rather the next horsewhip of the pointy haired boss types. It's more about following the rules and their religious observance than about anything else. As I read about XP/Agile first, I thought it was targeted at proficient developers, you know, at the responsible adults, which should be allowed to be adult and just do their job! But now I have more and more the impression that it's rather targeted at beginners. Obviously, they need clear rules and directions. So maybe it's about the overall prevalence (and importance) of beginners in our industry?

Well, mabe (just maybe) I'm opposing the abovementioned XP principles because they introduce a process-like quality into XP, and I feel kind of betrayed now? It was supposed to be about freedom and interacting free individuals? Maybe it was just an illusion, maybe the recipe of Agile Manifesto was too simple?

In this this excellent post about "post agile" development Gwaredd Mountain states that no methodology is pure "agile" or pure "process-oriented". Rather, each one of them contains "freedom" (agile) and "process" elements, as a mix of both is needed for the real world. So even the supposedly totally free XP has to have some emergency brakes. Well, so much for my illusions of a better world :(. Nonetheless, the emergency brakes are rather expensive, the double pair of eyes to watch over "Brownian motion" like TDD development? That's my private opinion, but arguably it's somehow taking things to the extreme.

But there's 3rd problem, and it's not easily dismissed:

c) evangelism
In the Agile world-view there's either agile or waterfall, stone age, and nuclear winter. A typical Twitter post says:
Agile change is change. Change is hard for people
thus, if you can't get enthusiastic about Agile it means that you are unreformable, and just can't see the light! I think the Agile trainer guild is responsible for that***. As their training courses target mainly the beginners, they must give them rules to be followed in each circumstances. But I cannot understand why this must be promulgated to the general public? You know, "Only a Sith deals in absolutes", it's not a sign of wisdom do divide the world in the only right way and all the others! #RANT#

Ok guys, you must earn a living, but doesn't engineering decency mean anything to you? Or can't you think for yourselfs and would rather become a follower? Silver bullet anyone? That irritates me, but at the same timee it's interesting - what could possibly be a result of a realy intensive full-night talk with an Agile trainer? #RANT#

It's a little known fact, but Dr. Royce's defining paper for the waterfall process already contained iterations (see figures 3 and 4)! Agile is not that original, people were able to think and use common sense before that! #RANT#

3. So What Do I Think Myself?


You may ask, how should we develop software then? We're not supposed to go back to "cowboy coding" are we? Steve Yegge' post describes an alternative: the pretty informal Google development practices at that time and praises it as the solution. Well I must admit it does sound good, but then even Google wanted to introduce some process not a long time after that (Shh, we are adding a process). In that article they describe how the Scrum process was introduced in the AdSense project (if I'm not mistaken), however not a full embodiment of Scrum. But it seems that somehow for time critical, heavy-money projects you need some kind of a whip in the end... :(

So what do we need a process for? Do we need it at all?

First let me quote Aristotle (via "Pragamtic Programmers" link, and no, I don't read him in original...) - "We are what we repeatedly do. Excellence, then, is not an act, but a habit." As I understand it, we have to kind of design the things which we repeatedly do, if we want to ge good at something. And that's a start of a process.

Staying Alive in Avalanche TerrainThe 2nd insight comes from the field of avalanche avoidance (because I'm somehow of an offpiste skier). What the professionals always do, is to have a checklist in the car and to go through it every time they set off. Because people forget, people do make mistakes, and in that profession, when they do, it can cost them their life. That's a kind of process too - you won't believe that you could do a mistake, but in the grand scheme of things, you probably will. So you need some annoying routine, even if you don't think so!

So what would I take? A methodology I liked rather well was the "Tracer Bullet Development" from the abovementioned "Pragmatic Programmers" book. It's simple, it has a lot of common sense (what I seem to like more then religious fervor) and it goes along the lines of my own understanding of the agile development which I came to during the last 10 or so years.

Because I'm not an enemy of agile. More than taht, I think it's somehow a necessity! In real life there's constant change, and the original design**** of a system cannot be sustained - either it will be dying or it must adapt! So for me, agile has got it right in its basic proposition - you must always iterate. As the ancients used to say "iterare necesse est, vivere non est necesse" :).

And what about my Agile/XP gripes? Here I'm with Steve Yegge - there's "Agile" and "agile", Agile of the trainers and pointy-haired bosses, and agile of the pragmatics. And I'm with the latter.

Waiting for your comments.

---
* or "die normative Kraft des Faktischen", by Immanuel Kant. This means: all that is, is good, because it is (i.e. exists) or something like that.

** sorry, the original blogpost I read is vanished, this one is the current version reworked as a programming kata:
http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata

*** Read Steve Yegge's post about the so called "Agile" experts: "Good Agile, Bad Agile ", http://steve-yegge.blogspot.com/2006/09/good-agile-bad-agile_27.html, or this one: "Agile Ruined My Life", http://www.whattofix.com/blog/archives/2010/09/agile-ruined-my.php and look out for the Fraud markers!

**** For example, take this fascinating and/or terryfying case of dying architecture (from the "Refactoring in Large Software Projects" book):
Alas, everything started out so well! The concepts were clear-cut. The technical prototype was a success, the customer was thrilled and Gartner Group decided that the architecture was flawless. Then real life began to take its toll: the number of developers went up, the average qualification dropped, the architect always had other things on his plate – and time pressure increased.
The consequence was that the architecture concepts were executed less and less consistently. Dependencies were in a tangle, performance dropped (too many client/server hops and too many single database queries), and originally small modifications turned into huge catastrophes. To a certain extent the architecture concepts were circumvented on purpose. For example, classes were instantiated via Reflection because the class was not accessible at compile-time.

Saturday, 11 December 2010

Some Observations on Software Estimation

In my prevoius post post in introduced the "real life factor" frw for software estimation, and conjectured it to be as high as 3. I remebered that as I read James Iry's short blogpost. Let me quickly restate its contents. He recollects the course of a software project and the estimates at each point of its history. I summed that up and added the reason for each estimate failure:

             | Project | 
   Estimate  |  Phase  |   Error Reason 
  -----------+---------+-----------------
    2 weeks  |    0%   |  initial guess
             |         |  
    4 weeks  |   50%   |  too optimistic!
             |         |  
    6 weeks  |   90%   |  hidden complexity
             |         |  
    8 weeks  |   99%   |  forgotten the tests,
             |         |  docs and review
             |         |  
    8 weeks  |  100%   |  not really ready, but 
             |         |  has had enough!

So there it is, when estimating we are too optimistic from the start, and then we tend to forget a lot of things .So using this error "model" the real life factor would be frw=4! I'd say rather high. Maybe we need a better model? And what if we want to be really careful?

Software Estimation: Demystifying the Black Art (Best Practices (Microsoft))
 When speaking about serious software estimation you will usualy end up with the "Demistyfying the Black Art" book (an excellent book indeed, read it!), and will probably learn and use the PERT technique, where you have to give 3 estimates: the best case, the normal case, and the worst case estimates. Then you take a formula and get the expected project duration.

That's all very well and good, but when using this technique, we still tend to be overly optimistic and to forget a lot of things, exactly as in the above example!

The following blogpost hits the nail on the head:
Our experience has taught us that simply asking developers to make two estimates (“low” and “high”) doesn’t really result in much more information than a single point estimate. Developers tend to be optimistic when it comes to individual estimates. So without a little structure, the “low” estimate usually means the absolute smallest amount of time the task could take – an event with a very low probability of coming true. The “high” estimate means what it’s most likely to take to get done.
Given that data, let us do a smal, back of the envelope calculation for the probabilities of the 3 PERT estimates. Thus:
  low estimate => rather improbable => say 20% probability
  high estimate => most likely => i.e. 50% probability
then
  medium estimate => will lie inbetween => ~30% probability
So the real life factor for the medium (i.e. realistic) here is frw=3.3, not that different form the above, unscientific guess! PERT will correct this somehow, by not that much. So should we really always multiply our carefully crafted estimates by 3 (or 2), thus admitting that we cannot do it? That's scary.

But wait, we don't need 100% certainty, that would be sandbagging! Let us say, 80% is enough (see Pareto), but that's still 2,7 times the our "realistic" estimate or 1,6 times the "worst case estimate". I don't want to make any conclusions though, it's only some observations because it makes me curious that the value of 3 seems to resurface rather often!

Tuesday, 23 November 2010

Yet Another... Web Framework (in C++)

What? YAWF - yet another web framework? But this is mine(!) ... and it's very small - a Simple Embeddable C++ Webframework for Qt!

1. The need


I have discussed this topic on this blog earlier*, so you shouldn't be surprised to hear about it again: a C++ web framework. You'd think there isn't such thing? Wrong! From my own research and from the comments of friendly internauts I collected a quite a list of possible frameworks:
And recently I found even another one:
  • CppCMS


    Do you see its cool logo? It says that programming in C++ is a good thing, as it isn't hard on the environment, and thus can maybe even stop the global warning ;). I must admit that I never seen C++ from that angle! Interesting point, isn't it? Ok, when you think of all that multicores and figths about cache lines then C++ does quite naturally comes to mind with its very direct memory control, doesn't it? Kind of "lean programming" :).
And don't forget the new kid on the block:

It's rather a wide range of possiblities, so you'd think the world doesn't need another framework, and least at all by yours truly. That's what I thought too, untill I stumbled upon a rather simple problem. Currently I develop a Qt application that runs in the background (call it demon, service, headless, etc.) and would like to have an admin interface for it. Of course I could write a standalone GUI client connecting to the application's command socket but that's so nineties! Only a web interface is fashionable these days. Thus I need a small webapp for the admin console.

So at first then, I thought I'd use some open source code from the above list. But all of them would either not integrate well with Qt events, or require 3rd party includes and dependencies, and gwan would even have to be started as an external server! Well, I didn't use gwan before and it does sound like a border case usage for it, just imagine all that debugging of its servlet compiler in run-time...

Then you may ask: isn't there any HTTP server in the Qt framework? Yes indeed, I found one, but it's an extension of the framework (they call it an option I think...) and it's running as Windows service, not as an additional interface to an existing binary. So we've got the same case as with gwan. BTW, why hasn't C++ a standard HTTP server class? Go has one, Python has one, Javascript has one, but C++ - nope! Well, that's not completely true, CINDER framework has one, and cpp-netlib got one as well, but I wanted to avoid big includes and dependencies like Boost.

But hey, Qt has a couple of HTTP support classes, so I thought: boy, that cannot be that hard! And I just hacked my own mini HTTP server.

2. The design

Of course that gives me an opportunity to design a web framework the way it should be always designed at last :-), because all the others seem to be somehow overcomplex or overcomplicated :-). So let's go down to the brass tacks then!

First we have to decide on the name - let simply try YAWF(4q), and in best software giant tradition I'll use an internal codename, for example "CutieW".

The design will be simple, plain and oldskool, as I need something working and that fast. Besides, never underestimate the power of KISS!

The basic ingredients are the Qt classes for TCP socket handling and HTTP request and response parsing. Then we'll have request handler objects with a process() method. The handler objects (kind of servlets for the Java minded) will have to be derived from a superclass (how uncool, I know) and statically instatiated, so that they can register themself with the server in the startup phase. They register with a name string**, for example "user" or "page", so they can be bound to an URI (see below for the example).

Let's sum it up: there will be a server executable, it will set the URL path configuration in startup phase, each path wil get its own handler. When a request arrives, a fresh instance of the handler will be created, this the handler classes need a clone() method for this.

The server will thus find the matching handler prototype for the URI, clone it, and then invoke its process() method. As you see, there's 1 to 1 relation betweem URI and the handler object in the current implementation, but an extension to "multiple dispatch" isn't difficult, and I'll program it when I have some spare time.

Now to the general usage pattern of YAWF4q. In Clojure you'd write the following:

  (defn display []
(html [:h1 "hello!"]))

(defroutes myroutes
(GET "/" [] (display)))

(defonce server (run-jetty #'myroutes
{:join? false
:port 8080}))
In cpp-netlib this:
  struct hello_world {
void operator()(server::request const &request,
server::response &response) {
// your code here ...
}
} handler;
  server server_(argv[1], argv[2], handler);
server_.run();
But in yawf4q it's all pretty plain, non-clever, and almost boring:
  #include "CuteHttpServer.hpp" // the cutie

int main(int argc, char* argv[])
{
// your application:
QApplication* qtAppl = new QApplication(argc, argv);

// the webserver on port 3100
ibkrj::yawf4q::CuteHttpServer testServer(3100);
string error;

if(!testServer.start(error))
return -1;

// run Qt
qtAppl->exec();
}
The server just starts, finds the config file (using a default, hardcoded name), sets the routes, and waits for requests. If you don't define any handlers, a simple "I'm alive" response is sent back.

3. The example


How to write your handlers? Look, you have to derive them from the TestHandlerBase class. First let us implement the handler of the index page:
  class TestHandlerBase
: public MiniHttpHandler
{
public:
TestHandlerBase()
: MiniHttpHandler("TestHandlerBase") {};
// base overrides
virtual MiniHttpHandler* clone() { return new TestHandlerBase; }
virtual void process(AnalyzerRequest& reqData, std::string& respData);
} g_handler1;
OK that's rather much boilerplate, as we need to supply the name string plus the clone() and process() methods, so maybe I should provide a macro like this:
  // --- OR maybe a MACRO?:
class TestHandlerBase
: public MiniHttpHandler
{
public:
BASE_TEST_HANDLER_FUNC(TestHandlerBase)

... your functions ...
} g_xxx;
I don't know, as a matter of fact I hate macros in frameworks! But as an alternative maybe it isn't that bad. Another possibility would be using CRTP, as to automatically add the clone() method, but wouldn't you say this would be somehow too clever when compared with the rest of the design?

And here is the processing method:
  void TestHandlerBase::process(AnalyzerRequest& reqData, std::string& respData)
{
respData = " TestHandlerBase alive!!!! ";

respData =
"<html><head>"
"<title>TestHandlerBase is alive!</title>"
"</head><body>"
;

respData.append("<h1> Input your user data: </h1><p></p>");
respData.append(testform); // HTTP form for UserName, UserMail and Text, action="person"

respData += "</body></html>";
}
OK this doesn't look very cool, but the view component isn't yet there, wait a little. What this handler does is to ask for some user data. Now the second handler follows, which will processes the submitted user data:
  class TestHandlerPerson
: public MiniHttpHandler
{
public:
BASE_TEST_HANDLER_FUNC(TestHandlerPerson); // here process() is already defined

} g_handler2;

///////////// impl:
void TestHandlerPerson::process(AnalyzerRequest& reqData, std::string& respData)
{
respData =
"<html><head>"
"<title>TestHandlerBase is alive!</title>"
"</head><body>"
;

respData.append("<h2> Thank you for your data! </h2>");

// parse the data for display:
map<string,string>& data = reqData.formularData;
map<string,string>::iterator iter;

respData.append(
"<table border=\"1\" width=\"70%\"><tr>"
        "<th><b>Field</b></th><th><b>Value</b></th>"
"</tr>"
);

for(iter = data.begin(); iter != data.end(); iter )
{
respData.append("<tr><td>").append(iter->first).append("</td>");
respData.append("<td>").append(iter->second).append("</td></tr>");
}

respData.append("</table>");
respData.append("<p></p> <a href=\"/index.html\">Back</a><br>");

respData += "</body></html>";
}

Rather grotty servlet or .jsp style here, isn't it? Mixing presentation with code?!

Don't despair, you can use a template. Yes, let's be modern! I chose the mustache :{{ template syntax. I decided for mustache, well, because it's pretty new, generates much buzz, and isn't looking too bad. For those who don't know mustache, it is a simple HTML templating syntax with values encoded like this:

  {{value}}
and sections, which can be rendered multiple times, if they receive a list as input data:
  {{#section_X}}
{{value1}} => {{value2}}
{{/section_X}}
So there's no need to code anly loops in the template. YAWF contains an implementation of mustache :{{, which seems to render correctly all the examples I found in the online mustache docs. The implementation is based on a simple idea: the template is parsed into a linear sequence of "nodes", and the data items passed to the template take care of rendering and walking the node list. Have a look at the source code*** if you want.

So our response handler would now look like this:
  // using templating:
#include "CuteMstchData.hpp"
void TestHandlerPerson::process(CuteSrvRequest& reqData, std::string& respData)
{
string templ =
"<html><head><title>TestHandlerBase is alive!</title>"
"</head> <body> <h2> Thank you for your data! </h2>"
"<table border=\"1\" width=\"70%\">"
"<tr><th><b>Field</b></th> <th><b>Value</b></th></tr>"
"{{#datatable}}"
"<tr><td> {{field}} </td> <td> {{value}} </td></tr>"
"{{/datatable}}"
"</table><p></p>"
"<a href=\"/index.html\">Back</a><br>"
"</body></html>";


// convert data to JSON represenation:
map<string,string>& inpData = reqData.formularData;
map<string,string>::iterator iter;
int i;
ibkrj::yawf4q::CuteMstchValMap templData;

for(iter = inpData.begin(), i = 0; iter != inpData.end(); iter++, i++)
{
templData.addToList("datatable", i, "field", iter->first);
templData.addToList("datatable", i, "value", iter->second);
}

// display page with data (the View of MVC)
respData = CuteHttpHandler::renderThis(templData, templ);
}
It maybe doesn't look much better than the plain HTML code, but here we could save the template in file, and read it in at the runtime. And we've got the View part of the MVC pattern. The handler objects stand for "C", but so far don't have support for "M" in YAWF4q.

Now, as last part of the puzzle, we have to configure the server paths, but this is simple:
#
# test configuration
#

index.html$ :: TestHandlerBase
person/.*$ :: TestHandlerPerson

You see, regular expressions are supported. Now let it run baby! The first handler gives us:


















Then we willingly give our data:



















And see the results:













4. Summing up

At the moment the code*** is only very basic, as I haven't got time to work on it a much as I'd like. I wrote it on my private time, as my customer did decide in favor of a general, grand-scheme, system management solution. So as for today, I wrote only a single test, that one which was described above, and tested it with Visual C++ on Windows. YAWF isn't more than a toy just now as many features are simply missing, for example I'd like to have a built in support for configurable error pages to round the things off. And as next thing, I'd like to add the Model component using my CuteWorkers framework (I hope I'll come to write a post about Qt-workers too).

But there's much more that could done, like:

- HTTPS support in the sever (that shouldn't be very difficult as Qt offers QSslSocket and other classes)
- cookies and session data handling
- dynamic loading and caching of the templates
- dynamic loading of the servelts vial DLL (kind of what ASP is doing)
- a "Clojure example" like dynamic interface

and so on, and so on. Look at my TODO list in the github repository. Nonetheless it's simple (KISS!), it's pluggable, it doesn't have any dependecies other than Qt. Requirements fullfilled!

--
* check out these previous posts: servlets-in-c.html, c-servlets-again.html, c-server-pages.html

** we cannot forget that C++ hasn't much to offer in terms of introspection. But we won't give up automatic registration and detection of handler prototypes!

*** You can find the code at Github: https://github.com/mrkkrj/yawf4q


Saturday, 13 November 2010

Engineering Decency


A couple of days ago I was quite unpleasantly touched by a tweet (a Twitter tweet :-) of a so called "expert" (you know, one the people doing only presentations and learning new languages to write their next book...) ridiculing a developer about a failed project. Somehow I didn't like that - come on, the guys just tried to capitalize on a promise Google (yes, that big engineering powerhouse) made! And they were not alone...

What is that, that the programmers find it so hard to show some engineering decency? I've seen it again and again. Is it so much fun* to flame someone to feel better? The experts should know best that doing stuff mean means making mistakes. Or maybe have they forgotten how it is to be working with real stuff instead of powerpoint metadata?

If you are skiing difficult terrain, you know that the question isn't if you will fall, the question is when you will. That's the same in software - you don't want to believe this now (and me neither) but you will make (sometimes stupid) mistakes! So please, show a little decency. The guys you are going to deride probably just tried to create a working system for a given set of requirements which then turned out to be largely false and for a specific platform, which then emerged to be broken. We've all been there.

And because it's difficult and needs to be learnt, I have an example of how to exercise engineering decency (found here). Instead of the usual:
What idiot with even half a handful of moldy cottage cheese for brains would ever create a pile of stinking filth like this and call it an application?! The true feat of engineering here is that this code monster didn't swallow your whole organization in the black hole of its utter lameness. Where did this person learn programming — NBC?”
Try saying that:
“This will take me longer than we had discussed. In my initial examination of the system, I missed some design decisions in the existing code that conflict directly with what we need to accomplish. I didn't anticipate the approach adopted by earlier developers, because I would not have designed it that way myself. I’m sure they had their reasons for choosing that direction, but so far those reasons have eluded me.”
That's decency, that's humility. Maybe there's a reason you just don't see now. But even if that's really a load of crap, frankly, who of us can say he never ever wrote bad code (or a bad powerpoint presentation for that reason)?

--
* well, if we'd like to get Freudian, we could say that the unconscious fear of doing some big, stupid mistake reveals itself by attacking others, and that we can maybe reason from that, that the majority of programmers are not well trained for their job. But that would be only a mere speculation to discuss with friends on a lazy evening...

Monday, 16 August 2010

Named function arguments for C++

For me a high quality code is a readable one. Consider a hypothetical method like this:
  class XXX:
{
public:
void func(int aaa, string bbb, bool optionX = true);
...
};
now try to call it:
  func(1, "test", true);
What irritates me here is, that I don't know what exactly does true mean at the first glance! Thus I found myself quite often writting code like this:
  bool useOptionX = true;
func(1, "test", useOptionX);
Well, that's better, but what about this:
  bool useOptionX = false;
func(1, "test", useOptionX); // should I use it or not?
a little bit misleading, isn't it? Not that this would be a big problem, but it's nevertheless a small hitch obstructing us from reading the code effortlesly. OK, next try:
  bool dontUseOptionX = false;
func(1, "test", dontUseOptionX ); // don't use is false, so I should use it?
A total mess! And what about constructors?
  class XXX:
{
public:
XXXX(bool optionY);
...
};
  class YYY: public XXX
{
public:
YYY() : XXX(true) {}; // true what???
...
};
Call me pedantic, but I don't like that at all! What we really need here are Python's named arguments:
  sameFuncInPython(aaa=1, bbb="pythonistas", optionX=True)
Simple, effective, readable! Is there a way to emulate this in C++? Recently, as I was especially annoyed with the constructor example from above, I devised a following solution:
  class XXX:
{
public:
XXXX(bool optionY);
...
typedef useOptionY bool;
};
  class YYY: public XXX
{
public:
YYY() : XXX(useOptionY(true)) {};
...
};
and now the other code can be wtritten totally plausibly too:
  typedef bool useOptionX; // local namespace!
  func(1, "test", useOptionX(false));
func(1, "test", useOptionX(false));
and what would you say to the following?
  waitOnSocket(sec(1), usec(20));

Small thing, but it improves my source code. I like it!

---
PS: After I wrote this, I remembered reading something in this vein about Java. And really, this post http://codemonkeyism.com/never-never-never-use-string-in-java-or-at-least-less-often/ by Codemokeyism proposes generally the same solution:

  new Customer(firstName("Stephan"), name("Schmidt")); 
Alas, instead of a benign typedef, you have to write a whole new class named name and firstName etc. Without doubt it's and improvement, but the costs and the clutter... But on the other side Java tends to be verbose nonetheless, so maybe it's OK.