The point is that those lambda functions are really twisted.

Reading some anecdotes about Alonzo Church it is immediately clear he was quite a guy. And devising lambda calculus required quite a mind.

Since lambda calculus is just functions, no statement, it came to my mind I could use it to devise a solution to my “if-less” programming quiz.

The solution I prepared was too complex to be explained in my previous post, so I decided to write this post.

First I’d like to stress once more that this is not the way functional programming requires you to write code. As for imperative programming, you are not required to reason in terms of Turing’s machine.

There’s a notable difference, though – stemming from lambda calculus you can build directly, abstraction layer after abstraction layer, a usable language. The same does not apply to Turing’s machine which is a conceptual device that cannot be evolved into imperative statements.

As *trigonometry *is the mathematics that lets you deal with angles, *lambda calculus* is the mathematics that lets you deal with lambda terms. So now, what is a lambda term? As a first approximation, we can say that a lambda term is either a variable or a lambda function, i.e. a function that accepts a lambda term as an independent variable and produces a lambda term as a result of its evaluation.

You can notice the recursive definition of the concept possibly, as claimed by Douglas Hofstadter in his *Godel, Escher, and Bach* is the base for intelligent behavior.

Now that you have somewhat familiarized with lambda calculus, let’s get back to the if-less programming riddle solution.

I intended to employ C++ for the solution, but I found so many problems in getting it working that I resorted to Scala. By having a look at rosetta code, you can see that you can actually write lambda calculus expressions in many languages, so there’s nothing special in Scala (maybe there’s something special in C++…). If you are not familiar with Scala, do not worry, I’ll try to describe all the constructs I’ll use. In this case, Scala is just a suitable tool to present something else.

Let’s start from the blueprint of a lambda function –

trait Lambda { def apply( x: Lambda ) : Lambda }

For those not familiar with Scala:

`trait`

is a pure virtual class, used to declare interfaces`apply`

is a special method that is invoked when an instance of Lambda is followed by parenthesis (i.e. it looks like a function call). You may think of this as a C++`operator()`

.

The easiest function is the identity function which can be written like this:

val identity: Lambda = x => x

(for those that need a translation from Scala, `val`

is the prefix for a variable declaration: val *variable* : *Type* = …; `x => x`

is a function that accepts a variable ‘x’ (on the left of `=>`

) and returns it (on the right of `=>`

)).

The first problem is …. hey, I read the lambda stuff definition a couple of times, but nobody’s talking about numbers? In fact, there are no numbers, but by invoking the power of conventions, I can find a convention that lets me encode numbers. Well, not me, good old Church took care of this and invented the Church numerals.

Church numerals are functions that applies a given number of times a function *f* to the variable *x*. Read this a couple of times to let it sink down and then observe the following table –

- 0 – does not apply function
*f*:`val zero: Lambda = f => x => x`

. - 1 – applies function
*f*just once:`val one: Lambda = f => x => f(x)`

- 2 – applies
*f*twice:`val two: Lambda = f => x => f(f(x))`

- … and so on

Computing the successor of a number *n *is a matter of finding a way to invoke *f* once more on *n*. It can be done like this

val succ : Lambda = (n) => (f) => x => f(n(f)(x))

`n`

is the given number and we want to compute `n+1`

(this looks like another riddle ). n(f) is a function composed of *n* nested invocations. `n(f)(x)`

translates to applying *f* nested *n* times to *x*. Since we want one more application, we wrap `n(f)(x)`

into a call to *f*: `f(n(f)(x))`

.

So we now have a set of purposefully crafted functions that represent integers. Since we live in a world that has different conventions about numeric encoding we need a function to go from `Int`

to Church numerals (of course, if we want to write other computations, we need also the reverse function, but this is not needed to find the minimum of two numbers).

The function can be written like this:

val zero: Lambda = f => x => x def toChurch(n: Int ) : Lambda = { if( n == 0 ) zero else succ(toChurch(n-1)) }

(translation from Scala – `def`

introduces a function, such as in def *functionName*( *arg*: *Type* ) : *ReturnType* = *function body*)

The function is recursive – we know how zero is encoded, so, if the number is 0, then we return the constant we defined above. Otherwise, the encoding will be the successor of the recording of the number minus one. Soon or later, keeping decreasing the number I’ll reach zero and I’ll be done.

Next, I need a way to encode the if statement (in C++ it would be the ternary operator since we want a result from the if). The trick used is strongly base on the lambda encoding for true and false values:

val aTrue: Lambda = (x) => (y) => x val aFalse: Lambda = (x) => (y) => y

True takes two variables and returns the first, while false takes two variables and returns the second. At this point writing the if, is just a matter of getting parts in the right order:

val aIf : Lambda = c => (t) => (f) => c(t)(f)

The first argument is the condition (that can be either true or false), then we take the value to return if the condition is true and then the value for the else branch and eventually we leave the job to the condition that will return the first argument if true, or the second if false.

The missing brick is to code a function, let’s call it `leq`

(as in **l**ess or **eq**ual), that compares two numbers and produces true if the first is less than (or equal to) the second and false otherwise.

This is the hardest part. I found several ways on the internet to perform the comparison, and resorted to the one that was less convoluted, nonetheless is way hard.

In order to compare two numbers, we can subtract one from the other and check the sign of the result. This is not exactly what we are going to do, but a direction for investigating.

If we can manage to write a predecessor, then we can implement the subtraction *m*–*n*, by applying the *n* times the predecessor function to *m*. This is easily done:

val sub : Lambda = (m) => (n) => n( pred )(m)

There’s only a minor hiccup in my reasoning – we can encode zero and positive numbers using the Church Numerals, but not negatives. So we can either decide whether to find a negative encoding for Church Numerals, and implement an isNegative function, or we can pick a predecessor function that yields 0 when trying to find a predecessor to 0. In this case, we would need an isZero function.

This latter approach seems somewhat simpler since no change in the number representation is needed. Also, isZero function is really straightforward since zero is encoded as the identity function, we can provide a function that always returns false regardless of the argument and a true as the argument:

val isZero : Lambda = (n) => n( (x) => aFalse )( aTrue )

If the number is non-zero, then f is called, the argument is ignored by f and false is returned, on the other hand, if the argument is zero, then the function is ignored and the argument (true) is returned.

Now we can write the comparison function:

val leq : Lambda = (m) => (n) => isZero( sub(m)(n) )

The only missing block to implement is the predecessor lambda… I left it for last since it is all but trivial (and, of course, I found it on the internet):

val pred : Lambda = (n) => (f) => (x) => n((g) => (h) => h(g(f)))((u) => x)((u) => u)

This is mindboggling, and it is pretty normal to stare at it wondering what is. Basically, this function needs to transform *f ^{n}*(

`h(g(f))`

part is the core that peels off one And this is enough to solve the riddle of finding the lesser of two integers without using the “if” statement. You may wonder if lambda calculus offers something similar to loops. In fact, it does, but it is a bit counterintuitive. You can actually implement recursion, which offers the building block for loops. But, since lambda functions are anonymous and therefore there is no way to reference them, how can this be done?

If you feel stuck it may be of relief, knowing that in the beginning, even Church considered that recursion couldn’t be implemented in lambda calculus. It was one of his students – Curry Haskell – the demonstrated that this was possible and the tool invented for this purpose is the Y-Combinator. I think that this post is already quite dense without the need of delving into this mechanism. If you are happy knowing that it exists, then you can stop here, if you want to investigate further, this blog post may provide an explanation more accessible than the Wikipedia page.

]]>The original idea of a C with Classes at the root of language is long lost and the fabled smaller and cleaner language hidden inside C++ is ever more difficult to spot and use.

