Write like a dynamic language, get a strict one
Full inference across the whole program. Annotate a signature where it helps someone reading it, never to satisfy the compiler.
Every function tells you what it touches — files, network, tasks, failure — and you never annotate one. Full inference, structural types, running on the JVM.
Runs in your browser. Nothing to install to try it.
use std::effects::log::{ Console, QuietConsole, println }
# The same function, two destinations.
let audit = { order } -> println { msg = "saw $(order)" }
let report = { n } -> println { msg = "$(n) orders seen" }
let main = {} -> do
# Console prints it...
perform Console in audit { order = "A-1" }
# ...QuietConsole drops it. Nothing in audit changed.
perform QuietConsole in audit { order = "A-2" }
perform Console in report { n = "2" }Full inference across the whole program. Annotate a signature where it helps someone reading it, never to satisfy the compiler.
Records are the whole story: arguments are records, so every call names its fields. Learn one shape and it holds from a two-field literal to a module API.
The same function runs against the real filesystem or an in-memory one, a live clock or a frozen one. Tests get a different handler, not different code.
Exceptions and early return are ordinary functions here, not syntax the language had to grow. Write your own control flow and it looks like everyone else's.
Millions of virtual threads, and cancellation that actually interrupts a parked task. STM, atoms, channels, agents and latches ship with it.
Optimised data structures, loop fusion, and mutation that is safe because the type system keeps it in scope. AOT native binaries when you want them.
Durable workflows and distributed execution, built on the same effect system. Designed, not yet shipped.
Mezze runs on GraalVM, so calling the Java, Kotlin and Python you already have is the plan. Designed, not yet shipped.