C++ vs Rust

The following code uses features from C++20 and QN Adv C++ course that uses Concepts
// At this moment I have a vague idea on how I would do it in Rust; is it even worth the effort..

@APalley
@MichaelLewis

C++:
// Test101ActorConcepts.cpp
//
// Simplest example of a system. Context diagram consists only
// of Input and Output systems.
//
// We use C++20 Concepts to replace V1 (outdated) policy-based design (PBD)
//
// Composition
//
//  V2: design using C++20 Concepts
//  V3: V2 + embedded actors
//
// Problem now becomes a pipeline Source -> SUD -> Sink
//
// Summary: this approach is feasible, so worth investigating..
// 1992 .. everything is an object
// 2024 .. everything is an actor
//
// (C) Datasim Education BV 2015-2024
//

#include <string>
#include <iostream>
#include <type_traits>
#include <mutex>
#include <agents.h>

// Interface contract specification
// 1. Each concept is an abstract method
// 2. interface == concept conjunction (e.g. ISUD)

// 1. Define abstract methods (building blocks)
template<typename Message, template <typename Message> class T> // abstract method
    concept ISource = requires (T<Message> x) { x.message(); };
template<typename Message, template <typename Message> class T> // abstract method
    concept ISink = requires (T<Message> x, const Message& s) { x.print(s); };

// 2. Interface relating to context diagram; cojunctional concepts are an alternative
// to multiple inheritance but no danger of fragile base class problem
template< typename Message, template<typename Message> class Input, template<typename Message> class Output>
    concept ISUD = ISource<Message, Input> && ISink<Message, Output>;

// Agent actor-based constraints
template<typename Derived>
    concept IActor1 = std::derived_from<Derived, concurrency::agent>;
template<typename T>
    concept IActor2 = requires (T x) { x.run(); };

// 3. Interface relating to defining constraints pertaining to Actor technology
// https://learn.microsoft.com/en-us/cpp/parallel/concrt/asynchronous-agents-library?view=msvc-170
template<typename Derived>
    concept IActor = IActor1<Derived> && IActor2<Derived>;
  
// The mediator using template template parameter "trick" => can use generic messages
template <typename Message, template <typename Message> class Source, template <typename Message> class Sink>
                requires ISUD<Message, Source, Sink> &&  IActor<Source<Message>> && IActor<Sink<Message>>
    class SUD : public concurrency::agent
{ // SUD is in a chain from Input to Output

private:
    concurrency::ISource<Message>& _source; // formerly known as src
    concurrency::ITarget<Message>& _target; // formerly known as snk
public:
    explicit SUD(concurrency::ISource<Message>& source, concurrency::ITarget<Message>& target)
        : _source(source), _target(target) {}

    void run()
    {
        Message info = concurrency::receive(_source);
        concurrency::send(_target, info);

        done();
    }
};   

// Instance Systems
template <typename Message>
    class MySource : public concurrency::agent
{
    concurrency::ITarget<Message>& _target; // send to SUD
    Message _msg;
public:
    explicit MySource(const Message& msg, concurrency::ITarget<Message>& target)
        : _target(target), _msg(msg) {}

    Message message() const
    {
        // Get data from hardware device
        return Message(_msg);
    }

    void run()
    {
        concurrency::send(_target, message());

        done();
    }

};

template <typename Message>
    class MySink : public concurrency::agent
{
    concurrency::ISource<Message>& _source; // received from SUD
    int _id;
    Message info;
    std::mutex myMutex;
public:
    explicit MySink(concurrency::ISource<Message>& source, int ID = 0) : _source(source), _id(ID) {}
    void print(const Message& s)
    {
        std::lock_guard<std::mutex> guard(myMutex);
        std::cout << "\nin a sink: " << _id << ": " << info << std::endl;
    }

    void run()
    {
        info = concurrency::receive(_source);
        print(info);
        done();
    }

    double compute(int val)
    {
        info *= val*_id;
        return info;
    }
};

int main()
{
    { // Single sink
        using Message = std::string;
        Message m(" good morning");

        // All actors access (read from/write to) a single buffer
        concurrency::overwrite_buffer<Message> buffer;
        MySource i(m, buffer);
        SUD<Message, MySource, MySink> s(buffer, buffer);
        MySink o(buffer);

        i.start(); o.start(); s.start();
        concurrency::agent::wait(&i); concurrency::agent::wait(&s); concurrency::agent::wait(&o);
    }

    {    // Multiple sinks
        using Message = int;
        Message m(23);

        // All actors access (read from/write to) a single buffer
        concurrency::overwrite_buffer<Message> buffer;
        MySource i(m, buffer);
        SUD<Message, MySource, MySink> s(buffer, buffer);
        MySink o1(buffer, 1);
        MySink o2(buffer, 2);
        MySink o3(buffer, 3);
        i.start(); s.start();
        o1.start(); o2.start(); o3.start();
        concurrency::agent::wait(&i); concurrency::agent::wait(&s);
        concurrency::agent::wait(&o1);
        concurrency::agent::wait(&o2);
        concurrency::agent::wait(&o3);

        std::cout << "\ncompute: " << o1.compute(2) << '\n';
        std::cout << "\ncompute: " << o2.compute(2) << '\n';
        std::cout << "\ncompute: " << o3.compute(2) << '\n';
    }

    return 0;
}
I’d be interested in seeing the Rust version.

