Tag: software engineering

Our Fathers’ Faults – Akktors and Ekkstras

After the first four posts of “Our Fathers’ Faults” it’s time to turn a specific aspect of the application – the Akka framework. The code I’m managing is strongly based on this framework offering endless inspiration for misuse and abuse. Before going straight to the sins parade, I think it is proper a brief introduction to the Akka framework actors and their usage. Half of my two readers are ludicrously proficient in Akka and Scala that they might think of skipping this post wouldn’t it be for my witty ranting prose style, the rest of you two may actually be interested in the content as well.

BTW, actors, as most innovations in programming, are no longer that innovative. The actor model dates back to 1973 (geez, I was 5! I couldn’t even spell “actor”!), but it has been largely popularized by the reactive manifesto as a viable model for reliable concurrent programming.

Continue reading “Our Fathers’ Faults – Akktors and Ekkstras”

Our Fathers’ Faults – Scantly Typed Language

Scala tries to help the programmer in many ways. Verbose and repetitive code can be often syntactic-sugarized into concise statements. This is very convenient but encourages the programmer to produce write-only code. Let’s talk about types. In many contexts, you can is very good at inferring types. Consider

val n = 1

This Is the most obvious case, you don’t need to specify Int because the language manages to infer the type of the variable from the type of the expression to the right of the equal sign.

Continue reading “Our Fathers’ Faults – Scantly Typed Language”

Our Fathers’ Faults – The Chain of Death

The functional programming core concept is about composing functions together to craft more complex and convoluted functions. In Scala (not unlike what happens in many other programming languages) there are two ways to combine functions: the first is to apply a function to the result value of another function and the latter is to use a function to produce the argument value of another function.

Written in this way they may look not so different, in fact, even if in practice they show up in quite a different look, the abuse of the mechanism leads to the same problem.
The first way of combining functions, is also called chaining since you chain functions together – the result of function fn is the input of function fn+1. (Interestigly this very same mechanism will get a boost in C++ starting from C++20 ISO standard thanks to range and pipes).

Take the following example:

List(1,2,3,4).filter( _ > 2 ).map( _.toString ).fold( "" )( _ + _ )

(If you already know Scala, you may safely skip this paragraph 🙂 ) If you are unfamiliar with Scala or function programming this may look suspiciously like bad code, (this could be some meat for another post), but trust me it is not. Function List(…) constructs a List. List, containers, and iterators in general in Scala have a set of methods that can be chained together. You may think of them as taking an iterator and producing an iterator in a different sequence. Back to the example above, filter produces an iterator that scans only elements of the input sequence that fulfill the given condition (being greater than 2 in the example). map produces an iterator over a sequence whose elements are computed by the given function on the source elements. Eventually fold collapses the sequence by accumulating items iteratively using the provided expression.

Each small block performs an operation. Note that I haven’t written “simple” operation, on purpose. In fact the operator (filter, map, fold) is simple in itself, but it is programmable via a lambda that can be as convoluted as you want. Therfore the operation performed by the block may become really complex.

While you are focused on your goal, it may be easy and convenient to dump your mind into an endless chain. This has two drawbacks, first, it is unreadable and second, it is uninspectable.

It is unreadable because you need to start from the beginning and analyze the sequence up to the point to where you want to focus and know what the inputs are and from there onward to understand how the output is processed into the final result. Pair this with complex lambdas and you may find yourself in quite a nightmare to figure out what this code is supposed to do or where is the bug.

It is uninspectable because you cannot use the debugger to stop execution and show intermediate results of your operation (I’ve noticed over the years that Scala programmers are usually reluctant in using a debugger preferring print/log debug).

The other form of the problem – functions calling functions calling functions – despite the differences in syntax, is not that different in how it is produced and in the result. The code you may see, such as –

context.become(
    enqueuer(
        resourceManagement(
            Queues( queues.execution.filterNot( x =>
                ( x == realFree || context.child( childName( x.getUUID ) ).isEmpty ) ), queues.waiting ) ) ), true )

can be written in any language, but it seems that our fathers was quite fond of this approach.

It is important to recognize that when writing code you have (or, at least you should have) a crystal clear and detailed comprehension of the data flow, and even if you strive to write clear code, you’ll tend to pack these things together because a) it is faster (less typing, less naming of values, less effort to add structure) and b) you don’t feel the need to make it clearer since it is so straightforward in your head.

Lesson learned – resist the temptation of dumping the mental flow into a coded data flow, use the old “divide et impera” to split the flow into manageable units with names reflecting the content e the intent. A good indication is the line length, if your statement, properly formatted to fit in 80 columns, happens to span over more than 3 lines, then splitting it is a good idea.

