The Verification Opportunity
Why effects and contracts enforcement is only practical in coding agent languages—and why this changes everything.
The 50-Year Struggle
Computer scientists have known since the 1970s how to make software more reliable:
- Effect Systems: Track side effects at compile time (Gifford & Lucassen, 1986)
- Design by Contract: Specify preconditions and postconditions (Meyer, 1986)
- Dependent Types: Encode invariants in the type system (Martin-Löf, 1972)
These techniques can mathematically prove that code behaves correctly. They catch entire categories of bugs before the code ever runs.
So why isn't all software written this way?
Why Humans Don't Write Annotations
Every attempt to bring verification to mainstream programming has hit the same wall: human annotation burden.
| Reason | Impact |
|---|---|
| Annotation fatigue | Developers skip contracts when tired or rushed |
| Time pressure | Deadlines trump verification discipline |
| Maintenance burden | Contracts rot when code changes |
| Learning curve | Teams resist unfamiliar syntax |
| Escape hatches | throws Exception or catch-all blocks defeat the system |
Haskell's Effect System
-- Haskell requires effect annotations everywhere
readFile :: FilePath -> IO String
writeFile :: FilePath -> String -> IO ()
-- Every function that uses IO must declare it
processConfig :: FilePath -> IO Config
processConfig path = do
contents <- readFile path -- Forces IO in type signature
return (parseConfig contents)Result: Haskell remains a niche language. Most programmers find the discipline too burdensome for everyday work.
Eiffel's Design by Contract (1986)
-- Eiffel requires manual contract annotation
deposit (amount: INTEGER)
require
positive_amount: amount > 0
account_open: is_open
do
balance := balance + amount
ensure
balance_increased: balance = old balance + amount
endResult: Eiffel never achieved mainstream adoption. The annotation overhead was too high for most development teams.
Java's Checked Exceptions
// Java forces you to declare every exception
public void processFile(String path) throws IOException, ParseException {
String content = Files.readString(Path.of(path)); // throws IOException
parse(content); // throws ParseException
}Result: Developers circumvent the system with throws Exception or catch-all blocks. The signal is lost.
C# Code Contracts (2008-2015)
Microsoft introduced Code Contracts for .NET—a promising approach to design-by-contract:
public int Divide(int a, int b)
{
Contract.Requires(b != 0);
Contract.Ensures(Contract.Result<int>() * b == a);
return a / b;
}Result: Abandoned by Microsoft. The static analyzer was slow, the runtime overhead was significant, and developers simply didn't write contracts consistently enough to justify the tooling investment.
Why AI Agents Change Everything
Coding agents change this equation fundamentally:
| Human Developers | Coding Agents |
|---|---|
| Find annotation tedious | Generate annotations for free |
| Forget to update contracts | Maintain perfect consistency |
| Skip verification under time pressure | Never cut corners |
| Resist learning new syntax | Adapt instantly to any syntax |
| Trade safety for productivity | Safety IS productivity |
When an agent writes code, the annotation cost is zero.
This isn't incremental improvement. It's a phase transition that makes previously impractical techniques suddenly viable.
C# vs Calor: What's Different
Problem 1: Hidden Side Effects
In C#, function signatures don't reveal their side effects:
// C#: What effects does this function have?
public async Task<User> GetUser(int id)
{
var user = await _repository.GetById(id); // Database? Memory?
_logger.Log($"Retrieved user {id}"); // Console? File? Network?
await _cache.Set(user); // Memory? Redis?
return user;
}
// Answer: You have NO IDEA without reading every dependencyIn Calor, effects are explicit in the signature:
§F{f001:GetUser:pub}
§I{i32:id}
§O{User}
§E{db,cw,net} // EXPLICIT: database, console write, network
§V{v001:User:user} (§C{GetById} id)
§C{Log} (concat "Retrieved user " (str id))
§C{CacheSet} user
§R user
§/F{f001}An agent (or human) reading this function knows immediately:
- It accesses a database
- It writes to the console
- It uses the network
No guessing. No reading implementation details. No surprises.
Problem 2: Contracts That Disappear
C# offers Debug.Assert, but these vanish in release builds:
// C#: These contracts vanish in release builds
public static int Divide(int a, int b)
{
Debug.Assert(b != 0, "Divisor cannot be zero"); // GONE in Release
return a / b;
}
// In production: DivideByZeroException with no contextCalor contracts are always enforced:
§F{f001:Divide:pub}
§I{i32:a}
§I{i32:b}
§O{i32}
§Q{message="divisor must not be zero"} (!= b 0) // ALWAYS enforced
§R (/ a b)
§/F{f001}The generated C# includes runtime checks:
public static int Divide(int a, int b)
{
if (!(b != 0))
throw new ContractViolationException(
"Precondition failed: divisor must not be zero",
functionId: "f001",
kind: ContractKind.Requires,
line: 5);
return a / b;
}Interprocedural Analysis
Calor doesn't just check individual functions. It analyzes the entire call graph:
error Calor0410: Function 'ProcessOrder' uses effect 'network'
but does not declare it
Call chain: ProcessOrder → NotifyCustomer → SendEmail → HttpClient.PostAsyncThe compiler traces effect violations through any depth of calls. You can't hide a side effect by burying it in helper functions.
§F{f001:ProcessOrder:pub}
§I{Order:order}
§O{bool}
§E{db} // Declares: only database effects
§C{SaveOrder} order // OK: SaveOrder has db effect
§C{SendEmail} order // ERROR: SendEmail has net effect
§/F{f001} // not declared in §E{db}The compiler catches this. Not a linter warning. Not a code review comment. A hard error that blocks compilation.
The Virtuous Cycle
When agents both write and verify code, a powerful feedback loop emerges:
┌─────────────────────────────────────────────────────────────┐
│ │
│ Agent generates code ───► Compiler verifies effects │
│ ▲ │ │
│ │ ▼ │
│ Agent fixes violations ◄─── Errors with call chains │
│ │
└─────────────────────────────────────────────────────────────┘- Agent generates code with effect declarations and contracts
- Compiler verifies effects are properly declared
- Errors include call chains showing exactly where violations occur
- Agent fixes violations with precise information
- Repeat until verified
This cycle happens at machine speed. What would take a human team days of debugging completes in seconds.
Real-World Impact
Bug Categories Eliminated
| Bug Category | Traditional Detection | Calor Detection |
|---|---|---|
| Undeclared side effect | Code review (maybe) | Compile error |
| Missing null check | Runtime NPE | Contract violation |
| Invalid state transition | Integration test (if lucky) | Contract violation |
| Effect leaking through abstraction | Production incident | Compile error with call chain |
| Contract violation | Silent corruption | Immediate, traced exception |
Getting Started
To see effect and contract enforcement in action:
# Compile with enforcement (enabled by default)
calor compile myprogram.calr
# See effect violations with call chains
# error Calor0410: Function 'f001' uses effect 'console_write' but does not declare it
# Disable for migration (not recommended)
calor compile myprogram.calr --enforce-effects=falseLearn More
- Effects Reference - Complete effect syntax and available effect types
- Contracts Reference - Precondition and postcondition syntax
- Design Principles - The five principles behind Calor