The combo – backward-compatibility latch and committee-driven approval/refusal of proposals, make the language evolution spin around. Missing or late additions to the language are sitting ducks, and the lack of networking in the standard library, for a language that is 40, is enough to tell how poorly the evolution of the language is handled.

I don’t blame the committee, at least not entirely, for this abysmal state, personally, I reckon the people in the committee are utterly smart and dedicated and committed to the language success, but I also think that maybe a committee is not the best way to drive the evolution. The decisional process takes too much is too fragmented, and has a high risk to be driven by politics rather than technical and market reasons. This is evident IMO by comparing C++ to other languages, whose development is led by a smaller group backed by large communities.

To be completely honest other languages have a single vendor, the one that usually drives the language evolution, while C++ must support multiple vendors offering more freedom to the user to choose the implementation that best suits them.

But that’s it, in 2022, C++ is in a bad shape, the library is made of patchy and heterogeneous pieces, and the language is extremely complex, verbose, and easy to misuse. Most of the defaults are contrary to what is expected from a modern language (for backward compatibility), the syntax gets involved and complex even for simple concepts, and you can get cryptic endless diagnostic messages if you get something template-related wrong.

Also, C++ lacks standard tools for building and for handling dependencies. There are some, but they are not part of the language, and not being universally adopted you may find yourself struggling to get different components to work together.

This has not gone unnoticed by developers and eventually, a niche for alternative or successor languages opened up. There are many reasons to stick with C++: it is a very mature language, with industrial-grade tools and compilers, and it is likely to stay around for a good while. But the cost of using C++ is getting higher and higher to the point that alternatives become viable.

First came rust. Never claimed to be a C++ successor, but it is a system language that aims to solve the same class of problems the C++ does, offering comparable (sometimes even better) performance. Additionally, rust comes with the notable property that valid programs do not leak. I.e. if you can compile rust code, you won’t have memory leaks or buffer overflows. This is not entirely true, since you can force the language to do unsafe things, but it is a good approximation since usually, you don’t need to be unsafe and when you need it, then you have to be very intentional about this.

Rust is 12 years old, it got quite solid and stable, and it is being used in Linux and Windows source code. The learning curve may be not very smooth, but rust is getting really widespread.

This year two announcements rocked the C++ kingdom – Carbon and cppfront (AKA C++ syntax 2).

Carbon was announced at CppNorth 2022 by Google. The language is still early in its infancy, presented as an experiment, and has the ultimate goal to be a successor of C++. There is no compiler (just an interpreter) and significant areas (notably memory safety) have not been designed yet.

Nonetheless, Google thoroughly analyzed the problems of C++ evolution and made sure to put the language on an alternate course:

- The language evolution is driven by a triumvirate taking more important decisions and an open community;
- Avoid stable ABI and backward compatibility thanks to a set of tools that automate translation between different versions of the languages.

From the syntactical point of view, Carbon takes the pattern: variable name followed by type, same for functions – the return type is at the end of the argument list. Set this aside the language doesn’t seem to offer a more direct or brief way to achieve the same results, yielding a verbosity only slightly lighter than C++. But it may be too early to have a definitive opinion.

Possibly the most notable innovation is about the handling of generics. C++ generic programming is based on *Duck* typing – i.e. the type is ignored, as long as it provides the features used in the template. This may be fine, but there is no guarantee that, even if the syntax fits, the semantics are what the template expects. Just to exemplify – a template may require an object of type T to expose a `fire()`

. This poses no requirements on type T, but for the presence of the method. The code may compile both passing an instance of Employee or an instance of Weapon, with clearly different and dramatic results. C++ concepts also don’t help, since they just define syntactical constraints.

Carbon gets around this limit, by enabling the programmer to require a base class, or an interface for the generic type to give a semantic context. This check can be performed at compile time.

Still, in the generic programming domain, there is no SFINAE, but templates are enabled via if statements that more conveniently express the conditions under which this template has to be used.

Another welcome innovation regard function arguments. These are const by default and they are passed by reference or by copy according to which is more performant, relieving the programmer from this choice. You may force copying of parameters. Reference to parameters, if needed, must be explicitly required via pointer use.

The last two remarkable additions are pattern matching and tagged unions (choice). Pattern matching is like a switch case on steroids where instead of literal constant you can specify patterns (e.g. types, tuples, expressions). Tagged unions are like `std::variant`

(sum types) but integrated into the language, very close to Rust’s enums.

So far, so good, but the reality is that the language is not yet there. There is no compiler, just an interpreter, and some quite important aspects of the language (e.g. memory handling) are still to be discussed and defined. But this effort is backed by google, so it is wise to take this seriously and check back in a few years.

You can try Carbon on compiler explorer.

Last September, at cppcon 2022, it was the time for Herb Sutter, a long-time C++ veteran, to unveil cppfront a new syntax for C++.

The reasons cited for creating a new language were basically the same, but the approach is quite different and interesting.

The guiding principle in designing the new language is to address the shortcomings of C++, turning proper idioms, and modern usage of the language into default syntax and making it impossible to use problematic or obsolete constructs. The goal for Herb was to measurably reduce the effort of programming correctly in C++ and the effort needed to teach the language. Basically, cppfront is a shell that wraps around C++ and lets you use only the safe part of the language in a modern and rational syntax.

Rather than implementing a compiler, Herb opted for a transpiler, so that Cppfront source is translated into C++. This approach has two additional benefits – first that integration with C++ code is straightforward since C++ is what is generated by the transpiler, and, second, cppfront may be used to produce working and editable C++ code if the original cppfront code is not needed (or welcomed, or the experiment fails).

Whereas Carbon has a rich website with structured documentation (even if mostly filled with TBD equivalent), cppfront has no documentation and Herb suggest interested readers to browse the unit tests. It can be done, but it is quite an ineffective way to find features.

Many of the cppfront characteristics are based on proposals that Herb made in the last years (and this left me for a while with a slightly disturbing feeling – were the proposals made for improving C++, or for easing the transition to cppfront?)

Cppfront syntax is modern, very uniform, and consistent – variables, constants, and functions are all declared as:

name: type = value.

Arguments are passed by using specifiers such as in, inout,

In both cases, the semantic, or, if you prefer, the executing machine, is still the same, but the C++ syntax is deemed broken, bloated, and too complex justifying the effort to design a new front end.

Compiler Explorer offers a way to experiment with cppfront as well.

Circle is worth mentioning here because it takes an alternative way to reach the same goal – be the next C++.

First, Circle is a C++ compiler, developed by a single programmer (!) – Sean Baxter, and designed to be easily extendible. This allowed the author to explore a number of additions to C++ that, while remaining in the C++ language framework, would make the C++ programmer’s life easier.

Slice, pattern matching, choices, interfaces, and so on and so forth.

The idea behind Circle is to work within the language while providing a number of powerful extensions, that very slightly break backward compatibility. Circle could somehow lead the language evolution (committee willing), or lock in developers on this very compiler.

