home page

Welcome to my blog.

In one of my previous articles, "compile-time repeat & noexcept-correctness", I have covered the design and implementation of a simple repeat<n>(f) function that, when invoked, expands to n calls to f during compilation. E.g.

repeat<4>([]{ std::cout << "hello\n"; });

...is roughly equivalent to...

[]{ std::cout << "hello\n"; }();
[]{ std::cout << "hello\n"; }();
[]{ std::cout << "hello\n"; }();
[]{ std::cout << "hello\n"; }();

If you squint, this is a very limited form of compile-time iteration. When writing generic code, I've often needed similar constructs in order to express the following actions:

... read more

I'm back in London from Jacksonville, where I attended my first ISO C++ meeting. Apart from the long flights and long working hours, it has been a very enjoyable experience for multiple reasons:

  • I was able to actively participate in the evolution of the language and influence it by voting and discussing;

  • Seeing the amount of work, the engaging debates, and the formal procedures used to move C++ forward gave me a newfound appreciation for all the members of the committee and for the language;

    ... read more

Simon Brand (a.k.a. TartanLlama) recently published an article called "Functional exceptionless error-handling with optional and expected" where he excellently explains how sum types (e.g. std::optional and std::variant) can be used in lieu of exceptions in order to implement error handling.

The article focuses on the usage of std::optional, on std::expected, and on two monadic operations, map and and_then, which reduce boilerplate and increase readability of the code. While Simon briefly mentions the benefits of ADTs (algebraic data types) over exceptions, I think that the topic deserves more attention, as some readers missed the point.

Here's an example comment from the article's /r/cpp thread:

... read more

In my previous article ("abstraction design and implementation: repeat") I've shown how to implement a simple repeat(n, f) abstraction that invokes a FunctionObject f \(n\) times in a row.

A large part of the article focused on adding a noexcept specifier to repeat that correctly propagated noexcept-correctness depending on the actions performed on the passed arguments. Adding a noexcept specifier resulted in a less elegant, longer, and less accessible implementation.

Is it worth the hassle? Jason Rice posted a comment on the previous article asking:

... read more

You know that you're obsessed with library design and abstractions when a simple for loop like this one...

for(int i = 0; i < 10; ++i)

...greatly bothers you.

What's wrong with it?

... read more

A very rare occurrence on my blog, but this post is not (directly) about C++. Having spoken at several conferences and meetups, creating slides is a task that I've always found unsatisfactory for a plethora of reasons. I want my slides to:

  1. Be quick and simple to create. I don't to spend time manually aligning text and shapes, I don't want to manually go through 10 slides if I decide to update a code snippet.

  2. Seamlessly support code snippets. I want nice and readable inline code keywords and code blocks with syntax highlighting.

    ... read more

In part 1 and part 2 we have explored some techniques that allow us to build simple future-like computation chains without type-erasure or allocations. While our examples demonstrated the idea of nesting computations by moving *this into a parent node (resulting in "huge types"), they did not implement any operation that could be executed in parallel.

Our goal is to have a new when_all node type at the end of this article, which takes an arbitrary amount of Callable objects, invokes them in parallel, aggregates the results, and invokes an eventual continuation afterwards. We'll do this in a non-blocking manner: the thread that completes the last Callable will continue executing the rest of the computation chain without blocking or context-switching.

... read more

RSS Feed