Semantic Adapters Make Languages Interoperable
Programming languages already interoperate.
They call each other through ABIs, RPC, bindings, generated clients, shared databases, message queues, plug-in systems, package managers, and runtime embeddings.
The problem is not that languages cannot communicate.
The problem is that most communication happens through narrow technical edges while the meaning stays private.
Rust exposes bytes.
TypeScript exposes a wrapper.
Swift exposes a client.
Python exposes a script.
None of those edges automatically explain identity, ownership, effects, permissions, runtime assumptions, or proof.A semantic interlingua changes the shape of the edge.
It makes the adapter itself a first-class object.
- Contract
- capability, action, data, effect, resourceThe shared meaning every language is trying to attach to.
- Source side
- native language factsRust may prove ownership. TypeScript may prove structural shape. CSS may prove cascade targets.
- Adapter
- mapping, shim, binding, transport, projectionThe adapter says how the native fact crosses the boundary.
- Proof
- type gate, runtime probe, span map, loss recordThe boundary is trusted only as far as the proof reaches.
- Loss
- explicit and queryableIf a target cannot preserve a constraint, that is recorded instead of hidden.
Glue Hides The Contract
Normal interoperability starts with mechanics:
Can the caller invoke this function?
Can the runtime load this module?
Can this object serialize across the wire?
Can this generated client compile?Those are real requirements, but they are not enough.
Imagine a search system.
The index is written in Rust. The product shell is TypeScript. A native client is SwiftUI. A worker script is Python. The browser surface is HTML and CSS.
The old shape is pairwise glue:
Rust -> Node binding
Node binding -> TypeScript wrapper
TypeScript wrapper -> API route
API route -> Swift client
API route -> Python job
API route -> browser UIEvery edge invents its own private contract.
The semantic shape is different:
The contract becomes the meeting point.
The adapter is where each language proves how it participates.
The Adapter Has Obligations
If a language adapter is only a generated file, the system can ask only shallow questions:
did generation finish?
did the file compile?
did the wrapper call the right endpoint?A semantic adapter can answer stronger questions:
which capability is implemented?
which source symbol provides it?
which target symbol exposes it?
which effects can cross the boundary?
which resource is read or mutated?
which constraints are preserved natively?
which constraints are preserved by runtime proof?
which constraints are lost?1capability Search @id("cap_search") {2 action query3 input SearchQuery4 returns SearchResults5 reads SearchCorpus.documents6 effects cpu.read, storage.read7}8 9adapter RustSearch @id("adapter_rust_search") {10 implements cap_search.query11 source symbol:rust/SearchIndex.query12 preserves ownership, input_shape, output_shape13 proves type_gate, fixture_gate14}Interoperability Is Not Equivalence
The strongest version of this idea is not pretending every language can express every other language perfectly.
It is the opposite.
Languages become interoperable when the system can say exactly where they are not equivalent.
That makes interoperability less magical and more useful.
The system can route the boundary:
Many Languages, One System
Once adapters are semantic, a system can stop treating language boundaries as hard product boundaries.
A workflow can be authored once and projected into different runtimes.
A UI component can expose a capability contract that a web shell, native shell, and automation shell can all bind to differently.
A Rust module can provide a fast implementation without forcing the rest of the product to understand Rust.
A TypeScript SDK can expose a friendly developer surface while still carrying the stronger ownership and effect claims from the provider.
A Python automation can consume the same contract without becoming a second source of truth.
The languages stay different.
The contract stays shared.
The adapters carry proof.
The losses stay visible.That is the important shift.
Interoperability is not a universal compiler that erases language differences.
It is a semantic coordination layer that lets languages keep their strengths while participating in one larger system.
Why This Matters
Most software becomes harder to change as it grows because every boundary accumulates private assumptions.
The API route assumes something about the database. The generated client assumes something about the server. The native app assumes something about the web product. The worker assumes something about the queue. The docs assume something about all of them.
Semantic adapters make those assumptions inspectable.
They turn interoperability into a set of durable questions:
what is the shared contract?
which language owns which part?
what did this adapter preserve?
what did it compensate for?
what proof admits it?
what would break if the contract moved?That is why the interlingua matters.
It is useful for semantic merging, but it is bigger than merge.
It gives different programming languages a common place to meet without pretending they are the same language.