From this point of view, it is relevant that Circle is the only one of these projects that is not open source. It is free (as in beer), but someday the author may decide to capitalize on his investment and propose paid support or subscriptions, or whatever.

Of course, compiler explorer lets you experiment with Circle.

These stories tell a clear truth – the C++ era is ended. Far from me to say that this language will soon be abandoned. It would take years, but this is the time when it started.

It is hard to say who will be the winner and even if there will be a single winner, or if the development community will split over several different languages.

Also, it is very likely that other contenders will enter the arena fighting to get programmers’ attention and trying to build the largest community.

As of today, the road taken by cppfront seems, IMO, to be the most promising – the C++ interaction is perfect and the effort needed to implement the new language is reduced. It seems a viable solution to replace and evolve incrementally your C++ codebase into the new language. The greater weakness, with the current implementation (aside from the utter lack of documentation and the bad name), is the chance of stumbling in an error reported by the C++ compiler that is difficult to map to the original cppfront code.

Circle may help to take C++ programmers to new constructs, but still paying the tens of years of technical debt, the more circle will pay this debt off, the more the language will be detached from C++, eventually losing the advantage of being C++.

Carbon looks less promising than cppfront and, considering the firepower of Google, also seems a bit neglected, when compared to Go and Dart.

What is clear to me is that if you are sick of C++ today, you don’t have to wait for anything else, just turn to Rust. A language that is mature, widely available, and popular. Interoperability with C++ may be not seamless as cppfront, but is possible and well-tested. Moreover, none of the C++ successors is bound to give you the same safety that rust provides out of the box.

Ps: beside of the original presentations, I found very interesting the following podcast episodes, guest Sean Baxter, comparing the new languages:

]]>As the winner, it was my duty to invent the next riddle. A really daunting task if I wanted to live up to the expectations. Honestly, I didn’t invent anything, I just squeeze the web looking for a good programming riddle in the drops.

Eventually, I decided to go for determining the lowest of two numbers… using if-less programming. After all, if statement can be tricky and someone already pointed out that if statement should be considered harmful in the same way the infamous goto is.

As the riddle maker I couldn’t compete (judging would have been a bit cumbersome), but nothing prevented me to try outside the competition.

I found quite a number of solutions, but I’d like to present them alongside those of my colleagues.

There are three main approaches:

- Comparison expressions evaluate to 1 if they are true and 0 if they are false
- Using library functions
- Bending other conditional constructs
- Using math
- Using information theory

One of the original design goals of C was simplicity. It had to be a simple language so that the compiler would have been easy to write. Stemming from BCPL where there was just one type – `int`

– C also got rid of extra types, notably strings and booleans (and defaulted types to int).

So every boolean expression (e.g. *a>b*) is of type `int`

and evaluates to 1 if the expression is *true*, or 0 if the expression is *false*.

This can be leveraged in a number of ways to determine the lower value between two numbers.

Here’s Mario‘s solution:

int Minimo(int x, int y) { int z = (x >= y) * y + (y > x) * x; return z; }

The expression `(x >=y)`

evaluates to 1 if is true (when x is greater or equal to y), or to 0 if it is false (when x is less than y). Multiplication zero (0) and identity (1) elements do the rest.

Not happy with the C++ solution, Mario also submitted the same concept written in LOLCODE:

HAI 1.2 CAN HAS STDIO? HOW IZ I MNIMUM YR X AN YR Y I HAS A PICC_Y ITZ BOTH SAEM X AN BIGGR OF X AN Y I HAS A PICC_X ITZ DIFFRINT X AN BIGGR OF X AN Y I HAS A MNIMUM ITZ SUM OF PRODUKT OF PICC_Y AN Y AN PRODUKT OF PICC_X AN X FOUND YR MNIMUM IF U SAY SO VISIBLE "WHATZ FRST TIEM 4 SPAGO?" I HAS A X GIMMEH X VISIBLE "WHATZ SECUND TIEM 4 SPAGO?" I HAS A Y GIMMEH Y I HAS A MINMUM ITZ I IZ MNIMUM YR X AN YR Y MKAY VISIBLE "TIEM 4 SPAGO IZ " MINMUM KTHXBYE

Esoteric programming languages have the expressive power to make you laugh. References to “Spago” and time are because of the way I formulated the puzzle, but I think that once you get over the confusing syntax is easy to identify the input request for two numbers and the output of the lowest.

I believe that most of these esoteric languages are translated into C and then compiled, that’s why they could inherit some of C behaviors, rather than by design.

Although it may seem like cheating, I considered valid solutions using a library function. First, hiding a low-level construct under a higher abstraction level contraption is the right way to go since it enables us to tackle increasingly complex problems. Moreover knowing your tools is always an important asset for programmers regardless of the language and the library used.

Anna submitted the shortest version in Python (one line shorter than the C++ equivalent):

def find_earlier(x,y) return min(x,y)

Other library usage includes various applications of containers.

Domenico proposed two solutions with containers – one with a standard array and then a sort operation –

int solution_array_sort(int x, int y) { std::array<int, 2> mArray{x, y}; std::sort(mArray.begin(), mArray.end()); return mArray[0]; }

The other one is more convoluted and uses an associative container which uses comparison results as keys for the result:

int solution_map(int x, int y) { std::unordered_map<bool, int> mMap{ {true, x}, {false, y} }; return mMap.at(x < y); }

In the same direction, yours truly wrote the following code that avoids the associative container relying on indexes 0 and 1 as the result of the comparisons:

int m7( int x, int y ) { int a[2]; a[x>=y] = x; a[x<y] = y; return a[0]; }

A different take on containers can be found in my solution:

int m5( int x, int y ) { int a[2] = {x,y}; return *std::find_if( a, a+1, [y](auto _){ return _ < y; }); }

The array is filled with the two values, then a find is performed on a range that includes just the first item in the array. If `std::find_id`

doesn’t find any item that satisfies the predicate, then it returns the `end()`

iterator. Since `end()`

is one past the last item of the range, it *points* to the other value.

Two solutions are based on sets. The first one is mine –

int m6( int x, int y ) { auto xs = std::views::iota(0,x); auto ys = std::views::iota(0,y); std::vector<int> out; std::ranges::set_intersection( xs, ys, std::back_inserter(out) ); return out.size(); }

This uses C++20 ranges, iota produces a sequence of integers from the first to the second argument. Then an output vector is filled with the intersection. Per construction, the intersection is equal to the set with the lower cardinality. And cardinality is the solution.

The other solution by Phuong, uses sets, but determines the smaller one, by trying to access it out of range:

int smaller_things_2(int x, int y) { std::vector<int> A(x, 1); std::vector<int> B(y, 1); try { A.at(y) = 1; } catch (std::exception& e) { std::cerr << "Exception caught : " << e.what() << std::endl; return x; } try { B.at(x) = 1; } catch (std::exception& e) { std::cerr << "Exception caught : " << e.what() << std::endl; return y; } return 0; }

Note the use of this `std::vector`

constructor that creates a vector of size equal to the value of the first argument and then fills the vector with the value of the second argument.

I liked this solution for the creative approach and the reckless application of exceptions, and the ruthless use of vectors. That’s why I chose this as the winner of the contest (kudos Phuong!).

