Mind the gap…


MIND THE GAP BETWEEN THE TRAIN AND THE PLATFORM. Well known for the people living in London.

In case of programming there is also one important gap that you should be aware of.

Can I write programs, daddy?

Programmers in the beginning are being taught methods of programming that are at first little invasive. Anyway, that’s one of problems when trying to start learning programming techniques with low level languages. This is not usually, but always a very bad idea. Because of that it’s usually a bad idea to start learning from C language.

Although I haven’t so far found a programming language that could be used as a first language, just to teach programming. From my point of view, the first language should be imperative (because it’s easier to imagine that a computer just executes commands), well structured (with clean syntax), should be expression-based (because the majority of languages in future use will be), shouldn’t contain any weird syntax features, and shouldn’t have any nasty tricks that the programmer needs to remember. All these rules deprecate the following languages, in order: ML clones, Pascal, Tcl, Python and Perl. Languages like C, C++, C#, Java (and other similar) are excluded from potential candidates even earlier.

Probably the only suitable language will be Visual Basic. Well, since some time I can see that BASIC or some of its mutation (featuring structural statements, procedures with local variables – that is, everything that is meant basic in every today imperative programming language) is the only language that may suit for learning programming basics. But even BASIC may contain one of very dangerous features, that is, the GOTO instruction.

Of course, especially for making an “educational” language we may make some special version of such a language that is castrated of this instruction (although there are other languages that do not have “GOTO”, for example Java and Tcl). But such a language should at least contain enough statements so that the use of such instruction is not necessary at all.

If we don’t have such a language, we should use some other, used in “real world”, but important thing is to teach to programmers important rules that strongly limit the use of language’s features. Because in the first time they would really hurt themselves.

I’m growing!

It’s very good if you are trying to experiment. That’s the best way to learn a language and programming in general. It’s getting worse, though, if you are getting too far with this experimenting and forget that you’re drowning in the pleasure of experimenting and getting farther and farther from the common sense.

The problem is, though, that this getting too far starts earlier than most of the people think. For example, many people think that overloading operators is a feature that should be prohibited by organization’s rule set. Because allowing for that will expose a field for making crazy things. I have never found in practice that this be a problem. In practice, it’s C programmers or “they want me to write C++ but I hate it” programmers, who are the source of majority of problems with obfuscated code in C++ projects.

Experimenting should be a way to make you wiser. Experimenting shall not be focused only on testing language capabilities, but also on checking whether particular kind of language features, especially used some particular way, can be used in real programming. That is, for example, whether you understand what’s going on there when you next look into this code. Whether adding new things to the code will be easier.

The gap

You can compare experimenting with a toy. You can have a toy train and play with it. When you pack some artificial people into the train’s car, it’s not a big problem that some of them will stuck a leg in the gap between the train and the platform. If you repeat the same with a real man, real train and real platform, you’ll quickly find out that falling into the real gap really hurts. So, the toy can be used to prevent unnecessary hurting, but the fact that it doesn’t hurt may be a reason that the prospective programmer won’t learn anything.

During experimenting with programming you can find a lot of various interesting solutions that can be useful… but need not. For various weird solutions you should take special care.

Operators overloading, for example, is one of the places where you should take special care. I even think that this technique is so rarely used in real programming because people are worrying whether this solution is designed well enough. The problem isn’t with the operators, but rather whether the API, that is designed with the use of operators, will be comfortable API. If you look at that from this perspective, you can quickly find out that it’s not operators that cause problems, but problem is to well design API. There’s a lot of APIs in many libraries, which are very badly designed – and they don’t need operators to be badly designed, it’s enough that they use functions and variables stupid way.

What can be a cause of incorrectly overloaded operators? Let’s take a signal-slot mechanism (called ‘delegates’ and ‘events’) in C#. There are used “+=” operator to connect a signal and “-=” operator to disconnect it (specifying the slot in both cases). The problem is that you practically cannot express the “connect” operation by using any operator – this “+=” is only a best possible wish to do it. And even though it would be good to specify adding numbers, also to append a string to another string, also even good to add new elements to the vector – “connect” is something that doesn’t have a logical explanation that can be interpolated to use “+=” symbol! This idea was definitely stupid, and even creators of Vala language, which was strongly based on C#, have realized that. Even though at first they repeated the “+=” statement for connecting signals, they now changed this to “connect” (as a method call) and made “+=/-=” API deprecated.

One of the problem is that “x += a” expression speaks “append ‘a’ to ‘x'”. Connecting a signal to a slot isn’t anything that is even close. Even though there is any appending, it’s only an implementation detail, so it shouldn’t be even exposed. The problem is that connection is a kind of registration – it means that this registration causes that a new “node” has been created and we get a reference to this node. This reference can be later used to disconnect this slot from the signal.

And here is another problem, with the “-=” operator. In order to make this API possible, a slot should be searched for and compared with each one element among the slots connected to given signal and only then once found it can be disconnected. This operation may also end up (potentially) with search failure and some way to handle it should be predicted. While it’s much easier and faster to just get the reference to the node where particular slot is saved in signal’s data and remove this node. But in this case we need something that will be a result of “connect” command and we can save it and later pass as an argument for “disconnect”.

