← Back to blog

Introducing MDL: Your Models as Text

Every component can be edited two ways: as blocks on the canvas or as MDL text. Change one, and the other follows.

Block diagrams are the right tool for designing dynamic systems. Signal flow, feedback loops, and system structure are spatial concepts, and a canvas shows them the way engineers actually think about them.

But some editing is simply faster in text. Renaming a signal, retuning a set of parameters, restructuring an expression — operations that take many careful canvas interactions are a few keystrokes in an editor. And text can be read top to bottom, searched, and copied.

This is what MDL — the Modeloop Description Language — is for. Every diagram in Modeloop has an equivalent textual representation, kept bidirectionally synchronized with the canvas. The text and the picture are two projections of the same model.

What a model looks like as text

Here is a PID controller, exactly as Modeloop writes it:

component PIDController:
    inputs:
        setpoint[1, float64]
        feedback[1, float64]
    outputs:
        command[1, float64]
    parameters:
        Kp[1, float64] = 1.2
        Ki[1, float64] = 0.4
        Kd[1, float64] = 0.05
    diagram:
        error = setpoint - feedback
        derivative_error = Derivative(error)
        integral_error = Integral(error)
        command = Kp * error + Ki * integral_error + Kd * derivative_error

The structure is Python-like: interfaces are declared with explicit dimensions and data types, and the diagram: section describes the same dataflow you would wire on the canvas — as expressions.

There is no hidden translation layer here. setpoint - feedback is a Sum block; Ki * integral_error is a Multiply block; Integral(error, initial=0.0) is the same Integral block you drag from the library, with the same parameters. Open the diagram after applying this text and you will find the familiar blocks, wired exactly as written. Statement order is free — signals can reference statements that come later, just like connections on a canvas have no reading order.

Feedback loops are written through memory blocks. A discrete low-pass filter is one line through a UnitDelay:

y = (1 - alpha) * UnitDelay(y) + alpha * noisy

Structure without leaving the text

Hierarchy is written inline. A container declares its boundary and its contents in one statement:

    diagram:
        clean = container SpeedFilter(noisy=speed):
            alpha = 0.1
            y = (1 - alpha) * UnitDelay(y) + alpha * noisy
            clean = y

        throttle = Kp * (target - clean)

The arguments are the container’s inputs, the targets are its outputs, and the indented body is its inner diagram. The same inline form covers periodic and event-driven tasks, conditionally executed subsystems, and state machines:

        heat_on = fsm HeaterLogic(temp):
            state Off initial:
                entry: heat_on = 0.0
            state Heating:
                entry: heat_on = 1.0
            Heating -> Off: [temp > 21.0]
            Off -> Heating: [temp < 19.0]

That is a complete state chart — states, entry actions, guarded transitions — in nine lines.

One canonical form

The text is canonical. Emitting the same model twice produces byte-identical output — deterministic statement order and formatting — and the built-in formatter produces exactly that form.

Editing is transactional. Invalid text never touches the model. As you type, MDL validates continuously and reports precise, line-anchored errors; the model is only mutated when you apply a fully valid buffer. And applying is a merge, not a replacement: Modeloop matches the text against your existing diagram, so block positions, hand-drawn routing, and everything you arranged on the canvas survive the edit.

Where you’ll find it

MDL is built into the editor. From any diagram, flip to the text view, edit, and apply — the canvas updates in place, at any level of the hierarchy. The text view always reflects the current state of the model, so you can switch between the two projections at any point in the design.