Note that relying on set cardinality works only for positive integers (which is consistent with my formulation of the problem).

I find Phuong‘s code the perfect link with the following section, since his solution not only employs sets but also finds a way to bend exceptions to work as ifs.

It is true that the “if” statement is the first we turn to when we need to make a binary decision, but the conditional branching – core to the Turing Machine – resurfaces also in other commands – `switch`

, `for`

and `while`

just to name a few.

My solution (indeed suggested by Alessandro) is the bending of the `while`

statement –

int m8( int x, int y ) { while( x < y ) { return x; } return y; }

The `return`

statement just breaks the loop and it’s not different from the if statement.

Another solution from myself relies on conditional expression shortcuts:

int m1( int x, int y ) { int result; (x < y && (result = x)) || (result = y); return result; }

when the result of a boolean expression is determined, then the remaining part is not evaluated. Interestingly (and a bit upsetting to purists) assignment is an expression, so it can be written in logical expressions

There are two directions for employing mathematics – devise a formula that produces the lower of two numbers, or approach it with arithmetic and sequence.

Finding a formula is not right intuitive, but it can be achieved by considering the two values as points A and B on a line. There will be a medium point M equally distant from A and B. If you subtract half of the distance AB from M, then you get the lower value. This is what my solution does –

int m4( int x, int y) { int mid = (x+y)/2; int delta = std::abs( x-y)/2; return mid-delta; // or (x+y-std::abs(x-y))/2 to avoid a division }

Nicola found another way to put it –

def get_min_without_less_operator(x, y): scaled_solution = (abs(x-y) - (x - y)) * x + (abs(y-x) - (y - x)) * y scale_factor = 2 * abs(x - y) return scaled_solution / scale_factor

As put by Nicola *This relies on the fact that [abs(x-y) – (x – y)] = 0 if x > y, else it is equal to 2 * abs(x-y).* *The solution works ONLY if x is different from y (otherwise there is a division by 0)*.

The arithmetic solution is once again from Domenico, go down from x and y to zero and count the iterations:

unsigned int solution_while(unsigned int x, unsigned int y) { unsigned int count = 0; while(x > 0 && y > 0) { x--; y--; count++; } return count; }

This solution applies only to positive integers.

The last mathematical solution is another code snippet by Nicola:

def in_luck_we_trust_tribute(x, y): """Inspired by your previous solutions, here is a solution that gives you 50% chance of a correct answer :D""" return random.sample([x, y], 1)[0]

Notably, this code sometimes yields the right solution, sometimes doesn’t… if you trust in luck (and RNG) then this is for you

Although most programmers are familiar with the concept of Turing’s Machine, much less of them ever got in touch with Alonzo Church‘s work.

Alonzo Church was a bright mathematician, besides being a teacher of Turing, Church devised a computational model based on functions named Lambda Calculus. It has been demonstrated that Lambda calculus is equivalent to Turing’s Machine, meaning that any algorithm that can be implemented on a Turing’s Machine can also be implemented in Lambda calculus.

The solution to the problem implemented in Lambda calculus is quite convoluted and I will write a dedicated post. In the meantime, I just note that numbers need to be converted to and from a specialized notation (Church’s numerals) in order to be processed by the algorithm.

Of course, no one sane in their mind would write production code like this (unless on a deserted island) in the same way no one would write code using Turing’s Machine notation. On the other hand, I find it very fascinating how something so functional, in the mathematical sense, can compute algorithms.

Being purely functional opens the way to mathematical tools and therefore to rock-solid certainties.

I tried for a while to write this in C++, but I haven’t found a good solution that avoids slicing, so I resorted to a better-suited language – Scala:

package org.maxpagani.iflessmin import scala.annotation.tailrec trait Lambda { def apply( x: Lambda ) : Lambda } object Main { def toInt( y : Lambda ) : Int = { case class Counter( counter: Int) extends Lambda { def apply( x: Lambda ) : Lambda = this } case object AddOne extends Lambda { def apply( x: Lambda ) : Lambda = { Counter( x.asInstanceOf[Counter].counter+1 ) } } y( AddOne )(Counter(0)).asInstanceOf[Counter].counter } val zero: Lambda = f => x => x val identity: Lambda = x => x val aTrue: Lambda = (x) => (y) => x val aFalse: Lambda = (x) => (y) => y val succ : Lambda = (n) => (f) => x => f(n(f)(x)) val pred : Lambda = (n) => (f) => (x) => n((g) => (h) => h(g(f)))((u) => x)((u) => u) val sub : Lambda = (m) => (n) => n( pred )(m) val isZero : Lambda = (n) => n( (x) => aFalse )( aTrue ) val leq : Lambda = (m) => (n) => isZero( sub(m)(n) ) def toChurch(n: Int ) : Lambda = { if( n == 0 ) zero else succ(toChurch(n-1)) } val aIf : Lambda = c => (t) => (f) => c(t)(f) def main( args: Array[String] ) : Unit = { val xx = toChurch(42) val yy = toChurch(24) val zz = aIf( leq(xx)(yy) )(xx)(yy) println( toInt(zz) ) } }

If you read this and don’t understand it, it is perfectly normal, since “in mathematics, you don’t understand things. You just get used to them” [Von Neuman].

This has been another really entertaining riddle proving that lateral thinking is a precious resource to get us out of stack situations. I’d like to thank the participants – Anna, Domenico, Mario, Matteo (whose solution included even unit tests), Nicola and Phuong, and all the colleagues that took the time to read my cumbersome puzzle. Also due thanks go to my employer Schindler who strives for engineer excellence and promotes these side activities.

]]>Produce a program which increments an integer variable by a value of 1 without using sum or increment operators.

You are pretty free to choose whatever integer size and type you prefer (I would say, but `bool`

), and whatever language you want. I stuck with C++ because it was quicker, but most of my solutions can be easily ported to other languages.

So, before continuing be sure to give some thought to this riddle to not spoil the fun.

Increasing an integer number without using the addition (symbol) is quite a challenge. After some brainstorming, I figured out the following directions –

- use algebra (hey, we studied it a life long… let’s put it to some use);
- use bit representation (a pattern of bits needs to be turned into another pattern);
- use reverse definition – find a number that when decremented results in the argument number.
- use other language constructs that allow some mathematics

Usual caveats hold – when trying to increment a signed int, you may stumble into an undefined behavior if the result would be greater than the larger number that can be represented using such a type.

If the type is unsigned then you don’t have a UB, but if you are thinking of int as a mathematical integer then you may be in for some surprises in comparisons.

But let’s start in the same order I found the solutions.

This is the very first solution, a plus, according to algebra is just a pair of minus in disguise. – -1 = +1, so subtracting -1 is just as adding 1.

// Everything's relative [[nodiscard]] int f0( int n ) noexcept { return n - - 1; }

A pretty boring solution, so let’s try something more exotic.

Getting back to the meaning of integers, I remember from primary school that is something stemming from the cardinality of a set, therefore if I create a set with a number of items equal to the number to increment, then add an item and compute the cardinality I got the desired result.

I opted for std::string for no specific reason… well I thought it was the only container that could be built with a given number of items, but I was wrong, std::vector can do it as well.

Any character can be used since the content of the string is not relevant, but its length is.

#include <string> // stringly typed language [[nodiscard]] int f1( int n ) { std::string s( n, ' ' ); s.append( " " ); return s.size(); }