This is one method. Another method is to make “slot” not a single function (or binder), but a real “slot object”, which also contains additional data, among others also a list of signals to which this slot is connected. As single disconnecting is rather a rare case and usually disconnecting happens when the receiver object needs to be destroyed, an alternative implementation is to store both signal data in the slot and slot data in the signal. This way a slot may simply disconnect itself from everything it is connected to, as well as there’s no need to save the reference to the node anywhere (it needs a term of destructor in a language, so it can’t be done this way in C#).

The problem with += and -= operators used for signals, then, is not the problem of using operators where functions should be used, but using inappropriately designed API. An opposite example, the “<<” operators used in C++’s iostream is, although far from bit shifting, both correctly suggestive and well matching the needs of API design.

But operator overloading is not the only thing that may look dangerous – moreover, they are relatively safe comparing to, for example, GOTO  instruction, as I have already mentioned at BASIC. There’s always someone who would like to use it the following way:

a:
while ( some condition )
{
    if ( something )
        goto b;
    ...
}

b:
while ( some condition )
{
     if ( something )
         goto a;
     ...
}

This stupid thing is even possible in Java, which is theoretically voided of this dangerous “goto”.

It’s merely the same thing with so-called “Singletons” used in Java. As I have already mentioned elsewhere, Singleton in Java is just nothing else than a global variable. Usually when you don’t know how to organize data sharing, the solution is simple – create a global variable. Well, theoretically global variable is just unlimited access to some shared data. Practically a global variable is the best way to shadow any true intentions standing for the written code and contribute to more bugs in the software because of not full ruling over what’s going on in the program.

A programmer must do the first hurt to themself to get the experience that this is a really bad way of programming.

A car that drives the driver

It’s used to say that during learning car driving the student should focus on that they drive a car, not a car drive them. This problem seems to happen sometimes to programmers, too.

In particular, programs seem to live their own life, on which the programmer has little influence. It sounds silly, but how can we describe other way a situation, when the program went out of control? Of course, nothing wrong can happen when the program isn’t running, but programs are not being written in order to be printed on a paper and hung on a wall, but in order to be run and work.

A programmer, who is experimenting with new, wonderful methods of programming, may forget to stop, when they’re getting close to the edge of the platform, and forget to check if the train is there.

A good way to verify the real results of programming is just to stop developing some code at some point, leave it for, say, one month, then return to this code and try to continue the development work. Even one month is enough time to forget what was on your mind when you wanted to write this. If the time is longer, and in the meanwhile you were trying to do any other development work, returning to this code may result in something like: Well, who the hell wrote it? How drunk had I been when I was writing it? Why the code is written as if the author would like to make the reader’s life harder?

It’s worth that you make this kind of tests before you approach to real programming. You can also have someone else to participate in this (or even interchange with the code written). This will also help you realize that if you later can see some idiotic code, you will remember this: this idiot might have been you. Experience like that may help you see “the gap”.

Call me nobody

Nobody is perfect, of course, but programming is, like any other advanced engineering domain, a “not for children” thing. Falling into “the gap” may cause harm not only to those, who write crazy code, but also to the people in the company where the code is being developed. Minding the gap is sometimes more important than finding the right solution. Creativeness is like a speed you can achieve in running through the underground station, but remember, there’s no barrier at the edge of the platform, where the train can be sometimes found. And the train doesn’t perfectly stick to the platform. By running too fast you can easily get stuck into it.

Generally, I would say that the language rules, good practices, various constrains etc. is not created to replace thinking, but at most to decrease the meaning of thinking in programming reliability. In other words, these rules exist in order to minimize the size of the gap. But the gap cannot be zero size. I think it’s obvious that the gap may be zero size only in case when the train is strictly bound to the platform. But it’s rather unlikely that such a train be able to go anywhere.

The best gap

Simple thinking about various engineering domains is that there are some perfect conditions, which are only theoretically defined, and rather cannot be achieved. This may be a case of a perfect gas definition in physics. Such a gas does not exist because the gas consists of particles, as any other thing, and these particles would have to be zero size in order that the gas be perfect. But this is something that is just physically not achievable; usually we think about perfection as something that we always want.

In programming, and also in many other engineering domains there are lots of cases when we can define perfect cases, but, well, perfection isn’t what we want. One of the cases is that the communication between two threads is decreased to none in perfect situation. This is because only in this case every thread can freely work only on their task and isn’t blocked by anything else. But this is a perfection that we don’t want to achieve because if we do then there’s no need for these two threads to be in one process, as there are no communication between them. This is, again, a gap, that we want that it be as small as possible, but if there’s no gap – the train will be one with the platform.

In practice there are lots of similar cases for that – which isn’t wondering as in every engineering domain there’s always a battle of various factors and finding a balance is one of the most important things that engineers do. The role of an engineer isn’t to find a biggest gap (because the passengers wouldn’t be able to enter the train) nor the smallest gap (because the train wouldn’t be able to move along the platform). The role of an engineer is to find the best gap.

There’s no point in explaining what the best gap is. If you are engineer, you know it well enough. Just remember, when you’re ready with this, that there are always people, who will put a leg into even the best gap. That’s another factor that can mess in this… 🙂

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s