Additional thought Attending some FP conferences I had the clear impression that FP pundits encourage complex aggregation of functions, even the justification for having short indent space (2 characters is the recommended indentation for Scala) has the purpouse of make the writing of chains more convenient. For these reasons I suspect that this point could be a little controversial in FP circles. I stay with my idea that industrial quality code must be first easy to read and understand and then easy to write.

Our Fathers’ Faults – Operator @!#

With a Great Power comes Great Responsibility. I’m referring to the incredible power of defining custom operators as function names. I was convinced that this feature was introduced by C++, but a quick look on Wikipedia was enough to dispell this myth. Starting from Algol 68, programmers were enabled to redefine operators. Not all languages have this feature and even those who do vary in what the programmer can do.

Continue reading “Our Fathers’ Faults – Operator @!#”

Our Fathers’ Faults – Failure is not an Option

Our Fathers’ faults.

Intelligent people learn from their mistakes, wise people learn from other’s mistake. Unlucky people learn from the mess they have to fix in someone else’s code.

Working as a programmer is not always an easy task. On lucky days you feel like a god planning and designing architectures, wisely crafting virtual nuts, cogs, and bolts that happily tick together in an elegant and coordinated choreography, while on bad days it is bug fixing in your code. In really sh**ty days it is bug hunting in code written (by a long-gone someone else) for exploration, demo, and test of the coolness factor.

Continue reading “Our Fathers’ Faults – Failure is not an Option”

Protecting you from danger

One of the interesting features of Scala is the trait construct. In Java you have interfaces, a stripped down class that lets you express the requirements for classes that implement it to have a given … interface. Just to keep this from an OO perspective – in a certain system all MovableObjects, must expose an interface to retrieve, say, position, speed and acceleration:

interface MovableObject {
    Point getPosition();
    Vector getSpeed();
    Vector getAcceleration();
}

class Rocket implements MovableObject {
    public Point getPosition() {
        return m_position;
    }

    public Vector getSpeed() {
        return m_speed;
    }

    public Vector getAcceleration() {
        return m_acceleration;
    }
    private Point m_position;
    private Vector m_speed;
    private Vector m_acceleration;
}

In Java the interface has no implementation part, just a list of methods that heir(s) must implement. This is a way to mitigate the lack of multiple inheritance in the Java language – a class can inherit at most from a single base class, but can implement as many interfaces as needed.

Scala traits are different in the sense they can provide an implementation part and fields. Now that I read the wikipedia definition, it looks like that traits are a bit more mathematically sound than interfaces (that’s what you can expect in functional language). Anyway, in plain English, traits are very close to C++ base classes (with some additions that is stuff for another blog post) in the sense that you can both require interface and provide common functionality.

Continue reading “Protecting you from danger”

Ugly Code

Unfortunately, I’m a sort of a purist when it comes to coding. Code that is not properly indented, global and local scopes garbled up, obscure naming, counter-intuitive interfaces… all conjure against my ability to read a source and causes a headache, acid stomach, and buboes. “Unfortunately,” I wrote, meaning that’s most unfortunate for the poor souls that have to work with me to whom I should appear as sort of source code Taliban.

Recently my unholy-code-alarm triggered when a colleague – trying unsuccessfully to compile an application produced by a contractor – asked me for advice.

More and more I delved into the code, more and more my programmer survival instinct screamed. The code was supposedly C++ and the problem was related to a class, that I would call – to save the privacy and dignity (?) of the unknown author – SepticTank. This class interface was defined inside a .cpp and then again in a .h. Many methods were inlined by implementing them in the class interface (and this possibly was part of the problem).

After resolving some differences, the code refused to link because there was a third implementation of the SepticTank destructor in a linked library. I claimed that such code couldn’t possibly work (even after disabling the dreaded precompiled headers – never seen a Visual Studio project working fine with precompiled headers), even if we could manage to get it compiled and linked the mess was so widespread that nothing good could come.

My colleague tried to save the day by removing the implementation of the SepticTank destructor so as to leave the implementation found in the linked library.

In the end, he had to give up because the code was broken beyond repair, and even if it compiled and linked it crashes on launch (not really surprising).

What stroke me most, basically because it caused a slight fit of dizziness, was the sight of the mysterious operator below –

class SepticTank
{
    public:
        // code removed for your comfort
        operator SepticTank* ()
        {
            return this;
        }
        // other code removed, again for your comfort
};

My brain had some hard moments trying to decode signals from my eyes. Then it figured out that the coder was redefining the implicit conversion to the class pointer so as to use instances and references where pointers were expected… why on the Earth one should want something like that?!?

Implicit conversions if not handled correctly are a sure way to kick yourself on the nose and this is enough a good reason to stay away. But… trying to enter the (criminal) mind that wrote that code, what’s the purpose? Just to avoid the need for the extra ‘&’ ? Or is it a Javism? Maybe it is better to stay out of such minds…