This method is a bit heavy on resources, but with nowadays PC could be affordable. Not as boring as the previous one, but still not that exciting. Time for something different…

C++ metaprogramming is as contorted as it could be, in comparison, INTERCAL is a model of simplicity and mindfulness, but I digress. So I just imagined that we want to compute the increment at compile time. Uninteresting as it may be, here you are the code:

template<int N> [[nodiscard]] int f2() { struct T { char a[N]; char b; }; return sizeof( T ); }

This time the argument is not passed as a function parameter, but as a template parameter. So you need to call this function with `f2<41>()`

to get the answer. The same code cannot be used to compute something that’s only known at run-time since you can’t pass a variable as a template argument.

This was funny, but the limitation about the run-time was a bit disappointing and this led me looking into bits.

What’s an integer, but a sequence of bits? What is left of an electronic engineer in my soul still knows how to design an adder circuit with some logic gates. You take two bits (addition terms) and output two bits. The first bit is the result, while the latter is the carry. In schematics, it would look like:

You can design an increment by chaining several of such circuits. All ‘A’s ports are connected to operand bits, the first ‘B’ port is set to 1 (we want to add 1), next circuit ‘B’ is connected to the previous carry signal. The translation in software is quite straightforward.

// every bit counts int f3( int n ) { int carry = 1; int result = 0; int mask = 1; do { int bit = (n&1); result |= (bit ^ carry)*mask; carry = bit & carry; n >>= 1; mask <<= 1; } while( n != 0 ); return result; }

The most notable part is that the loop completes when there are no more ‘1’ bits in the argument. I picked this as an alternative to sweeping through all the bits of the operand since it is a slight optimization and also because the use of ‘+’, needed for incrementing the loop counter, is forbidden.

While looking at the bits and reasoning about what is the meaning of increment, I noticed the following pattern –

0+1 | 1 |

01+1 | 10 |

011+1 | 100 |

0111+1 | 1000 |

01111+1 | 10000 |

That is, from left to right:

- if the bit is 1, then it gets flipped to 0 and the operation continues,
- if the bit is 0, then it gets flipped to 1 and the operation stops.

In other words, bits to the left of the first 0, are not affected by the increment. That sounds like an algorithm

// it's a bit thing. int f4( int n ) { int mask = 1; while( (n & mask) == mask ) { n ^= mask; mask <<= 1; } return n | mask; }

This is faster, on average, than the previous solution since the loop lasts stops at the first least significant bit at 0 in the operand, while the former code looped through all the bits.

Also, it is shorter and somewhat more readable.

This is just a crazy solution, loosely inspired by the random sort algorithm. Since I know which relation must hold between the result and the operand (result – 1 == operand), I may look for numbers that satisfy this relationship. And where do I get these numbers from? Uh? Random generator, of course. Given an infinite time, for sure, I’ll get the right number

#include <random> int f5( int n ) { std::random_device dev; std::mt19937 generator( dev() ); std::uniform_int_distribution<std::mt19937::result_type> dist( std::numeric_limits<int>::min(), std::numeric_limits<int>::max()); while( true ) { int result = dist(generator); if( result-1 == n ) { return result; } } }

This is more hideous than what is needed because of the Uglification Principle that inspires C++ Evolution (given two solutions yielding the same result, pick the uglier one). On the other end, it is true that you can choose different RNG algorithms. An improvement that I left out for sake of brevity (and some sadism). is to further limit the range of the random numbers. Since you can’t add, you could double the number and search the result in the (n, 2n] range. Of course in the argument is 0, then it must be treated as a special case. Also, negative numbers require some care. But … trusting in luck must be blind as the luck herself

After looking into representation, let’s have a look at semantics. I remember an optimization for computing multiplications from just square lookup tables, sum, and subtraction, and halving (axb = ((a+b)^{2}-(a-b)^{2})/4. Therefore I looked for some formula that involved somehow n, resulting in n+1.

The formula is from basic algebra: (a^{2}-b^{2}) = (a+b)(a-b), which means that a+1=(a^{2}-1)/(a-1).

int f6( int n ) { return (n*n-1)/(n-1); }

That’s it, elegant, neat, tidy. Regretfully you must ensure that n*n does not overflow the integer type you are using. Also may have some trouble if n equals 1.

The next exploring direction was to look if the language provides, i.e. is there any operation in the syntactic sugar of the language that I can exploit to get a sum or increment?

Yes indeed. The weird C equivalence between array and pointers requires that a[n] == *(a+n). So item accessing hides a sum (and a multiplication if you look under the hood). Let’s use it

int f7( int n ) { auto const* ptr = reinterpret_cast<char const*>(n); auto result = reinterpret_cast<uintptr_t>( &ptr[1] ); return result; }

Ugly as it can be it is just turning integers into pointers and back. Strictly speaking, this is UB. Even if the pointer is not dereferenced, pointer math could rely on the fact that the pointer is well defined and the integer argument may not be such a value. I found more info in this here.

I don’t like this solution very much, but it is still a hack.

Talking about lookup tables… a lookup table where at index n, n+1 is stored could easily solve the problem. The drawback is that this is really expensive for integers beyond 8 bits. `int16_t`

and `uint16_t`

require 2*2^{16} = 128k (and that’s could be still acceptable), while `int32_t`

and `uint32_t`

require 4*2^{32}=16G. Also, you need to create the table… So I decided to just show the proof of concept using an `uint8_t`

and a table computed outside the code.

// Don't look down int f8( uint8_t n ) { static uint8_t const next[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 0 }; return next[n]; }

(I didn’t even try to format the code O:-) ).

This solution stems from the random search one, i.e. searching from a solution in the solution space, but this time with a better strategy – linear search from the highest integer number.

#include <limits> // The crab move int f9( uint8_t n ) { int result = std::numeric_limits<uint8_t>::max(); while( result-1 != n ) { result -= 1; } return result; }

Now that I read this solution again, I think that many improvements can be done both to restrict the search space (according to the same thoughts on the random search) and to step from the linear search to a binary search. A binary search would take just 32 attempts in the worst case to figure out the next integer for int32_t.

Being right half of the time is better than never being right. That sounds a bit pretentious (and it is), but sometimes you just need to look at your problem from a different perspective to find that not all the constraints you think you have, are there for real.

// correct half of the times int f10( int n ) { return n | 1; }

Yes if n is odd, then the answer is wrong, but it is always right when n is even.

With all the fuzz on functional programming, I couldn’t miss a recursive solution. It took a while to figure out what could be the best approach for applying recursion, eventually, I came out with the following – if the number is even, then just set the least significant bit to one (see the previous solution) and we are done. If the number is odd, then look for an even number in the most significant bits and pads with 0 the right of the result.

int f11( int n ) { if( n % 2 == 0 ) { return n | 1; } return f11( n >> 1 ) << 1; }

Although this function has a certain elegance I wouldn’t pick this as the most readable, I’m not that recursion-addicted. Also, note that this is not a tail recursion, but in the worst case it recurs just 32 times. Likely no problems with the stack.

Last solution devised by me is dubbed “Pass the test” and the idea is that it is better to be right at least once than never. So, if you know you are testing with a specific number, why not just check that input?

int f12( int n ) { if( n == 41 ) return 42; return 0; }

