Compbolt is library with a stable and hard to misuse API.
The functionality of this library is to calculate compounded interest... but the real purpose is to test Matt Godbolt's suggestions from "Correct by Construction: APIs That Are Easy to Use and Hard to Misuse - Matt Godbolt - C++ on sea" on a high-level language.
Matt gives us the example of a stocks trading API that is implemented in C++. Because we wanted to test what we saw there on a high-level language, we picked Python.
Tinytypes are a concept for creating distinct types even for simple -but important- values, instead of utilizing types only for complex structures. Price and Quantity, for example, are not values that you want to put the one in the place of the other, so the more hard is to do this, the better.
The main thing we try to avoid is :
Before we go to a tinytypes example in Python, we need to mention that Python, in contrast to C++, does something to help to enforce clarity - but hold on after this, because there is still good potential into using tinytypes.
What Python does to address the exact issue, without tinytypes, is that it allows for a function to enforce calling it only with the names provided for each parameter. For example :
The problem with the * solution is that you don't get any error. Yes, it helps the programer to see better what he is doing, but still, if someone mistakes the one for the other, nothing will stop this from running.
Given a complex data flow, a big number of functions and the existence of high-order functions, you need something that not only it makes it visible to your eyes that it's wrong but... that it will stop you as well if you make a mistake. With tinytypes, if you pass a value of type Quantity where Price is expected, you will get an error.
Tinytypes can also improve domain-specific logic. Instead of checking in each function that you expect a Price if the value is negative, tinytypes offer the option to centralize this and just make the tinytype check it's self. This way, wherever you expect a parameter of type Price, you can be sure that it won't be negative. (This could be called... tiny-OOP and it's just an extra, that's not the best of tinytypes.)
Price as a tinytype would simply look like this :
A full example of tinytypes follows below:
Another clarity concept.
There are times that instead of waiting for a number, someone needs a specific set of numbers.
For example, for compound, only the numbers :
- 1 for annualy
- 2 for semi-anually
- 4 for quartely and
- 12 for monthly
Anything else, in the context of our example, is a bad idea, specially 365 for daily or 52 for weekly, they both can be tricky, since they change according to the year.
Let's say now that we want to express this with code. One way is to make our function to check, once it's called, that the compound is one of the numbers that we like. But this way, the caller doesn't know this, and will get an... unfair... error because we don't want compound to be 365 but we didn't made it crystal clear.
With enums, we can express this in our code and exclude weekly and daily in a very cool way.
Now, our function makes it clear what are the options for compound.
Enums can also be used for better state management. Instead of states existing magically in our code, we can have an enum that specifies each state. This, not only makes our work more reliable, but adds to better readability and maintainability.
RAII stands for "Resource Acquisition Is Initialization".
In the context of higher level and garbage collected programing languages is not needed.
Matt gives a more self-explanatory terms for this, "Constructor acquires, destructor releases". It's all about how you can free memory in a more streamlined way instead of throwing memory allocations everywhere and then based on your understanding of your code to free them.
With this methodology, when you create an object (since he is talking about C++) you acquire memory and when you destroy it you free memory.
A nice abstraction over memory management.
.png)