Mind if I comment?

When I worked at Ubisoft I conducted some job interviews for programmer positions. As the interviewer, the company provided me with a grid of questions/topics to ease the candidate evaluation. A list of questions, when not taken too rigidly or in a quiz-like fashion, offers the interviewer a good source for firing up some interesting talks.One of these questions was “What are the qualities of a good source code?” In fact this question is open ended enough to let the interviewed express himself (or, in very rare occasions, herself) on what he (she) considers good or bad programming habits, helping the interviewer understanding the programming-wise maturity of the job applicant.

Counter-intuitively, one of the most common answers I got first was not “don’t goto” as you may expect from school fresh programmers, but “comments”.

The virtues of commenting are taught in every entry level programming class and I think that “commenting” is even more agreeable for everyone than “don’t goto”. After all it takes a few days off the code you were writing to recognize the importance of stuffing your work with the code equivalent of post-its.

What actually most teachers fail to convey to their audience is that comments are just a tool, actually quite easy to abuse and thus causing the opposite of the desired effect. Misuse of comments reduces code readability.

I’m going to demonstrate how to actually remove comments while IMPROVING readability. Just don’t misquote me; I am not against comments at all. If in doubt, comment your code! What I’m going to show you is that by removing comments AND carefully crafting your code the readability will improve.

First: terse is beautiful. Consider prose for example, the shorter the sentences the more comprehensible. Comments add repetitions, extra information and dilute what’s going on with redundancy. If we could write good code first, then, maybe, we could leave out most of the comments.

Moreover comments burden maintenance. An old programmers’ saying tells that if a comment mismatches with the commented code then both are wrong. Maybe this is not always true, at least not for the most trivial cases, but it for sure marks a point – comments have to be maintained. An outdated comment may be from disturbing to misleading causing code maintenance problem. In fact rather than helping you in figure out the way the clockwork turns it confuses your understanding.

Let’s start trimming from variables. It is way too common to comment variable declaration:

int b; // number of bits set to one

Why can’t b be named as oneBitCount? By picking the right name not only we avoid the comment, but we’ll make the lines where this variable is used more clear – our brain need not to remember what b is and we don’t have to look it up in the declaration section.

Using b instead of a more meaningful name denotes two levels of laziness – typing laziness and naming laziness. About the first, a good editor could do much. My editor of choice allows me just to type the first letters of any symbols and then cycle through all the available completion in the file, or the included files or the ctags file.

About the second, there’s no excuse, take your time to chose right names, the ones that best describe the purpose of what they identifies. Names are powerful handles to concepts, the right name is not just for better readability, is for better grasping and processing ideas.

This could be the right time for a little digression on Hungarian Notation, but I don’t want to get this post too crowded, better save it ol’ HN for another time.

Another common misuse of comments is to mark the semantic of a block of code within a function. E.g.

// count bits set to 1

b=0;

while( v != 0 )

{

    if( v & 1 )

    {

        ++b;


    }

    v >>= 1;

}

// ... the function continues

This kind of code is easily turned into functions and the block can be reduced to the single, very clear, line:

b = countBitsAtOne( v );

This has also a number of side beneficial effects such as reducing the size of the including function, clearly defining inputs and outputs of the code block, clearly marking where the code block ends.

In other words not only the code is more readable, but it becomes automatically more maintainable because the maintainer has less chance to mess something up.

I have heard two objections to this approach – execution inefficiency and programmer inefficiency. The first is very unlikely since a common optimization operation performed by every compiler is to make an inline copy of short functions where they are called. For long functions the call cost is not relevant. Anyway the old optimization tenet is always to be remembered and applied – measure before optimizing. The programmer judgment is far from fair in most but the trivial programs. (There is another good rule about optimization: Don’t.)

About programmer efficiency, it may be true that a newbie codes like a rocket and feels that spending time in anything but writing code is a waste of time, but the result is usually a write-only source code that no one is willing, nor able to fix or modify. Moreover the time taken to write the good code at first time is much less than writing bad code and come back later to refactor it in something more convenient. In fact for most code blocks is very difficult to pick up inputs and outputs and be sure the no side effect has been missed in refactoring.

This very same technique can be employed to reduce the size and improve readability of large switch-case statements.

There is another use of comments similar to the one just described. An obscure piece of code is commented with the intended functionality. This goes in a quite grey area. I mean, there are times that code has to be obscure because it is handling unusual or complicate stuff. So explanation for, let’s say, floating point math implementations is more than welcome. In all the other cases it is just smoke hiding what’s really going on. There may be several causes (ego, job insurance, pretending being smart…), but the result is always the same unreadable code. Here holds the principle: don’t do anything that may surprise the reader.

Write simple code unless there is a compelling reason to do otherwise.