Friday, October 25, 2013

Legal system for software developers.

Hello there. You as geeky software developer want to know the philosophy behind legal system? Let me explain it all to you.

To make it easier let's say that menacing Code of Laws is simply "code". Code is logic expressed formally. Suppose certain borrower refuses to return money to the lender. We as society need a set of formal rules that let us resolve the conflict. Just like our software needs code to resolve conflict if certain image is too big for its page. Sure enough there are many variations in each case.

Depending on your location your local laws may represent a codebase with pieces from 500 years ago and layers of patches on top of it. As developer you know how much misery can be brought by 20 years old software that can not be replaced. Here we talk almost 2 orders of magnitude more.

Such code is mission critical contributing to fear of change and especially fear of removal. You'd rather have 30 corner cases than one generalization. You'd rather keep obsolete pieces just in case.
And sure enough there are many cross-references and inter-dependencies all over the code.

The lawmakers are like legacy system developers while practicing lawyers are administrators in the field. The administrators know all the quirks and hacks of the system, are aware of inner workings that could drive simple people mad. Developers hate the current state of the system, have vague memories of the rationale behind part of the system and once hoped to change it for the best. Sure enough some developers are ready to put a backdoor into the system if the pay is right. I believe that while some of the law-makers are lazy or evil most of them are not, at least on the West. They are simply shocked by the pile of legacy rules. Remember the first time you as developer were asked to maintain a module in a 10-million-lines of code project and realized that your module affects 20% of the entire system?

Voters give power to law-makers in hopes for greater human friendliness and greater efficiency of the system. Usually such hopes are not fulfilled. Customers that pay for legacy software upgrades are rarely fully satisfied.

Software administrators are often seen as people who do no real job and get too much easy money, same applies to lawyers. The legal agreements are similar to scripts written by administrators, ugly, seems to work, may have side effects and you can't work and live without them.

Usually no one is guilty. Nor the lawyer, nor your candidate, nor you administrator, nor the programmer. That's how the world works. It's a consequence of incredible complexity of the task system aims to achieve. It takes a genius to improve such a system.

Please leave your thoughts in a comment.

Wednesday, May 29, 2013

C++11: copy and decorate idiom

I love to generalize. Some would say "over-generalize". For example if you ask me: "What is Query Language?" I will answer: "A way to create predicates from textual data at runtime". I know, over-generalizations are bad.

Recently I looked at the GOTW#4 solution. To my shame I did not know why and how operator + should be implemented in terms of operator+=. However (once I understood it) I really like the guideline: "Prefer passing a read-only parameter by value if you’re going to make a copy of the parameter anyway, because it enables move from rvalue arguments." In fact I liked it so much that I call it "Copy and Decorate" idiom. I think it is a nice mnemonic that helps remember this guideline. In my mind it connects well with "copy and swap". You take your argument by value to get a copy of it, you decorate it, you return it. Simple.

Let's look at example often shown to show why C++11 is normally a better language than pure C.
 string compose(const string& name, const string& domain)
 {
  return name+’@’+domain;
 }
This example is a pure win compared to C solution that allocates memory and copies bytes in funny ways. It was used by Prof. Stroustrup himself in a recent interview. It can also be used to illustrate Copy and Decorate idiom:
 string compose(string name, const string& domain)
 {
  name+=’@’;
  name+=domain;
  return name;
 }

Name is copied anyway so the copy with passing it by value. Or by move. But I doubt that symbolic performance gain is worth the damage to readability. But there is more to it. This example can also be used to show the kind of tricks one may use in attempts to improve performance:
 string compose(string name, const string& domain)
 {
  name.reserve(name.size()+domain.size()+1);
  name+=’@’;
  name+=domain;
  return name;
 }

Here reserve is used to hint how much memory should be allocated. Also the function is already almost as long and as confusing as C alternative. The only difference is that in C++ error in estimation of the required size leads to poor performance, in C such miscalculation leads to memory corruption and crashes.
P.S: blogger WYSIWYG editor is horrible at formatting code. WYG is actually not WYS.

Wednesday, July 18, 2012

Comments

Consider the following code:

