Blog

Concurrency, Text DSLs, and Soft-Robots

Posted on 2026-07-02

Every embedded project eventually collides with the same wall: concurrency. A motor must keep running while a safety monitor watches the sensors, while a communication stack answers the host, while a timer counts down an automatic action. The moment two of these interact, the code fills up with threads, mutexes, condition variables — and a class of bugs that only appear every few thousand hours in the field.

There are two well-known escape routes. The first is writing all of that control code by hand — and I have already argued why that does not scale. The second is handing the whole problem to a code-producing AI — and I have argued why that is not acceptable for production embedded systems either.

This post is about the third path: describing behaviour in a text-based DSL and letting a deterministic generator do the mechanical work. I call this class of tool a soft-robot — and the relationship it creates with the developer is neither manual labour nor blind delegation. It is co-development.

Why a Text-Based DSL Changes the Process

The obvious benefit of a DSL is abstraction. The less obvious — and in daily work far more valuable — benefit is that the model is plain text.

A .umt file lives in Git like any source file. It diffs cleanly: when a colleague adds a transition, the pull request shows exactly one added line, not two hundred lines of regenerated switch blocks. It merges, it greps, it survives every editor and every CI pipeline. A graphical modelling tool with a binary or XML store gives you none of this; a diff of two XMI files is not a design review, it is noise.

Text also means the model is the single source of truth for humans and machines at the same time. A reviewer reads the behaviour directly. The generator reads the same file and produces the implementation. Documentation, review artefact, and build input are one and the same — nothing can drift, because there is nothing separate to drift.

Declaring Concurrency Instead of Implementing It

UMTSM is based on UML State Machines 2.5, and the full feature set is supported — including the parts that make concurrency declarative: orthogonal regions, fork/join synchronisation, do activities with completion events, and deep/shallow/persistent history.

That changes what "writing concurrent code" means. Instead of implementing parallelism, you declare it:

sm Conveyor
{
    state Running
    {
        region Motion
        {
            init -> Moving;

            state Moving
            {
                BeltStalled -> Fault;
            }
        }

        region Safety
        {
            state Monitoring
            {
                do / checkLightCurtain;

                [is_breached] -> Fault / stopBelt();
            }
        }
    }
}

Two regions of Running execute in parallel. The generated C++ contains the thread management, the mutex protection around shared data, and the synchronisation on region completion — produced deterministically, the same way, every time. The developer never writes a std::mutex for the state machine's own bookkeeping, and never debugs a race condition inside infrastructure they did not design.

The Soft-Robot: Automation Without Losing Control

Industrial robots did not replace engineers on the assembly line. They execute a precise program, repeatably, and the engineer retains full authority over what is built. A welding robot that improvised would be removed from the factory floor immediately.

A deterministic code generator is the software equivalent — a soft-robot. It is fast and tireless like an AI assistant, but unlike an AI assistant it never improvises. The same .umt input produces byte-for-byte identical output. Every line of generated code is traceable back to a line of the model. When the behaviour is wrong, the fix happens in the model, under version control, in a reviewable diff.

This is the balance the title of this post promises: the complex control code is not written by hand, but control is never surrendered either. The developer owns the design — states, events, guards, actions — expressed in a language built for exactly that. The soft-robot owns the translation into correct concurrent infrastructure. AI still has a seat at the table, as discussed previously: it can help draft and critique the model. But the final transformation into code belongs to a machine that is accountable, not one that is merely convincing.

Conclusion

Concurrency does not become manageable by heroic hand-written code, nor by delegating engineering judgement to a generator. It becomes manageable when behaviour lives in a text-based model — diffable, reviewable, versioned — and a deterministic soft-robot turns that model into infrastructure the developer would otherwise re-implement, imperfectly, on every project. The engineer decides; the robot builds; the model keeps them honest.

For questions or projects related to UMTSM, feel free to get in touch.