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.

Read moreOur 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.

Read moreOur Fathers’ Faults – Failure is not an Option

A Type with Character

So, you know everything about C++ integral types, don’t you?

I thought I did, until when I enabled clang-tidy on my project. It all started with the rather innocent-looking warning:

warning: use of a signed integer operand with a binary bitwise operator

It looked somewhat less innocent when, examining the line, I saw no evidence of signs.

But, let’s start from the comfort zone (at least, my comfort zone):

unsigned x = 32;

The type of ~x (bitwise negation) is still unsigned. No surprise here, really obvious. The diligent programmer finds that the data fits in a smaller integer and writes:

   uint8_t s = 42;

Can you guess the type of ~s? Give it a try, really. Ready? Well, the type of ~s is… int. What? A quick check of other expressions involving uint8_t yields the same … fascinating result. Apparently these expressions are all converted into int.

In other words (and with a bit of syntax bending) uint8_t+uint8_t -> int, uint8_t<<uint8_t -> int, uint8_t+1 -> int. Let me rephrase that, in every expression an uint8_t type is converted to int.

Time for some Internet Duckduckgoing :-).

Back to our uint8_t (that is nothing but an unsigned char in disguise). When a char value, be it signed, unsigned or plain is encountered in an expression (in C++ standard jargon, a prvalue) it is promoted to int pretty much on every common CPU. On exotic architectures, char and int could have the same size, so int could not hold every possible value of char and therefore it is turned into an unsigned. From a strictly rigorous point of view, the signedness of the type of uint8_t in expression is machine-dependent. Keep this in mind if you aim to write really portable code 😉 (*)

You can find a very good (and somewhat frightening) explanation here.

But I’d like to add something beyond the standard technicalities and look at the reasons for why this is like this and what we can take home.

First, it is important to fix that in C (and C++ by extension) the int/unsigned type is mapped to the most efficient word of the target processor. The language provides that, as long as you use int/unsigned (without mixing them) in an expression, you get the most performing code.

Also, the language mandates that an int be at least 16 bits wide and at most the same size of a long.

What if you need to do math on 8bits data on a 32bits architecture? Well, you need assembly code to insert mask operation for cutting away the excess data in order to reach the right result.

So, the C language opts for the best performance turning everything into int, avoiding the extra assembly for masking and let the programmer arrange the expressions with cast here and there if anything different is desired.

Unexpected type promotion, sign change, and performance penalty should be three good reasons to avoid using anything different from int and unsigned in expressions (or long long when needed) and keep intXX_t and uintXX_t for storage.

Note that this applies also to function arguments. It happens quite frequently to read APIs where types for integer arguments are defined as the smallest integer capable of holding the largest value for a given parameter. That may seem a good idea at first since the API embeds in the interface the suggestion to the user for a proper range.

In fact, this has to be balanced against the aforementioned problems and don’t really enforce the constraints for two reasons – first, you can actually pass any integral type and get not even a warning and second, possibly your accepted range is a subset of all the possible value of the type, therefore the user is still required to read the documentation.

Finally, when in doubt, use the compiler 🙂 Finding types of expressions via the compiler could be not the most intuitive task. Below you find the code I used for my tests. Happy type-checking!

/* Linux only, sorry */
#include <iostream>
#include <cstdint>
#include <cxxabi.h>

int main()
{
    uint8_t a = 42;
    std::cout << abi::__cxa_demangle(typeid( a ).name(), nullptr, nullptr, nullptr) << "\n";
    std::cout << abi::__cxa_demangle(typeid( ~a ).name(), nullptr, nullptr, nullptr) << "\n";
    std::cout << abi::__cxa_demangle(typeid( 42u ).name(), nullptr, nullptr, nullptr) << "\n";
    std::cout << abi::__cxa_demangle(typeid( ~42u ).name(), nullptr, nullptr, nullptr) << "\n";
    return 0;
}

(*) Also keep in mind, if you strive to write a portable code, that uintXX_t types may not exist for exotic architectures. In fact, the standard mandates that if the target CPU has no 8 bits type then uint8_t be not defined for such target. You should use uint_least8_t (meaning a data type that has at least 8 bits) and uint_fast8_t (a data type that is the most efficient for operations with 8 bits).

Lambda World 2019

Lambda World 2019 Blog Post