Although I wouldn’t advise using code like this in production, it may be useful to force a test passing or to implement mock-ups.

What a ride! Very interesting stuff from an apparently simple challenge. Although my intention was just to explore the solution space, it turned out I won, so it is my time to propose the next C++ riddle of the week.

]]>C++ offers the exception mechanism, which is a clever way to leave the happy path in sight and hide the troubles under the carpet. Even before questioning if this is a good idea or not, C++ abstraction is so delicate that you need to take particular care in making your code exception-safe. Meaning that in case of exception your program does not leak resources and leaves everything in a useful state so that the exception can indeed be recovered from.

RAII and smart pointers are part of the correct exception handling toolset from the design and coding point of view. More generally you need to be able to afford some extra memory (for storing stack unwinding tables) and some non-deterministic execution time.

Also, you may be confronted with the dilemma of what is an exception and what is an error. Trying to open a file that does not exist? They tell me that this is not an exception because it is a possible outcome of file opening… I am afraid these “distinguo”s are too subtle and thus controversial.

Functional programming way of error handling is via `Either<L,R>`

, that is functions always return something, and that something can either be a value or an error. This is a very good abstraction, but eventually, you end up with everything wrapped into an Either. That could be annoying and in C++ even more, since the language lacks monadic composition (such as the for-comprehension we have in other languages).

Moreover, when working with firmware and embedded systems you have many functions that can return an error, but no real value when succeeding. Yes, these are impure functions, which are relevant just because of their side effects. Maybe someday we could use an effect system in C++ (a la Cats Effects or Zio), but today C++ (and C++ community) is not ready yet.

What you see in many firmware or embedded software projects is a sequence like this:

int result = 0; result = initStuff(); if( result != 0 ) { return result; } result = sendData(); if( result != 0 ) { return result; } result = waitReady(); return result;

Not nice to write, not a joy for the eyes, possibly subjected to copy’n’paste antipattern. Screaming “compose me” to any functional programmer.

After tinkering with alternatives for a while, I came up with this solution I named (with a brilliant effort of creativity) Error. Error is just 4 bytes of data, partitioned like error code (8 bits), error module (8 bits), and additional data (16 bits). An error code of 0 means *no error* regardless of the module where the error occurred. All other codes are defined within the module context. Additional data is an optional field defined according to the module and error code that may contain additional data that can be useful when reporting or debugging the error.

And this is nothing special. Maybe some clever way to let module self register, but pretty traditional C/C++ code.

Things get more interesting by adding the andThen method:

template<typename F> inline Error Error::andThen( F f ) const noexcept( std::is_nothrow_invocable_v<F> ) { return m_code == 0 ? f() : *this; }

In other words, function `f`

(which must return an Error) is invoked only if this Error object contains no error. Otherwise `f`

is not called and this object is returned.

Now you can rewrite the code above in a more elegant and smart way:

return initStuff() .andThen( [](){ return sendData(); } ) .andThen( [](){ return waitReady(); } );

Once you get over the ugly lambda syntax that the committee gave us, the sequence is quite trivial. In case of error, the sequence is interrupted, no more calls are performed and the error value is returned to the caller.

The Error behavior is pretty similar to `Either<E,void>`

where `E`

is the error code. When the Either is successful the result value has no information, when the Either is a failure then you have the error code.

If the `andThen()`

method looks pretty familiar the reason is that it is indeed a flatMap.

So, am I inventing the wheel or just reinventing a monad? Let’s see. In order to be a monad, we need two methods: *pure* and *bind*. Pure is the constructor and we know how to construct an Error, be it successful or failing.

Bind is the flatMap operation, Error embeds information (ok/error code) that can be transformed via a function producing another Error.

And then we need to follow the monad laws: **right identity**, left identity, and **associativity**.

Before diving into laws, we need to define equality between two Errors. When two Errors are both ok, the data field is not used and the source module is not really interesting – the call has succeeded, how does it matter where?

When the Error represents a failure then all fields are relevant since I want them to guide me in finding the problem (possibly not any problem, but the first problem that caused the error to happen.

Back to laws. Right identity laws prescribe there exists an element I such that e.andThen(I) is equal to e. Ok value is such an element I, because if e is a failure, then the result is e, if e is OK, then the result is still OK.

The same holds for left identity, where OK is once again the identity element.

Associativity is a bit trickier since you need to investigate three items: a, b and c and verify that:

(a.andThen( b )).andThen(c) = a.(andThen( b ).andThen(c))

Let’s demonstrate it with a table of truth (possibly there are more elegant ways to demonstrate it):

a | b | c | truth |

Ok | Ok | Ok | true |

Ok | Ok | Error | true |

Ok | Error | Ok | true |

Ok | Error | Error | true |

Error | Ok | Ok | true |

Error | Ok | Error | true |

Error | Error | Ok | true |

Error | Error | Error | true |

Qed (it’s from a long time I wished to write QED ).

Well, that may seem like a fruitless exercise in some *mathetmaticism *with no practical purpose or application.

Quite the opposite. First having a solid math foundation “you can prove stuff” (as my good friend Sandro once told me) and you make sure that you can compose and use Error with the standard FP constructs. Also, it is straightforward to lift Error to other kinds of monads.

Now, before starting coding with Error claiming to be a fully functional programmer, a bit of caution is due.

Functional programming preaches that functions must be pure, i.e. function just computes something starting from its arguments, and its arguments only, and only produces a result. No side effects, no global state access. Error has no return value, therefore functions returning an Error must do something in the environment to be useful. In fact, this kind of function is usually employed for initializing hardware peripherals. From this point of view is pretty impure.

Also, consider associativity, if you just look at the result, then things are fine, but since the order of invocation may matter, associativity does not work in general.

That is my Error is as close to a Monad as possible for an imperative code, without being a Monad.

You can find Error implementation in my chef library.

]]>Before learning Scala I was perfectly fine with C++ imperative statements, if you want to retrieve a value out of them just change a variable in the outer scope.

The example below is a bit artificial, but I’m sure you recognize the pattern you already used countless times in your imperative code.

bool f( int x ) { bool ok; if( x == 1 ) { printf("yeah\n"); ok=true; } else { printf("ouch\n"); ok = false; } return ok; }

Although fine it had one annoying quirk – you need a dedicated outer scope variable (`ok`

in the example). You could leave that variable uninitialized since you are going to initialize rightly thereafter, but leaving an uninitialized variable is a bad habit, reported as a warning by the compiler and forbidden by many coding guidelines.

But the initialization is just something dummy to silence the warning and doesn’t really prevent any bug. I mean, if I forget to assign a value in one of the statement branches the compiler won’t complain because a default value is already present.

On the other hand, relying on the default initialization value, thus assigning the variable only in some branches of the statement could be legit and intended. So the same construct can be both correct or wrong according to a larger semantic context that requires an extra effort when reading the code.

char const* f( int x ) { char const* result = "zero"; if( x == 1 ) { printf("yeah\n"); result="one"; } else { printf("ouch\n"); } return result; }

Hard to tell from this example alone if the function has a bug (missing result assignment in the else branch), or is correct (default value is used for the else branch).

Here come functional statements, i.e. statements that look like their imperative counterparts, but return a value (I already wrote about these in my Is C++ ready for FP series). In C and C++ you have the ternary operator, which is a dumbed-down version of the functional if/else statement. (This is just another entry in the missed opportunity for unification in the C++ records, but this is would be a too-long digression).

