Modern programming languages have a lot of useful features. This includes traits, inheritance, operator overloding and many more. I was making an intermediate representation to support all those features, but it become overwelming, so here I am breaking those down.
We are gonna be using C to implement broken-down versions of patterns. That is because C doesn’t have any of them. And manual memory management will help us understand what is going on under the hood
Modules, or namespaces, can be found in most modern languages. They help separate code into reusable segments. Modules (not namespaces) in dynamic programming languages can also be lazily-loaded. Yet we will only focus on namespaces here. Let’s look at the following C++ snippet:
int
This grouping of functionality can be represented in C using prefixes:
void
int
Note: As a good coding practice, it’s better to move grouped functionality into a separate header file!
Starting off simple. Methods are essential feature of most modern programming languages. And yet, C doesn’t have that. Let’s look at this simple C++ example:
;
void
int
Here we can see a class, that has a field called player_position and a method called update. But how does this method knows about player_position? Let’s modify the hit function:
void
Now we can see the hidden this
pointer that is used to access fields under the hood.
But where does it come from? Let’s look at a language that shows it more explicitly,
for example, Python:
-=
AHA! self
(alternative to C++’s this
) comes as a special argument!
We can now try to replicate this behavious in C:
;
void
int
Generics (or templates) are a way to make container types and reuse same code for multiple types. Consider this C++ example:
;
int
Under the hood compiler just creates the same struct for all types it’s used with. We can’t replicate all the syntactic sugar, but we can utilize macros to make this in C:
;
int
Be aware: any typedef-ed type will resolve to a different name!
Note: A ## B
in a macro converts to AB. It’s a token pasting operator, you can read more about it here
Another note: Zig also uses a similar approach to emulate generics
Inheritance is a useful feature in multiple OOP-oriented programming languages. It allows reusing functionality from parent’s class by multiple children
Look at the following C++ example:
;
;
int
To recreate this in C, we can utilize a different concept - composition (yes, they are normally looked at opposites, but one can be implemented with another). This also plays nicely with C++’s ability to inherit multiple parents Here is the implementation:
;
void
;
void
int