//Increment data count here
dataCount++;

The developer responsible for this legacy code heard that comments are good. What he was not aware of is DRY (Don't Repeat Yourself) principle. It is obvious what the code does. What is not obvious is why it is incremented here and not at the end of the function. I'd like to know why it is incremented unconditionally. As maintenance developer I'd like to see variable name that clarifies what kind of data it counts. Unfortunately there is no comment to help me.

Sunday, July 15, 2012

Phunction names.

Somewhere in code there was a function named "abtain_list_lock", That's right, with "a". A few years ago a rather large group of developers branched out from main version to work on a another set of special awesome features. The developers working on side branch quickly renamed the function to "obtain_list_lock" and continued working. Over the next three years much work done; lots of new functions that obtain list locks were written. It was time for a merge between branches and resulting version included awesome new features from both branches. It also included both "abtain_list_lock" and "obtain_list_lock" having the same function body. One day this will be fixed, but not today.

Why?
1. Developers do not read function and variable names carefully, IDE allows code navigation without reading function names.
2. Developers on side branch expected that the typo on main branch will be fixed by the next person who uses that function, extrapolating own quality standards on others. It also highlights some bureaucracy in branch ownership and commit policies in larger software corporations.
3. C language allows implicit function declarations. Many users of "abtain" did not include the relevant header file where function is declared. Thus removal of function with typo led to errors while linking, not during compilation. Due to complicated custom build system such errors did not show verbose error messages by default. A simple preprocessor macro in header file wouldn't be enough to make it link.
4. The merge was done in haste. People were under pressure to release product that contains all features from both branches as soon as possible.

Wednesday, June 13, 2012

Software maintenance and selection bias

As maintenance developer you often look at old code. And old code is ugly. If you think that all old code is ugly you are wrong. Good old code simply does not need your attention. Don't let selection bias influence your overall opinion on company code..

Wednesday, March 14, 2012

Rotational matrix as an example of Data Driven Design.

Every self respecting linear algebra teach causes students to hate matrices. If you can't you are not qualified. Only now, after three years without formal study of matrices, I learned to appreciate them.

I made a small computer graphics project at school. I had a separate function for X axis rotation, separate function for Y axis rotation, Z rotation and XYZ scaling were separate function, so was XYZ translation. My teacher told me to use matrices but I simply could not understand why it is better. I mean, matrices are creepy and functions are simple. Rotation around arbitrary axis was a bit cheaty (and buggy); this is fine for a small project though.

Now I understand the beauty of matrices. Now I see what is wrong with transformations stored as list of function objects. 8 years ago I was too young to understand the value of simple matrix that replaces arbitrarily long list of functions with parameters.

My friend recently showed me a piece of code from his hobby project. The code was full of conditional and switch cases. After little thought we realized that confusing branching in code can be replaced with a single matrix. It was the most satisfying change I ever made in code.

Saturday, February 25, 2012

The value of well placed goto.

Some legacy programming languages do not support nor destructors nor exceptions. You must carefully check the returned error codes in case of error you must carefully free all resources. Often this leads to code like this:
error_code =some_func(some_params);
if (error_code!=NOERROR) {
  goto cleanup;
}
error_code =other_func(some_params);
if (error_code!=NOERROR) {
  goto cleanup;
}
error_code =yetanother_func(some_params);
if (error_code!=NOERROR) {
  goto cleanup;
}
//... More code here


There is much code like this. At some point a well-intentioned developer who heard that goto is evil changed the code to look like this:
do {
  error_code =some_func(some_params);
  if (error_code!=NOERROR) {
    break;
  }
  error_code =other_func(some_params);
  if (error_code!=NOERROR) {
    break;
  }
  error_code =yetanother_func(some_params);
  if (error_code!=NOERROR) {
    break;
  }
  //... More code here
} while (0);


In my opinion the do-break-while(0) is much uglier and harder to read than goto.
1. Here break is just a goto in disguise.
2. If you see the beginning but not the end you think there is a loop here.
3. In original version goto is used to control the flow in exceptional cases. Goto does not change the structure of the code under non-exceptional scenario.

What do you think?