The problem with the ternary operator is that you can use just expressions in the then/else branches, you can’t insert other statements. You could be tempted to use the comma operator, but I would really advise against it unless you are up for an obfuscated source contest (or you really hate your readers). The comma operator has few applications and should be restrained to those (note that – folly madness – C++ allows you to overload the comma operator).

Therefore without employing the comma operator, you can’t really translate the first example into an equivalent and terse code:

char const* f( int x ) { bool result = x == 1 ? "one" : "zero"; if( x == 1 ) { printf("yeah\n"); } else { printf("ouch\n"); } return result; }

Statements in languages such as Scala and Rust always return a value and, based on the context, the lack of such a feature in C++ ranges from slightly annoying to stressful. Consider the following Scala code:

def f( x: Int ) : Boolean = if( x == 1 ) { println("yeah") true } else { print("ouch") false }

Although this feature is not even on the deep scan radar of the committee, I found an interesting workaround based on lambda functions.

Considering that lambda functions are C++ (ugly) first-class citizens, you may create a temporary value of them, with no other purpose to be invoked in place:

char const* f( int x ) { char const* result = [&](){ // capture everything by reference, no arguments if( x == 1 ) { printf("yeah\n"); return "one"; } else { printf("ouch\n"); return "zero"; } }(); return result; }

You can improve the robustness by avoiding the default capture and having the discriminant variable as an argument:

char const* f( int x ) { char const* result = []( int _ ){ if( _ == 1 ) { printf("yeah\n"); return "one"; } else { printf("ouch\n"); return "zero"; } }( x ); return result; }

Note that this version gives the reader a better understanding of what is going on because the lambda pretty well defines a fence around its content, the only input is x, the only output is what lambda returns. You don’t always manage to achieve this kind of terseness – after all, this is a silly example -, but you would always have a clear list of which are the dependencies of that code fragment.

Eventually, all C++ programmers would ask the price in terms of additional CPU cycles for the increase of the abstraction level. Time for compiler explorer. As you can see in https://godbolt.org/z/bhescexKc, the lambda version generates the very same assembly code as the imperative version.

The only drawback is that the code is a bit awkward (at least the first time), but when did awkwardness stop any C++ programmer?

]]>Let’s take the std::optional which tries to mimic the Option monad available in other languages. Since 1990 there has been a resurgence of functional programming languages in the mainstream – Haskell (1990), and Scala (2004) just to name two that have Option since their first version.

C++ programmers had to wait until C++17 to receive std::optional. Given the long wait, you’d expect that std::optional works like a clockwork of perfection, wouldn’t you? Improving based on what other languages had, right?. Well… er… not exactly.

The main failure (aside from the long wait) is failing to recognize the monadic nature of std::optional and interpreting the optionality as a glorified pointer.

The std::optional interface is the pointer interface:

std::optional<int> opt{3}; // opt with value; std::optional<int> no{}; // opt with no value if( opt ) // check if the option has a value { std::cout << *opt << ' '; // dereference to access the value }

Insisting on the null pointer paradigm, even after the null inventor claimed it to be a one billion dollar mistake, is beyond my understanding. You forget the check and you get an exception, maybe a modest improvement over the null pointer dereferencing (possibly it is a not so modest improvement, since dereferencing a null pointer is undefined behavior, another twisted contraption of the C++ Language).

Other languages indeed allow the same (wrong) approach:

val opt = Some(3) val no = None if( opt.isDefined ) { println( opt.get ) }

But then they provide also a monadic interface –

val result = opt.map( _*3 ) // if opt has a value, then result is Some( 3*opt.get ), otherwise None opt match { case Some(x) => println( s"x=$x" ) case None => prntln( "no value" ) }

As you can see the map function is safe (no risk to access an undefined value) and is very concise. The only drawback is that the result is enclosed in an Option, that could, sometime, cause a sort of avalanche effect. Pattern matching is another powerful tool that goes hand in hand with ADT (Some and None are subclasses of Option) providing an extremely expressive construct.

Note that even failing to recognize the monad in std::optional, the committee could have provided easy and effective access even if imperative, by considering std::optional as a sequence of one or zero items:

for( n : opt ) { std::cout << n << ' '; }

By simply adding begin()/end() pair and a suitable iterator, std::optional could have worked like this, which is pretty clear and convenient.

For these reasons, I set out to develop my own Option template, with the goal of offering monadic and pattern matching facilities as much as possible in the clumsy C++ ecosystem.

]]>After my last post, I found that Smart Types are also known as Refined (or refinement) Types. And here is a notable implementation for Scala.

Simple things first, if you need a type with a bunch of possible values, don’t use `int`

&` #define`

s, don’t use bool either (please), use enum, or, even better enum class.

Now that we’ve done with the trivialities, let’s proceed to something more challenging – numeric types. Ideally, we want some template code that wraps the numeric type and saves us the boredom of writing all the usual +, -, *, /, ==, !=, <… operators, while letting us define the rules of the existence of the represented type.

I mean, for each smart type, you would have to write an endless list of code like:

```
[[nodiscard]] T T::operator X( T a ) const noexcept
{
return T{ m_value X a.m_value };
}
```

And mostly the same for relational operators.

And there’s no other way since using and typedef just define type aliases so the type checker doesn’t distinguish between them. e.g.

```
typedef int Speed;
typedef int Acceleration;
void f( Acceleration acceleration );
Speed a = 3;
f( a ); // that's ok, Speed, Acceleration and int are indeed the same type
```

Being a C programmer at heart, my first idea was to use macros and preprocessor to craft the arithmetic smart type skeleton. Inspired to X-macros, something like:

```
#define BASE_TYPE int
#define TYPE_NAME Speed
#include <x-smartType.hh>
#undef TYPE_NAME
#undef BASE_TYPE
```

The `x-smartType.hh`

file would have been something like:

```
#if !defined( BASE_TYPE )
# error "Undefined preprocessor symbol named BASE_TYPE"
#endif
#if !define( TYPE_NAME )
# error "Undefined preprocessor symbol named TYPE_NAME"
#endif
class TYPE_NAME
{
public:
[[nodiscard]] TYPE_NAME operator+( TYPE_NAME other ) const noexcept
{
return m_value+other.m_value;
}
// all the other operators (*,/,-,<,<=,==,>,>=,!=)
private:
BASE_TYPE m_value;
};
```

Unfortunately, this approach yields at least two problems – first using the preprocessor is not a well-regarded practice in C++, second it solves half of the problem since you still need to provide the factory methods to construct the objects (remember you cannot just provide straightforward constructor because you need to ensure that only valid values are used).

More precisely using the inheritance relationship is not that straightforward. Consider the sum operation – you can define it in the base so that you can pass derived class as arguments, but the base class can’t return a derived object –

```
class SmartBase
{
public:
SmartBase operator+( SmartBase b ) const noxcept;
};
class Speed : public SmartBase
{ /*...*/ };
Speed a = ...;
Speed b = ...;
Speed s = a+b; // doesn't work
```

The last line above doesn’t work because a+b returns a SmartBase type, while s is of type Speed and either there is no way to convert a SmartBase into Speed, or SmartBase can be converted implicitly in every one of the derived types nullifying the effort to build a smart type.