The Spanish town of Cadiz lies outward in the ocean, circled by ancient walls, protected by two castles. Grids of alleys, old houses facing at a short distance across narrow streets, narrow balconies enclosed in windowed structures. Warm, light brown rocks and stone. Old, ancient, historical and yet so filled with sun and sparkling energy.
It is just a heck of a journey to get there to attend the best functional programming conference in the world. You start from your ordinary small northern Italy town, get by car to the nearest airport, fly first to Barcellona, hoping that the turmoils for the recent sentence on the separatist leaders cause no problem with your flight exchange. Wait for a while at the airport terminal, eating a sandwich, then you board on another plane that will carry you to Jerez de la Frontera. There you are up to a ride on the train. Eventually, you reach Cadiz, but you still need to walk to your hotel in the historic downtown. “Walk” because at Cadiz core everything is at a walking distance and most of the streets are impractical to any car.

This is my third year in a row that I manage to get my employer to sponsor my attendance at Lambda World Cadiz. I like this conference, I like the eclectic view of the functional-programming-verse that provides and last, but not least, I like the setting.

Read moreLambda World 2019

it++ 2019

In Italy, June is usually that period of the year when the weather becomes hot and the Italian C++ conference is held in Milan.

That’s why (the conference, not the weather) on Saturday 15th June, my friend and coworker Francesco and I went to the Milan Polytechnic. As for the other conferences I attended, I wrote quite a large volume of notes. Regretfully, as it happened for the other conferences, reorganizing my notes to make some sense of them and present them in an understandable and useful way is out of reach for my homeopathic level of free time. Also, usually you can find online the slides and videos of the talks well before my post. Therefore I decided for the short format I already used a couple of times in the past – a brief overview describing the conference for what you can’t see in the video e a brief summary of the talks I attended to.

Read moreit++ 2019

If the free lunch is over, where can we eat for free?

In the first part of this blog post, I wrote about why FP is mandatory for programmers that work on modern software projects. Summing it up, it was like this – modern hardware scales up by adding cores, therefore, if software wants to scale up and well, then it has to do it by going concurrent, and FP is a good choice to deal with concurrent programming issues.

In this post, I’ll write about some differences between traditional and FP programming and I’ll present one more reason about why FP is a good match with parallel programming.

You can write bad code in any language. That’s a fact. So there’s no magic in functional programming to turn a lame programmer in a brilliant one. On the other hand, you can write pretty good code in the functional paradigm by sticking with the tools provided by functional languages.

So, let’s have a look at this FP thing… First, it is evident that this is not your parent’s FP – map, filter, fold… Just a few of the most recurring spells you’d see in a Scala source and none of them was in the notes I jotted down during my University courses. Even looking at my LISP textbook I couldn’t find any reference to the map operation. (Just to help those with no FP background – map (transform in C++) is an operation that applies a transformation to each item in a collection. In other words, if you have a function that turns apples into pears, then – using map – you can turn your array of apples into an array of pears.)

Read moreIf the free lunch is over, where can we eat for free?

Is Functional Programming functional to programming?

Some 25 years ago I took my class of advanced programming which included exotic paradigms such as logic and functional programming.

As most of the content of that course, FP went into a seldom-if-ever open drawer during my professional career.

Simply I never saw the needs to use Lisp or had the luxury to afford never changing values.

A few years ago (well not that few – just checked it was 2005) I read on DDJ that the free lunch was over. That has nothing to do with the charitable food bank, but it marked a fundamental twist in the computer performance evolution. Something that would have a strong impact on how software was going to be designed, written and tested.

Until 2005 no matter how your code was badly written and underperforming. You were assured that for free, just waiting for the next hardware iteration, your code would have run faster (bugs included)! This is like deflation in economics – why should I invest my money if keeping them in the matters for a year they increase their value?

Read moreIs Functional Programming functional to programming?

++it18 – Channels are Useful, not only for Water

High performance computing made quite some progress lately. Maybe you heard about the reactive manifesto (you should if you are a reader of this blog ;-)), if not, it is an interesting readying … if nothing else as a conversational icebreaker.

Basically the manifesto preaches for systems more responsive and reliable by reacting to requests and dusting it into smaller requests processed by smaller and autonomous systems. This is nothing new, but quite far from traditional processing where single monolitic application took care of requests from reception to response.

There are several programming patterns useful for implementing a reactive system, channels (and streams which are quite the same thing) are one of them. A channel allows you to define a data flow with inputs, computation units, merge, split and collector of information coming in sequence into your system. Once the dataflow is defined, the data flows into it and results come out from the other end.

In this talk Felix Petriconi describes his implementation of channels for C++.

Read more++it18 – Channels are Useful, not only for Water