I take advantage of this anecdote to write a long diary to share my experience and my learning, hoping to teach you new points of view.
Maybe it's worth making a fuss about… Tell me in the comments. 😉
My professional career as a C developer started in 1994 and I naturally enthusiastically adopted C++ in 1999. I was a happy C++ developer and considered the new version of the C++11 standard just a long-awaited evolution.
But in 2015, I finally realized how much C++11 had revolutionized the C++ ecosystem and its upheavals in the mindset of the C++ community. I then became passionate about C++11, C+ +14 then C++17, I get involved a lot, I become a referent for my colleagues, I give conferences on C++, I organize Meetups in Paris, I publish many C++ articles on LinuxFr.org…
However, in 2018, an experience radically changed the way I approach software development. At that time, a C++ team found itself overloaded and could not implement all the expected functionalities. We think about a backup solution, and here I am in charge of developing an application in Python by integrating bricks under free license. I then work in close collaboration with end users and we release the application in a few months.
My new vision:
The DIY application in Python gives complete satisfaction. Users are happy to have had their tool very early on, and it cost less compared to an entire C++ team in its ivory tower.
Warning, I am not denigrating C++, it can be a good solution to many problems. But before running headlong, please ensure that the chosen technology will respond well to the unexpressed expectations of the end user. an intermediary (MOA, MOE, Business Analyst, Product Owner, Architect, etc.)
We may have all noticed it already, the end user does not really know what he wants, and has great difficulty in clearly expressing his expectations in writing. An intermediary (MOA, MOE, BA, PO, Archi) is necessary to allow him to take a step back to translate a functional request into a technical requirement.
But the intermediary adds an intermediate layer! It's human, the intermediary will tend to make himself indispensable. And without doing it on purpose, the intermediary will prevent developers and users from exchanging directly.
The best thing is to have the end user on your development team, even if it's not in the same office. With remote work habits, developers and users can chat regularly.
The ideal duration of a sprint is the day. In the morning, we quickly discuss with the client what we could do, we hard at work, we deliver, the user can test, we re-deliver… And, at the end of the day, we debrief very quickly.
The interest of Python (compared to C++) in this mode of operation is the delivery: we can afford to directly deliver the source code and presto the user executes the application! Thus, in my case , when the user launched the application start, the master branch of the Git repository was automatically updated. I still tried to notify him when a new version was on the master branch.
The joy of delivering often, quickly, and getting feedback straight away :-)
We could caricature:
¹ Using Pythran/PyPy/Cython/Numba/… speeds up execution, but it slows down development: slower compilation, more complex development, difficult bug to investigate…
Often the end customer needs a feature quickly, even if the execution is not super optimized. By delivering this feature quickly, the customer matures and has new ideas, new ways to optimize your work… and so on with short iterations.
For an existing application, we need to provide a basic WebSocket interface so that our customers can access a Subscribe/Publish service.
I'm developing the feature using Python and Socket.io. The JavaScript tests are conclusive. However, we find that Socket.io adds its protocol on top of the WebSocket protocol. So we will force customers to use Socket .io which is not acceptable.
We want to offer a simple WebSocket so that the customer is not locked into one technology and is free to implement their software as they wish.
I then orient myself towards WAMP with Autobahn… But again the P in WAMP stands for Protocol.
So as not to reinvent the wheel, I am therefore looking for a solution that already implements the Subscription/Publishing functionality and ideally with coroutines (async
and await
).
It was then that I discovered uWebSockets (µWS), a breathtaking C++17 implementation that integrates Subscribe/Publish functionality while retaining the basic WebSocket protocol . \o/
My team is enthusiastic. I clone the project, adapt a C++ example to our needs and present a convincing result. It's nice to compile a C++ project that doesn't pull dozens of dependencies :-)
I should point out that for this new project, I have just joined another organization, and I was hired, in part, for my in-depth knowledge of C++17.
In Python, Node.js, Ruby, Go, Rust we have pip
, npm
, gem
, go-get
, cargo
which simplifies downloading of dependencies, and integration into the project with a import xxxx
. Additionally, some IDEs support this dependency management.
In C++, dependency management and compilation are not standardized. In fact, it hasn't evolved much since the origins: C++ is 40 years old and is still compiled in the same spirit as C, which is 60 years old.
For this, we have the choice of the compiler, of which here is a selection with their dates of birth:
For software construction (build), we have a dozen tools to abstract us from the compiler, here is a small selection under free license:
And to abstract ourselves from these software building tools, we use build configuration generators, of which here are still active projects:
With the above tools, building and non-regression testing of a large C++ application can sometimes take half a day. That's way too much to wait if what we have implemented is correct!
Other software construction tools have therefore been developed with the aim of building/testing in a minimum of time:
These projects do not reuse the build tools mentioned above, and do not generate the IDE project files.
On the other hand, these tools finely analyze the dependency graph, manage large source code repositories, parallelize the software construction on all the cores (CPU) of many machines (cloud). The build steps are memoized to avoid redo the same operation N times (for example, to avoid compiling an unmodified file, or linking an unchanged library).
Without having to resort to these tools, we can improve C++ compilation and linking times with these two good old tools:
These ccache
and distcc
tools are supported by CMake, SCons…
But by the way, how do you manage C++ dependencies?What is the official C++ package manager? (manager package)What is the C++ equivalent for pip
, npm
, gem
, go-get
commands and cargo
?
Well… let’s say we have some encouraging initiatives:
Be careful not to confuse the b
executable of the build2 project with the b2
executable of the Boost.build project mentioned above.
Another way to very easily manage your C++ dependencies is to simply copy the source code of these (and also the source code of the dependencies of the dependencies) with the source code of the application. It always compiles.
But this is not good practice for at least two reasons:
I am testing different ways to obtain the uWebSocket package: the package manager of my distribution, Conan, Hunter… and finally, the uWebSocket package has recently been integrated into the vcpkg repository . I test, and, miraculously, it downloads the source code and installs it on my GNU/Linux distribution!
The vcpkg tool works with CMake, so it will be CMake that will manage the software construction. The time to document and get familiar with vcpkg, to try to integrate it into my CMakeLists.txt
, to fail, to start again...
However the example with SQLite3 works for me… Arg… In fact, it is poorly packaged, the find_package()
will never be able to find the uWebSocket library provided by vcpkg.
I try to do it myself. Then, I realize on the second day that vcpkg is an amateur tool, not to be used to go into production: no version of dependencies, impossible to decide on the options for compiling dependencies...
Well, I know C++ well, so properly packaging a library that doesn't depend on anything shouldn't be a problem.
I roll up my sleeves and start looking to see if anyone has ever packaged uWebSockets…
I especially find that the main maintainer deleted the CMakeLists.txt
and meson.build
files in 2017. And this one seems to send compatibility contributors upside down with CMake, removes the title from Pull Requests and there are even deleted comments.
There is an explanation in the FAQ:
Basically, the main maintainer refuses any software build system, because developers want to use different tools and for the same tool, developers do not agree on the right way to do it.
A very surprising commit is the Not my problem which changes the license and replaces in all files the line:  Copyright 2018 Alex Hultman and contributors.
by:  Authored by Alex Hultman, 2018 -2019.
  Intellectual property of third-party.