It seems like most in this thread don’t see Rust as a C++ replacement. But I’d still like to see some comparable programs to make the decision a bit more concrete.
 
I’d be interested in seeing the Rust version.

It seems like most in this thread don’t see Rust as a C++ replacement. But I’d still like to see some comparable programs to make the decision a bit more concrete.
I understand.
Have you tried some examples in Rust?
 
Just out of curiosity, I would be interested in technical (not idiosyncratic, altho' they exist as well) reasons for choosing Rust. I have 35 years C++ exposure and I learned essential Rust in about 5 days. In a sense it is an extreme mini C++.

Channels have potential but they are nowhere near a decent Actor framework IMO.
Maybe the reason: if you are not comfortable with C++, then it might be an option. But its support for OOP and generics is a culture shock. In fairness, it has traits, but then so has C++20 Concepts and more.

I have not seen much on C++ language and Boost library interop.

I could be wrong but at this moment (1st impressions) Rust is a (low-level) systems language. It is unclear to me how it models higher-level abstractions etc.
 
Last edited:
Just out of curiosity, I would be interested in technical (not idiosyncratic, altho' they exist as well) reasons for choosing Rust. I have 35 years C++ exposure and I learned essential Rust in about 5 days. In a sense it is an extreme mini C++.

Channels have potential but they are nowhere near a decent Actor framework IMO.
Maybe the reason: if you are not comfortable with C++, then it might be an option. But its support for OOP and generics is a culture shock. In fairness, it has traits, but then so has C++20 Concepts and more.

I have not seen much on C++ language and Boost library interop.

I could be wrong but at this moment (1st impressions) Rust is a (low-level) systems language. It is unclear to me how it models higher-level abstractions etc.
I’ve never really done systems programming so I can be wrong, but based on your statement, it sounds as though it’s more akin to a C replacement than a C++ one.
 
Last edited:
I’ve never really done systems programming so I can be very wrong in this statement, but based on your statement, it sounds as though it’s more akin to a C replacement than a C++ one.
I'd agree there. We are using it as an essential C replacement for now. Maybe folks will give it a go to create an analytical library with it, but it won't replace C++ in that regard in finance land. Certainly not for many many more decades I'd say.
 
I’ve never really done systems programming so I can be wrong, but based on your statement, it sounds as though it’s more akin to a C replacement than a C++ one.
Feels a bit like that.
Analogy? If a house were built using different languages, then we get a Rust programmer to do the (low-level) plumbing work.
C might be >> Rust?
 

Hey folks,

This is as short a series as one can be: just removing myself as maintainer of
the Rust for Linux project.

I am retiring from the project. After almost 4 years, I find myself lacking the
energy and enthusiasm I once had to respond to some of the nontechnical
nonsense, so it's best to leave it up to those who still have it in them.

To the Rust for Linux team: thank you, you are great. It was a pleasure working
with you all; the times we spent discussing technical issues, finding ways to
address soundness holes, etc. were something I always enjoyed and looked
forward to. I count myself lucky to have collaborated with such a talended and
friendly group.

I wish all the success to the project.

I truly believe the future of kernels is with memory-safe languages. I am no
visionary but if Linux doesn't internalize this, I'm afraid some other kernel
will do to it what it did to Unix.

Lastly, I'll leave a small, 3min 30s, sample for context here:
-- and to reiterate, no one is trying force
anyone else to learn Rust nor prevent refactorings of C code.
 
Last edited:
QUOTE

I think you shall not use C++.
It is too difficult for you. You cannot comprehend. You CANNOT use it. It is too UNSAFE.
It uses abhorrent pointers. And malloc. And free. And these pesky new and new[], delete and delete[]. Nightmare. Not talking about the templates. You cannot understand templates. And the virtual methods. And pointer to methods. And lambdas. WTF. C++ is not for you.
Mmm, why nobody wrote an OS in Go or Rust? Because the OS writers do not like the safety. They like page faults, invalid addresses and that awkward assembly language, so unsafe. And every compiler can outperform you in that assembly, why the heck someone still uses it?
Learn Rust. Or Go. There everything is clear. You can sleep calm.
So, bottom line:
You CANNOT learn C++.
I CAN.
You - NO.
Me - YES.
Haha.
If, by any chance, you got annoyed by my post, I strongly suggest you to work out your issue with a psychologist.
And no, your anger does not bother me. I will continue my happy life, but you will darken your days, as you allowed yourself to get annoyed. But that is your choice.
Have a great day!
 
Back
Top