Also, this doesn’t work because you can use any of the class derived from SmartBase and pass them as arguments, so you can sum Speed and Acceleration, and that’s not good.

Enter CRTP. If we parametrize the base class on the derived type we can write operators with the right types:

```
template<typename T>
class SmartBase
{
public:
[[nodiscard]] T operator+( T rhs ) const noexcept;
};
```

This is just half of the solution because the left-hand side of the sum is not bound to be a T and can be anything derived from SmartBase.

To get the desired result, we need a free function operator. Since this operator needs to access the implementation, it has to be declared as a friend –

```
template<typename T>
class SmartBase
{
public:
friend [[nodiscard]] T operator+( T lhs, T rhs ) const noexcept;
};
```

Now the problem is – how do you implement the operator?

The only way I found is to require that the derived class has a constructor from the numeric type (conversion constructor) and that is a friend to the base class so that methods of the base class can access the conversion constructor.

Moreover, this constructor cannot be called from friends of the base class but needs to be called from member functions of the base class.

For this reason, I defined a set of member functions that implements the operations:

```
template<typename T, typename N>
class SmartBase
{
public:
friend constexpr operator+( T lhs, T rhs ) noexcept;
protected:
explicit SmartBase( N value ) noexcept : m_value{value}{}
private:
static constexpr [[nodiscard]] T sum( T a, T b ) noexcept
{
return T{a.m_value+b.m_value};
}
N m_value;
};
```

Recap – you need operator+ with two arguments to avoid the first argument polymorphically accepting any descendant from the base class. But operators are friends of the base class, therefore they can’t build the result. Since the derived class is a friend of the base class, then only methods of the base class can build a derived object. So this requires a set of static functions that implement the operator.

I’m aware that this is a bit convoluted and still requires CRTP and base class to befriend the derived class, but it is a small price to pay for generic smart types that can easily make your code safer and stronger.

And … tah-dah, that’s all. All the pieces fall in place and you have a smart type template for C++.

PS: I’m working to make available this source code and others as well, just don’t hold your breath

]]>At the dawn of the computer age, it was just bits and bytes, wire and silicon (or relays and vacuum tubes) containers for ones and zeros. The need for abstraction led the early programmers to define different kinds of data: boolean, integers, floating-point numbers, strings. These types were a huge step forward because let engineers handle things they were used to handling – arithmetics, and symbols.

This brought an interesting practical property – while no one prevents you to combine bits with bits, regardless of their meaning, you may feel uneasy to sum integers with booleans. By trusting language and compiler, the programmer could get an extra review of the code she/he wrote, finding subtle mistakes about how values are handled and passed around.

For an extremely long period of time (relatively speaking), programmers cheerfully used language built-in types to encode a large set of information; happy with some feedback from the compiler when they tried to pass an integer when a pointer to char was expected.

So far so good, isn’t it?

Now let’s consider the following API –

```
void newWindow( int width, int height, bool showInFront );
```

Well… It may make sense, but let’s take a closer look.

Let’s start from the `showInFront`

parameter. The author declared it as a boolean, only because the new window can be either in front of the other windows, or not. But besides the fact that it can have only two values (in front/not in front), there is no other relationship with the concept of bool. In other words, using True to say that the window is in front and False to say that the window is behind is just a convention. In fact, when you read the API call like:

```
newWindow( 320, 200, true );
```

You can’t figure what the third argument is, until you look up the API definition to read the parameter name. The only advantage of using a boolean type is to avoid the chance of using a value of range.

A better approach would be to use an `enum`

(even better an `enum class`

) to give a better name to the type and to improve the readability.

And now let’s focus on the first two arguments. If you have spent some time on first-gen PC hardware, then you will recognize a standard resolution, and either from this or from your analytic geometry class you know that first number is the horizontal value and next there is the vertical value. But if you just finished handling matrices you may be tempted to consider the first argument as the number of pixel rows (vertical resolution) and then the number of pixel columns (horizontal resolution).

Some languages (actually quite a lot, but C++) offer a “named parameter” convention that you can use to partially solve this ambiguity:

```
newWindow( width=640, height=480 );
```

Is there a way to avoid the confusion and let the compiler catch this kind of mistake? (spoiler – yes)

The solution is simple (once you know it) and straightforward. Push the concept of types a bit further. In fact, nothing prevents me to define a specialized `int`

to represent only horizontal resolution. If I carefully avoid implicit conversions, I can be sure that I can’t accidentally pass an Width where a Height is expected. This new API would be written like:

```
void newWindow( Width width, Height height );
```

One notable aspect is that the name of the type matches the name of the argument and this is the ultimate goal – no two parameters may have the same type unless you can safely exchange one with the other (e.g. `min`

and `max`

functions).

Smart types bring additional benefits. Consider the Speed type. Since you control the creation and the access to the value, you can no longer misinterpret the measure unit – you could design your API so that the name of the factory method clears any doubt about the interpretation of the *dumb* type:

```
class Speed
{
public:
static [[nodiscard]] Speed fromKilometersPerHour( float kph ) noexcept;
static [[nodiscard]] Speed fromMetersPerSecond( float mps ) noexcept;
[[nodiscard]] float asKilometersPerHour() const noexcept;
[[nodiscard]] float asMetersPerSecond() const noexcept;
private:
explicit Speed( float theClassKnowsWhat ) noexcept;
};
```

This may resemble the dimensional analysis, but is way simpler to implement and is part of a general approach to types.

Another brilliant application is with data validation. When you get strings from an external input, it is a good practice to validate them in order to prevent that malicious (or clumsy) content becomes interpreted (as in the infamous SQL injection). Adding the smart type `ValidatedString`

the can contain only validated strings, then you avoid the problem entirely because

- It is clear if a function accepts any string or needs a validated string
- an unvalidated string cannot be mistakely passed to a function that doesn’t properly handle it.

Eventually I leave you with one last example to remark the power of smart types – Division. The function division is defined for every pair of numbers (a,b), but when b is 0. Historically two approaches have been used when the divider is 0 –

*someone else problem*approach, i.e. raise some form of exception;*garbage in – garbage out*approach, i.e. you’ll get an invalid response in the form of NaN.

Both are not really solutions to the problem and in both cases error handling is a pain in the neck, to the point that often the programmer tends to ignore the problem.

From the functional programming land a third approach is available – wrap the result in an Option. If the division is defined then the Option contains the result, otherwise it contains nothing. Although elegant, managing this kind of result is not effortless. In order to get some result, you should move everything into a flatMap or in a for comprehension – which is a construct not (yet) available in C++.

Enter Smart Types – just define a `NonZeroNumber`

type to use as a dividend and you’ll be unable to express an invalid division. And that’s not error-recovering at run-time, but error-prevention at compile time, which will cost zero during the execution.

I changed job quite a lot and I feel so lucky and grateful to have met so many wonderful people. Always. Everywhere.

With many of them I’m still in touch, and with others I feel we’re still connected even if we don’t talk or write since a long time.

This post is just this – to all the people I met on the workplace, from ABB Elettrocondutture, Ubisoft, Webplan, Dylogic, MR&D Institute, Ovosonico, Tecniplast and SISSPre, thank you all for the good time we shared, the things you taught me and for being kind and welcoming.

Ad Astra!

]]>