My favorite IDE for C++ is QtCreator, but it doesn't support Meson yet. And I don't have much time to get started with GNOME Builder.
And I get a nice CMakeLists.txt
that works on two different GNU/Linux distributions and also on GitLab.
I also realize that GCC-8 does not compile this library, and that we need to use only Clang.
But my biggest problem is that I can no longer get this library compiled by QtCreator, whereas with the command line it works perfectly... Arg... I'm still investigating some time...
My colleagues don't understand why I'm taking so long to do the equivalent of a pip install
in C++. In addition, I will have to redo this same work as soon as I integrate the other libraries: database, message queue, logging...
We decide together to stop being obstinate, to raise our heads, and to list the possibilities:
I have several colleagues very competent in Node.js, so here we go. Indeed, the installation of the dependency is very simple and the application is quickly implemented.
The great thing about Node.js (and JavaScript in general) is the incredible community size and spirit of sharing and innovation. While it takes a decade in C++ to decide, the JavaScript community decides in a few months. Projects, programming concepts, working methods are constantly evolving.
I enter a ship that moves at the speed of light. In C++, the life of a project can be ten years. In Node.js, it's more like 10 months. This is also the disadvantage, you have to adapt quickly.
But, we find that the uWebSockets.js project does not support Subscribing/Publishing the underlying uWebSockets library. It does not work.
Stop, we've just matured, let's see the possibilities:
We are aware that the WebSocket part may be a performance pain point. Finally, we bracket our Node.js attempt.
Rust is still too young (few developers mastering Rust on the market). And we have a fellow DevOps fan of Go.
Our colleague mastering Go is not very available, we learn to manage on our own. Finally, the principal of the Go language is acquired in a few hours of programming. The WebSocket test is a success and we are implementing a first basic version of Publish/Subscribe in Go.
We will set up repeatable performance tests, and only then can we decide which parts need to be optimized.
But, no, I'm not giving up C++!
I appreciate acquiring new strings to my bow, opening my mind to new practices.
Some technologies are more suited to certain contexts. Let's not have dogma, let's choose the right technology according to the situation.
However, I don't know when I'll be coding in C++ again...Maybe when we have a standardized C++ package manager... :-)
A little publicity: Do you appreciate this state of mind and like to code in Python, Node.js, JavaScript/TypeScript/Angular or Go? Feel free to contact me at oli (at) Lmap (dot) org
. We have positions in Paris and Metz. We can arrange for telecommuting. For the moment, we do not release anything under a free license. But I push to release some interesting bricks…
DIRECT. Assassination of Razia Askari in Besançon: "No guilt, no remorse, lack of empathy", the profile of Rashid Askari, accused of the assassination of his wife, dissected
[Video] The Amazing Spider-Man 2: the ultimate trailer
Nantes. He had assaulted a tram driver: sentenced to 6 months, he avoids prison
Samsung AU9000 Test | TechRadar