Rust is not an Oriented-Object Programming language. Despite this, Rust borrows some principles from multiple languages
Hi all!
I would like to share this blog article from John Carmack, a legendary figure of the video game industry – with the development of DOOM, Quake... (https://en.wikipedia.org/wiki/John_Carmack)
Although this article was written ten years ago, this one is still relevant about the advantages of functional programming and the parallel with OOP. This concerns the disadvantages of “OOP programming” vs “functional programming”, mainly because it is hard to detect multithreaded and race conditions issues. Also, it delivers a beginning of solution with “how to mitigate it by doing “functional programming””.
Here is a little summary wrote in the article:
My pragmatic summary: A large fraction of the flaws in software development are due to programmers not fully understanding all the possible states their code may execute in. In a multithreaded environment, the lack of understanding and the resulting problems are greatly amplified, almost to the point of panic if you are paying attention. Programming in a functional style makes the state presented to your code explicit, which makes it much easier to reason about, and, in a completely pure system, makes thread race conditions impossible.
In my opinion, C++ is better and better (especially in the last versions of the standard) to execute a first set of “functional programming”, despite the OOP pragmatism and construction around C++.
Don’t hesitate to read it here: http://sevangelatos.com/john-carmack-on/
During the last month, I was training my skills about Rust. In my learning roadmap, it was time to start a personal project. I chose to create a "Run-And-Gun"/"Multidirectional shooters "game in Rust, inspired by the classic game" Sheriff".
To implement it in Rust, I should choose a game engine. Fortunately, I found two significant game engines based on Rust:
The two games engines look great. After few analyses, I didn't find a good reason to choose Amethyst or Bevy. They look similar (Amethyst inspires Bevy) and perform both well. Then, I selected the Bevy engine because it looked easier to use.
My game and sources are free and open sources (don't hesitate to clone it or test!). The source code is under MIT license and sprites under Creative Common License. Don't hesitate to check the code on my GitHub!
Another point, the game is available in WebAssembly on the web! You can try it on this webpage (Controls: Arrow to move, Space to fire).

My video game Street of Zombies- Programmed with Rust and Bevy
Bevy is a data-driven game engine free and open-source (license MIT). The engine has many features that convinced me to use it:
All around Bevy, there are multiple Third-P plugins developed by several contributors. In my case, I used the bevy_webgl2 to support the rendering in a wasm target! Other Third-P plugins are available, such as a ".tmx" support (a file format generated by tiled, based on XML).
As I said in the introduction, I created a game based on the classic game arcade by Nintendo, "Sheriff".

Sheriff - A run&gun arcade game. By Nintendo
The game principle is simple: The player moves on a game arena in four directions. The goal is to avoid the projectiles fired by the "bandits" on the border. To win, the player should eliminate all of them like a classic "Space Invaders". It was my main inspiration, but I completed the game with other features:
I also had other ideas, such as weapon management (multi-shot fire, camera movement). However, I didn't take the time to implement those ideas as the game is playable right now. Maybe a next time?
As I have no experience in game development (Excepted in some projects in schools), I checked the examples provided by Bevy. One of them was a great source of inspiration thanks to its 2D format and movements: The breakout.

The breakout game featured the Bevy's example.
I used the system to move the "pad", and I adapted it for my player. Then my first function, "keyboard_capture", was created with few modifications to support "diagonal movements". I started a new trait, "MoveableSprite", which represent a "Moveable entity" with three main variables:
Now, let's modify the sprites, and I obtain the beautiful squares to test my movements:

How a "Moveable" 2D sprite is represented in my game
Now, let's use those "MoveableSprites" to create my enemies and projectiles.
It is where I made my worst error: The usage of a trait for the moveable sprites. I quickly featured this error during one of my previous posts concerning design patterns on Rust.
By defining the "Trait", I re-implemented the methods to retrieve and set the speed, direction, and position of the entity for each structure: "Player", "Enemies", and even "Projectiles"! I copy the same code, the same test and the same documentation for all structures. Something is wrong!
First, I was slightly concerned about this. But quickly, when I added the "Hitboxes", "Initial Position", and others, the code started to smell, and I was overwhelmed by my mistake!
I created this trait like an inheritance in an OOP language.
As I described previously, the consequences were terrible.
The solution is a traditional good practice for OOP language: Prefer the inheritance per interface. I transformed the "MoveableSprite" trait into a simple "Struct" and moved my "movement methods" inside it. Then, the code was more straightforward and more efficient!

Inheritance per interface for a "Player" structure. Player can access to MoveableSpriteData
The following things are more anectodical. I will summary one of the Bevy add values in my project with the projectile movement and collision systems.
"Projectiles" are managed by "Weapons", a structure that regulates the fire rate, the number of Amo, and the time to reload the weapon (valid for the "enemy AI", which has a cooldown between each burst of fire). Each entity Player or Enemy contains a Weapon.
Concerning the projectiles movements, Bevy plays its part gracefully by using two "Bevy" systems based on projectiles. Those two methods are directly managed and called by the game engine!

The movement system. Based on a "Bevy" call.
The system is the following: Each projectile created contains an "ID" created by Bevy. Thanks to those IDs, Bevy select a set of data where are collected:
When a weapon fires a projectile, all those data come from this single "ID".

The method from "Weapon" which fires a projectile. The red frame represents the creation of a projectile on Bevy.

This part is executed by "Bevy" frequently. It checks if a "projectile" hits a Player or an Enemy hitbox.
Here, the collision system is a loop that retrieves all my projectiles all around the game area.
For each projectile, I match with the "Player" or list of "Enemies" (following the type of projectile) to check if there is a "Collision". The collision is detected thanks to the "Moveable Sprite" structure where the position and the "hitbox size" is contained. A "collision" gears an update of the Scoreboard (Player Health/Score) and the enemy structure (Enemy health/Enemy destruction if life equals 0).
Now, I have a prototype where a player launches projectiles on a single enemy.

The prototype of my game! Player and Enemy move. Projectile and collisions, OK!
Let's continue to code!
Now, my "Game System" is complete. It is time to make up the game! As I have few talents in graphical design, I looked for free sprites only. Fortunately, I found Sprites under Common Creative License (a huge thanks to the contributors!) that are beautiful. I modified and merged the format for my blog:
An example of SpriteSet from my game "Street Of Zombies"
Now that I have my sprite sets, I cut them per line and columns with Bevy. The management of 2D sprites is logical and user friendly! All the sprite management is in my file "sprite_management_system.rs". I enumerated the texture available (one for the player, one for zombies). Then, I generate the sprite on the map after a "Player" or "Zombie" creation. This process keeps the "Sprite" in the same Bevy "ID" to encapsulate resources.
The sprite is created with a "SpriteSheetBundle" from Bevy.
My sprite is selected and loaded from this function.
My sprites are now generated and created in the game area. Unfortunately, they are not yet "Animated", and the game looks static.
The next step is to create another "Bevy system" dedicated to the sprite animation. Fortunately, sprites with "Player" nor "Enemies" structures are together in an indivisible "Bevy ID". Then, an "animate_sprite" method can be called with the object "MoveableSprites" to determine "Where the entity is seeing" thanks to the "Direction Factor"!
I complete this task with a timer that changes the animation on a single "Row". If the direction changes, the Sprite Set "Cols" switches to the corresponding one thanks to the "TexturePositionEnum"!
Animation of the sprites in my game "Street Of Zombies".
Great, now the game is completed and animated:

The game is running!
Now that the game is complete, it is time to enlarge the deployment of the game. Currently, it only supports Windows, Mac, and Linux.
After a few research, I saw that Bevy could be deployed in WebAssembly to produce a code integrable in the web.
Fortunately, I found a great and precise tutorial in the unofficial Bevy book! As my game doesn't use audio, I focused on graphic rendering. The principle is the following:
Replace the "WebGPU" official rendering with an unofficial one supporting deployment on a Web Page: bevy_webgl2.
After that, the book proposed two solutions to deploy my application: use "wasm-pack" or "Cargo Make". I choose "Cargo Make" to ease the deployment of my application (it requires more configurations, but the process is automated!). This process needs a kind of "Makefile" dedicated to cargo.
Finally, I modified my "cargo.toml" file to support a "Native" or "Wasm" configuration. The last complicate situation was the "Random Number Generator" support, which required an extra configuration in wasm. Fortunately, the book explained the procedure to use the "getrandom" crate with the "js" feature!
Wasm format should be the smaller possible to accelerate the browser downloading. I choose two solutions that are not intrusive in my build process:
Although my "wasm" file is large (~10Mb), it is better than the default version (~12Mb). This process is not the optimized one, but it automated my build optimization and deployment.
Now, let's talk about the deployment with "Github Pages". Initially, "Github Pages" are used to hosting project pages on a GitHub repository. I created a new empty branch, "web".
This branch will contain all the files to deploy my game on the web. It concerns a javascript file, an index.html and the wasm of my game.

My Github page is created!
During this personal project, I was happy to start game development. Although I don't have any experience with Game Engines, Bevy was intuitive to use. Sometimes, the documentation is not complete, but overall, the performance was significant and user friendly!
I think I made some errors concerning a game structure or usage of a game engine. I only touched the surface of Bevy and didn't expect the impressive number of features I didn't use, such as the UI, scenes, sound, and other features through the Data-Driven system.
Moreover, even if I considered the game as completed, it could support multiple weapons or enemy types. Last, there are no sounds implemented (It is maybe a chance 🙂 ).
Bevy is still in development, but the state of the art is promising for the next steps. It looks like a new version (0.6) is in progress with multiple new features and bug fixes, such as the Android support.
Later, I will choose Bevy again to develop another game. This time, in 3D!
I recommend this engine to initiate a game in Rust! It is promising for the future!
I think that Software Development and Quality is a fascinating subject. It concerns the analysis of tools and practices which improve productivity. This week, I checked an article from Greg Wilson about Software Development and its comparison with the medicine world.
The article explains the lack of evidence base in the Software development world. When we need to prove something in the medical world, we use studies. In the Software world, there are plain of “headlines”, "punchlines" and "tags" without any proof:
Those claims were emitted by the most brilliant guys in our industry, from merited books or academic journals. However, they are not accompanied by any citation or studies.
In a medical context, Those facts are “Not proven” and would not be “applied” to concrete treatment. Some developers use those beliefs on not proven facts: The base is fragile and could be destroyed by a study.
Of course, these facts are “intuitive” and looks like a great way to improve the code base. In my case, I believe that SOLID principles, DRY and others are a significant “landmark” to drive my coding style. However, they are not linked with proved data. Moreover, some of them are misquoted, as explained in the article by Greg Wilson on quote “The best programmers are up to 28 times more productive than the worst”.
Featured by some developers as the “magical pill”, TDD is also a practice with unwillingness for many reasons:
Fortunately, TDD is the subject of many recent studies. They are proof of the benefits and disadvantages of TDD. Without using “tags”, they are a weapon to convince developers and managers about “the goods and evils “of TDD.
For those who do not know what TDD is, I will simplify the definition. It is the process to write the test before the development of a feature. Those short tests are in the “Green Red Refactor” cycle:
Thanks to this process, TDD allows tests to guide the implementation to maintain a supposed “higher-quality” code. Even if it is not yet proven, multiple studies are in progress about the benefits and disadvantages of TDD!
Some of them claim that TDD improves productivity, other that it decreases productivity. Sometimes it depends on the industry. Maybe, it depends on the project size or other!
But overall, in the industry world, current studies show that TDD improves quality, bug count and improves productivity in the long term (when it decreases short time). This kind of evidence is a weapon to convince you to embrace or not the TDD development style.
As you see, the Software world is full of claimed facts. Some developers will feature those claims as a “quality elixir”. I do not think it is an excellent way to improve the software world. Some leaders force the introductions of those facts, which add tensions, without guarantee of quality.
I keep in mind those headlines to guide my own “coding style”, but not to force a complete team without agreements.
Rust is not an Oriented-Object Programming language. Despite this, Rust borrows some principles from multiple languages like C++, JavaScript or Haskell. The language can partially use "OOP" and then some design patterns. My first tentative in Rust was to reproduce those patterns as defined by the GoF. Unfortunately, it was an error, and I got a codebase unclear. For this post, let's check how and why using Design-Patterns in Rust can be a good idea or a trap!
In software development, we encounter and resolve many problems. A design pattern is a reusable solution to a problem type. The practice of those helps to solve common problems during application design. They give to your design multiple benefits: clean code, SOLID principle respect and, essentially, a common language.
Initially, the Design Patterns defined by the GoF serve an OOP language. Then, they are not suitable for Rust! We will see when and how we can interpret some of those patterns in a no-OOP language.
I insist on the word "interpret" or "equivalent": Some of those patterns are hard to apply. Furthermore, class diagrams are not always a good representation in Rust. If you want more details about Design Patterns, I created a post about them.
At first, I tried several times to apply those design patterns in Rust. It is the case in my project, "street of zombie", a run and gun game in Rust. I designed my objects per "structs" and defined some patterns in my code.
Quickly, I started to re-copy some data in another struct. Then I continued until I reached a milestone where my "structs" are similar to mimic inheritance. I tried to code in Rust as I code in C++: Like an OOP language. I made a classic mistake: The patterns defined by the GoF are not wholly applicable in Rust!
Then, I stopped this style of language and reorganized my code. I started to code as I code in C, then I began to use the traits to complete with some known patterns. Now, my coding style in Rust is different from what I do in Java or C++.
Using the "trait" like a "contract", a standard interface for multiple structs, my code became cleaner and more maintainable! Then, I extracted those patterns from my code and compared them with the "official ones":
I will feature (and complete this post) with a few pattern examples in Rust!
Here is a tab about the Design-Patterns in Rust I presented in GrapeProgrammer.com. If I write another post concerning a Design Pattern in Rust, this tab will be updated.
Name | Description | Post | Usage in Rust |
|---|---|---|---|
Composite | Design a tree structure of different components | Usage of "traits" and "dyn" in Box. Adaptable in Rust |
Photo by Barn Images on Unsplash
The composite Pattern is dedicated to creating a group of similar objects in a tree. This Pattern is represented as a tree, where branches are connected to others and finishes with a single leaf.
Remember: I will feature here an example of Composite Pattern, among others. The pattern form depends on the problem to resolve!
The composite Pattern contains an interface with a series of Leaf and Branches.
IComponent is my trait linking the two distrinc objects: Leaf and Branch.

A classic “composite” problem is the file system from our computers!
Indeed, a folder can contain another folder. However, a file cannot hold a folder. If I generalize this with the composite Pattern format:

This is where the composite Pattern helps us. It creates a hierarchy composed of folders and files represented as a tree structure. By dealing with the organization with a contract (The trait), we can complete this complex structure with a scalable code. Here, the client can ignore the differences of the “tree components”.
The following example is an implementation of the “Composite Pattern” for the File/Folder problem.
In this code example, I recreated the following data structure in my function “create_structure()”:

As you see, the standard interface is a “trait” implemented in my “structs” File and Folder.
The “Trait” is my “Contract” usable by the client to print my “Folders” and “Files” content. Then, a simple call to “open_and_print_all()” reaches my tree recursively to publish the texts.
Here, the Pattern was exploitable by Rust because it exploits an “Interface” (represented by the “trait” Component) and not the inheritance features.
Photo by Viktor Talashuk on Unsplash
During my different usages and learning of Rust, I tried to use paradigms from the C++ and Java. After some practice, I was able to reproduce some design patterns in my Rust code. It is a great start to organize my code with interfaces and recognizable patterns! However, Rust is not an Object-Oriented-Programming language… At least, it is the “short answer”, the nature of Rust is complex. Indeed, the OOP deserves an entire chapter in the Rust book!
For this post, I will review with you some characteristics of Rust and why it is or not an OOP language!
I will try to make a short definition because the term is complex. I already made a post about the OOP and its paradigms here. Do not hesitate to check it!
For this post, I will simplify the definition of OOP to the respect of three of the main paradigms:
Let review the three pillars of object-oriented programming language in Rust!
Rust respects the Encapsulation principle! Indeed, it is a simple “struct”:
Polymorphism is the ability to pass a function that will differ following the object type. In Rust, Polymorphism is possible thanks to the “traits”:
Inheritance is one of the biggest benefits of OOP. The key is to provide code re-usability: Instead of implementing the same code in many places, inheritance allows to copy the property of a class to another one.
Concerning Rust, inheritance is not possible: A structure cannot inherit another one. The reuse of the content and functions is not possible. The only key which is closer to this definition is the declaration of default functions in “Traits” … But it is not enough to call that “Inheritance”!
However, I am not surprised: The Inheritance is a poisoned chalice. Indeed, even if the re-usability of code is a great advantage, it complexes the code structure:
Without discipline, documentation, and coding rules, it can trigger a complex and hard-to-read architecture:

Inheritance is beneficial but also one of the most criticized paradigms of OOP.
Rust is a “multi-paradigm” language. In fact, Rust is inspired by multiple languages with various paradigms. It can concern JavaScript, C/C++, Haskell, Swift and others!
However, be careful, it is hard to write Rust code in an OOP style. If you write it as you are using classes, you can run into problems. Indeed, the “Trait” feature is a great way to mimic OOP style. However, remember that “Trait” had been created to define “contracts”. It links multiple structures to a common interface.
Do not hesitate to check this quite interesting story about Rust! It is a great way to start this programming language and how it helps you to write secured and clean code in other languages!
Photo by Christina @ wocintechchat.com on Unsplash
Did you already encounter this issue?
During your work, your boss asks you to add some cool feature to a car app. You are ready to analyze the state of art, you open the source code and… Damned! What happened here? What is this home-made XML parser? Why are we using Unix sockets here?
You continue your investigation and find tab/spaces in the same file. Bad indentation and then, the usage of multiple deprecated standards. No doubt, you are analyzing an old code base not standardized and without coding guidelines.
During my career, on old code base, I encounter some strange patterns: Homemade parsers, re implementation of std::string, multiple usage of C style string in no critical parts… In huge code bases, the number of developers is proportional to the risk of multiple tools integration.
The issue of code without coding guidelines that it increases the general complexity:
However, each teams or individuals want to integrate their own tools. It is the goal of the leaders to control those tools and limit the multiplication of those libraries. I will feature here some simple solution to set standards in your code base.
It is the obvious one, but also the harder to implement!
The first goal is always to communicate with the team about your objectives.
Before each library integration, you should communicate about your intentions. Debate with your colleagues and select a single tool to support this JSON parsing!
The second step is to adopt coding guidelines. A good code guideline consists to give a set of rules for using a code language in a particular environment. A coding standard is always better than no coding standard. Of course, a good standard should be written by someone with solid knowledge about the concerned language.
Therefore, my recommendation is to use an existing code guideline. You have some great examples in C++:
The usage of those guidelines will save you lot of time in the future:
However, be careful: Some software engineer will reject your coding standards. In majority, those are developers with obsolete skills. They will try to ignore your standards and you should defend the value of code standardization.
The goal here is simple: Have a simple set of rules that help developers to edit any part of the code. Important in big code bases!
Do not hesitate to check this quite interesting article from isocpp about coding guidelines.
You defined a coding guideline in your team. Congratulation, you completed the first task!
However, some developers still not respect those standards.
After months, the standards are forgiven. It is important to use automatized tools to support your code standards and force this new policy.
To help the adoption of your guidelines, you should define tools and automatic verification.
The easier to configure is your IDE! There are multiple tools to define code rules and helps for automatic verification.
For instance, you can use the Code Spell Checker in Visual Studio Code.
In eclipse, you have the Static Analysis configuration: StaticAnalysis
For another cases, you can also use some static code analysis tools. Such as CPPCheck.
And here the more important: C++ standards are evolving. Do not hesitate to edit your guidelines with the evolution of C++!
Photo by Vamsi Konduri on Unsplash
Today, I review with you some interesting blog posts!
First, I updated my old post about regular expressions, do not hesitate to review it! You have now new code blocks and extra tests!
This week, during my research, I found an old blog post from Joel Spolsky named “Things You Should Never Do, Part I”.
The post is 20 years old but is still relevant today! It explains why rewriting a code from scratch can be a terrible error for a company.
For me, rewriting a code from scratch is a double or nothing bet. It can be productive in some special cases (Very old code base, new standards, revolutionary technologies, etc.…). However, in majority, it is inefficient and counterproductive for commercial usage. We can dispatch the common issue in two parts: Architectural and Performance.
Concerning architectural issues, they can be fixed smoothly. Time by time, I can modify an interface. This other time, I refactor a class during a development. And again, let us rewrite this single part which is slow!
Trust me, I applied this method during years on an old project. The result today is a code modernized and easier to understand compared to few years ago. First, modernize build tools. Then, refactor the code iteration after iteration is pretty efficient.
Concerning the optimization... Do you have a code which is not performant (slow, memory leaks, etc…)? Let identify the part and do not rewrite the entire code! A simple modification of the concerned part is maybe better for the commercial usage. Your code is immediately deliverable and productive.
Of course, some errors are hard to fix (Threading, shared pointer...). But I doubt it is a reason to throw it in the trash bin.
This post is a particular one. Have you ever been ashamed of your own code? In an ethical way?
I already encountered some questionable decision during my career.
You may know this well-known post from Bill Sourour: The code I’m still ashamed of.
The question of ethical in software is still important: There is a chance that during your career, someone will ask you to code something a little deceitful. This experience from Bill Sourour is touching and terrible. It reveals how you can code something unethical and why it is important to say “No”.
In my personal experience, I already encountered this. Fortunately, leaders were listening, and it was resolved quickly (Just say no and explain why it could cause problems). But I supposed it is not the case for everyone. Moreover, saying "No" is far more easily said than done. You could have terrible leaders which refuses to listen your concerns and stay the course.
In C++, a function object (or functor) is an object which implements the “operator()”. Thanks to this overload, the object call with parenthesis can be launched. With this behavior, your object looks like a function!
During this post, you will see some advantages to use functors. They are more flexible than function thanks to multiple advantages: Encapsulation, virtual functions, and arguments passing!
A functor can be created by overloading the operator():
As you see here, my object is directly callable with the “objectName()” operator. It looks like a function but it is the call to the operator(). Thanks to this behavior, my multiplication looks like a function call.
Functors have a great advantage over functions: Their interactions with algorithms. In the next example, I show you how to set a simple “coefficient factor” in my multiply class. Then, this factor will be applied to an entire array smoothly!
In this example, I construct my object with a variable equal to 2. It is my coefficient factor. Combined with the function object “myMultiplicator”, I can multiply all elements in my list by my CF!
This is a simple example of functors usage. We could go further by using virtual methods. Or even templates!
You are certainly thinking that functors are like lambda expressions.
In fact, a lambda expression is a “nameless functor”. The only difference is about the complexity of your code: A lambda expression is simpler! Indeed, functors are taking few additional hidden data in C++.
This similitude is explained by the goal of a lambda expression: Lambdas are designed to create a “function object” capable of capturing variables in scope.
Another great advantage: You do not need C++11 specification to use functors. Indeed, functors are a great alternative to lambda expression if your job does not permit the usage of C++11. It is the case in multiple big company with huge code base.
Don't hesitate to exploit functors. It is a good alternative to lambda for multiple complex situations.

In C++, a developer could define a “const method”. This “const method” is useful to guarantee that the method will not alter your variable.
In the world of encapsulation, it helps developers to develop secure and understandable code. It guarantees that the method will not alter the concerned object. It gives a mark of confidence and improve the code cleanliness! We will see during this post how to improve your code quality with the keyword “Mutable”!
mutable – “permits modification of the class member declared mutable even if the containing object is declared const.”
In my previous post about the "const" case in C++, I quickly introduced this keyword. Let's see how to use it!
As I featured previously, C++ developers creates classes with several encapsulated variable (obviously). Sometimes, they declare a special method type, “the const method”:
This technique guarantees a method which return data and does not modify the object. It is useful for code quality and easy maintenance. A fresh developer can immediately see the purpose of the method. Overall, he can exploit it without unexpected knock-backs.
However, sometime, we can have a requirement to modify one or multiple variables. The best example is the mutex usage.
The solution is the keyword “mutabe”.
This simple code example does not compile without the “mutable” keyword (try it!). It is due to the mutex which is acquired and released during the process.
However, should we sacrifice the code cleanliness? Should we convert the function as “no-const”? No, the “mutable” type specifier is a great solution! It specifies that your variable can be altered even in an object declared as const!
Most of the time, a mutex will be mutable. Because it is really helpful to consider a “const” as thread safe. The mutable keyword helps you to use internal mutex in const method.

It is the first post of my website for 2021. Many thanks to continue reading my blog. I wish you all the best for the New Year 2021!