Type Systems & Mechanized Proofs

← Back to Home

Types catch bugs before a program runs, and stop humans and bots alike from doing nonsense.

A type system is a negotiation. The programmer wants to write what they mean; the compiler wants a guarantee it can actually check. Push too hard on the guarantee and the notation turns rigid (effects marshalled one per line, motives spelled out by hand). Push too hard on convenience and the guarantee evaporates.

My work here tries to move that boundary rather than pick a side, from both ends. At the notation end: let the structure of the code carry the information the compiler needs, so that writing effects in direct style is what reveals which parts may run in parallel, instead of obscuring it. At the inference end: make the type checker itself stronger, so that constraints today’s proof assistants reject (including ones produced by something as routine as omitting the motive of an induction) come within reach. Both ends lean on the same habit: if the claim is that a translation preserves meaning, or that a solution is correct, then the proof belongs in Coq or Lean, not in prose.

Highlight
  • 🏅 Distinguished Paper🏅 Distinguished Artifact A Direct-Style Effect Notation, ECOOP 2023
Collaborators
Timon Böhler Simon Daniel Mira Mezini Pascal Weisenburger

Timeline

2023ECOOP

A Direct-Style Effect Notation for Sequential and Parallel Programs

David Richter, Timon Böhler, Pascal Weisenburger, Mira Mezini

Problem. Two notations dominate effectful code and each gives up half of what you need. do-notation embeds any monad, but monads chain everything into one sequence, discarding parallelism that was there for the taking. Idiom brackets embed applicatives, which run in parallel, but cannot express one effect depending on another’s result. Real programs are neither purely sequential nor purely parallel, and composing the two was an open problem. Worse, both notations impose a rigid shape on the code (one effect per line), rather than letting effects appear where they are actually used.

Idea. A mixed applicative/monadic notation written in direct style. A purify block introduces an operator ↓ : F[X] ⇒ X, and where you write it is all the compiler needs: parallelism is read off the structure of the code rather than recovered afterwards from a sequential program. Arguments of ++ cannot depend on each other, so they run in parallel; a fetch whose URL comes from another fetch cannot, so it does not.

A dependency diagram: fetch(urlXX) and fetch(urlYY) start in parallel, each feeding a second fetch, and both chains converge on x ++ y
From the paper: the example's dependency structure (two independent chains, each internally sequential).

Result. A one-pass translation from direct style to effect combinators, proved to preserve typability, semantics and parallelism. Parallelism is made precise as the span of a term (the longest chain of effectful operations) against its work (the total number of them); the translation is span-preserving, which notations built on monads alone cannot be. The proof is mechanized in Coq using parametric higher-order abstract syntax, and the translation is implemented in Scala via macros, staying close to the formal development. Distinguished Paper and Distinguished Artifact at ECOOP 2023.

Links: ECOOP 2023 · paper · artifact · github · arxiv 🏅 Distinguished Paper🏅 Distinguished Artifact

2026TyDe @ FPW Paris · Extended abstract

From Pattern Unification Towards Pattern Matching Unification

David Richter, Timon Böhler

Problem. Dependently typed languages lean on Miller pattern unification, a well-behaved fragment of the undecidable general problem. But that fragment has a blunt limitation: it cannot synthesize a function defined by case analysis. The constraint system F true = 1, F false = 2 is trivial to any functional programmer (the answer is a match), yet it falls outside Miller patterns and outside the modern extensions too (FCU, DHOP), all of which reject metavariables applied to terms that are not variables.

Idea. These constraints are not exotic; they come straight out of type inference over eliminators. Omit the motive P of an induction principle and the checker is immediately asked to solve P true = ℕ, P false = Bool, again a definition by cases. That correspondence is the whole point: such constraints are definitions by dependent pattern matching. So bring pattern matching into unification itself, collecting delayed constraints and discharging them with a pattern matching compiler.

The same induction-principle test in two languages: this work's prototype synthesizes the motive as a match on the Boolean, while Rocq fails with 'Unable to unify bool with ?P false'
Fig. 1 from the paper (excerpt): the litmus test, as this work's prototype and as Rocq handle it.

Result. A prototype dependently typed language (under 3000 lines of Lean) that collects the constraints falling outside the pattern fragment, suspends them as delayed problems, and hands them to a dependent pattern matching compiler: the metavariable becomes a function symbol, its arguments become pattern variables, and the constraint states the desired output. It infers solutions that Rocq and Lean reject, pointing toward a unification procedure that merges type inference with pattern matching compilation. An extended abstract.

Links: arxiv

2026TyDe @ FPW Paris

Mechanizing Choreographic Programs and Hoare Logic

Timon Böhler, Simon Daniel, David Richter, Pascal Weisenburger, Mira Mezini

Problem. Formally verifying choreographies in a proof assistant is notoriously painful, because most choreographic languages are functional (receiving a message introduces a fresh variable), and machine-checked proofs about variable binding and substitution end up dominating the whole effort.

Idea. Give every participant a local state of an arbitrary type, and model “receive a message” not as binding a new variable, but as a plain function from (old state, message) to new state (a state transformer). Receiving a message then introduces no binder at all.

A Hoare-logic derivation tree verifying a simple addition protocol, built from the Hoare-Com and Hoare-Done rules
Fig. 8 from the paper.

Result. A full mechanization (in Lean) proving soundness and completeness of endpoint projection, deadlock freedom, confluence, and a Hoare logic for choreographies, sidestepping the binding and substitution reasoning that usually dominates such a development.

Links: arxiv

2026TyDe @ FPW Paris

On Eliminating the Impossible with Dependent Types

Simon Daniel, Timon Böhler, David Richter, Pascal Weisenburger, Mira Mezini

A partial located value with an unreachable, uncheckable error branch, next to ChorLean's total located value where unwrapping is provably just the identity function
Fig. 2 from the paper.

Problem. Choreographic libraries embedded in a host language (Haskell, Rust, …) still have a gap: a “located” value that a role may or may not own is modelled as an option type, and unwrapping it always keeps a dead “impossible” branch (ruled out only by the library author’s discipline, never by the type checker).

Idea. In a dependently-typed host language, make “this role owns this value” a genuine machine-checked proof rather than a runtime tag: a located value’s type carries a proof that the current role is among its owners.

Result. A choreographic library where no error/undefined appears anywhere in the core implementation: totality is enforced by the compiler itself, without sacrificing expressivity relative to prior, partial libraries.

Links: arxiv