APOLLO TERMINAL v1.0 –
> █type '/help' for commands
Skip to main content
0200 / 00:00:00 / 1970.01.01
×
HOME ABOUT NEWS PROJECTS REFERENCES LINKS

ACAUSAL MODELLING, AND WHY ONE PLUGIN SPEAKS TWO LANGUAGES

Four navy links joined into a closed ring with amber nodes at the corners

Write a resistor in ordinary code and you have to pick a direction before you write a single line. Is voltage the input and current the output, or the other way around? You commit, you write the function, and the function only ever runs that one way.

Write the same resistor in Dyad and you do not pick a direction at all.

component Resistor
  parameter R::Resistance
relations
  v = i * R
end

That is the whole model: a parameter and one equation. Nothing here says which side is input and which is output, because nothing has to be. Feed it a current and it solves for voltage. Feed it a voltage and it solves for current. Wire it into a bigger circuit and a symbolic process looks at every equation in the system at once and works out what needs to be solved for what. That is acausal modelling, and the word “acausal” is doing real work in that name: causal code declares a direction, and acausal modelling refuses to.

Ports instead of arguments

The connecting piece is the port, and Dyad has two kinds of port field. A potential field is equal on both sides of a connection, the way voltage is equal at both ends of a wire with no resistance. A flow field sums to zero across a connection, the way current in has to equal current out. connect(a, b) wires two components together, and the compiler turns that single call into the right equations for whichever fields the two ports actually carry.

That is the trick that makes acausal modelling worth the strangeness. A causal function has to know, at the point you write it, what everything around it looks like. A component built from potential and flow ports does not. You compose it into a bigger system and let the symbolic layer sort out the direction the information actually needs to flow, per equation, for that specific system.

Dyad is not a toy syntax bolted onto Julia. It combines causal code, acausal modelling, and synchronous state machines in one system, and it sits on top of SciML, Julia’s differential equation and modelling ecosystem, including DifferentialEquations.jl and ModelingToolkit.jl. JuliaHub, the company behind it, raised a 65 million dollar Series B and put out Dyad 3.0 on 30 April 2026. This is not a hobby project I stumbled onto.

Where a Julia plugin picks up a second language

Dyad compiles to Julia. That single fact is the reason Flexible Julia, the JetBrains plugin I build, ends up needing to understand a language that has nothing to do with Julia’s own grammar.

DyadLanguage registers Dyad as its own IntelliJ language, separate from Julia entirely. DyadVocabulary is the single list every other part of the Dyad support reads from: declaration keywords like component, connector, analysis, enum, and parameter, modifiers like partial and structural, block keywords like relations and switch, plus the whole set of dimensioned built-in types, Force, Torque, Resistance, Voltage, and so on, each with its own hover doc. That list drives syntax highlighting, autocomplete, and the on-hover documentation, all reading from one place so they cannot drift apart from each other.

The part I actually expected to write, and did not end up writing, is code generation. I assumed I would need something that walks a .dyad file and emits Julia. I did not, because Dyad.jl already does that the moment the package loads. So the plugin’s “Reload Dyad Library in REPL” action does something almost embarrassingly small: it finds the enclosing library by walking up for a folder with both a Project.toml and a dyad/ directory, reads the library name out of that Project.toml, and runs Pkg.activate(libRoot); using LibName in the Julia REPL. That one using statement is the entire code generation step. I built a folder-walking action and a REPL command, not a compiler.

What I am, and what I am not

I should say plainly what I am here: a tooling author, not a control systems engineer. I did not study differential-algebraic equations for a living, and my working understanding of acausal modelling comes from reading Dyad’s own documentation closely enough to write a lexer and a keyword list against it, not from years of building physical simulations. Everything above is accurate to what I read and tested, and I would rather say that outright than write around it as if I had spent a career doing this.

Flexible Julia’s Dyad support covers syntax, completion, hover docs, folding, and that one REPL reload action. It does not include a live equation view, and if Dyad.jl’s own error message is cryptic when a model does not balance, the plugin has no translation to offer you. You get exactly what Dyad.jl tells you, filtered through nothing.

Flexible Julia is on the JetBrains Marketplace. It is still a young plugin, and the Dyad side of it is younger still.

Background
EducationEBS Business School, SFSU, HSG
Experience20 Years Enterprise Systems
BuiltScipio ERP - ERP & Ecommerce System
Author"Start/Up - Set the net on fire"
JetBrains5x Plugins Published
Tech Stack
LanguagesJava, Python, JS, TS, Rust, Go, Swift, PHP
FrontendReact, Vue, Angular, HTML/CSS
DatabasesPostgreSQL, MySQL, MongoDB
CachingRedis, Memcached
Key Clients
EnterpriseL'Oréal, Amadeus, Konica Minolta, Orange
Digital1&1 Internet, Sedo.com, Creditsafe
PublicDRK, Kanton Basel, Aktion Mensch, Börsenverein
← PREV NEXT → TOP ↑