Dafny Verified Effects Bridge
Table of Contents
1. Motivation
Dafny distinguishes:
- function: pure, ghost-eligible, no heap access, used in specifications
- method: may have side effects,
modifiesclauses, heap allocation
Clojure has no enforced pure/impure boundary but uses conventions:
- Pure functions for transforms (the codec pipeline)
core.asyncchannels for concurrent effectscomponentlifecycle for stateful servicesatom/reffor managed mutable state (STM)
The Dafny-Clojure interop focuses on pure codec functions.
This note explores what happens when Dafny method contracts
(modifies clauses, fresh allocations) cross the boundary into
Clojure's effect management.
2. The tension
Dafny method:
method Insert(s: set<int>, x: int) returns (r: set<int>)
modifies this
ensures r == s + {x}
Clojure caller:
;; Which pattern?
(swap! state dafny-insert x) ;; atom -- but Dafny's "modifies this" conflicts
(>! ch (dafny-insert @state x)) ;; channel -- who owns the state?
(component/start (->DafnyService)) ;; lifecycle -- how do modifies map to start/stop?
3. Scope
- Map
modifiesclauses to Clojure's ownership model - Define when Dafny
methodoutput can safely enterswap! - Define when
functionoutput is safe forcore.asyncpipelines - Out of scope: distributed state, Dafny's concurrent verification
4. Related
- Dafny-Clojure JVM Interop (parent article, pure functions only)
- Reversible pipeline transforms (effect-free codec contract)