Koka is a research language by Microsoft Research that pioneered algebraic effects as a first-class feature. It provides Haskell-level purity tracking with a revolutionary memory management system called Perceus.
Why Koka Matters
Algebraic effects solve the "what color is your function" problem. In Koka, effects are tracked in the type system — you know exactly what side effects a function can perform, and you can define your own effects.
What you get for free:
- Algebraic effects: compose and handle side effects cleanly
- Effect types: know what a function does from its signature
- Perceus reference counting: no GC pauses, deterministic cleanup
- Functional-but-fast: compiles to C with optimizations
- Row-polymorphic effect system
- First-class modules and interfaces
Quick Start
# Install
curl -sSL https://github.com/koka-lang/koka/releases/latest/download/install.sh | sh
# Run
koka main.kk
# Build optimized
koka -O2 main.kk
The Basics
// Pure function — no effects
fun add(x: int, y: int): int
x + y
// Function with console effect
fun greet(name: string): console ()
println("Hello, " ++ name ++ "!")
// Function with multiple effects
fun ask-name(): <console, ndet> string
println("What is your name?")
readline()
fun main(): <console, ndet> ()
val name = ask-name()
greet(name)
Algebraic Effects
// Define a custom effect
effect fun ask(prompt: string): string
effect fun tell(msg: string): ()
// Use effects in functions
fun conversation(): <ask, tell> ()
val name = ask("What is your name?")
tell("Hello, " ++ name)
val age = ask("How old are you?")
tell("You are " ++ age ++ " years old")
// Handle effects differently
fun handle-console(): <console> ()
with handler
fun ask(prompt)
println(prompt)
readline()
fun tell(msg)
println(msg)
conversation()
// Or handle with testing (no IO)
fun handle-test(): list<string>
var answers := ["Alice", "30"]
var output := []
with handler
fun ask(prompt)
match answers
Cons(a, rest) -> { answers := rest; a }
Nil -> "default"
fun tell(msg)
output := output ++ [msg]
conversation()
output
Effect Handlers for Exceptions
effect ctl raise(msg: string): a
fun safe-div(x: int, y: int): raise int
if y == 0 then raise("division by zero")
else x / y
fun main(): console ()
// Handle exception effect
val result = with handler
ctl raise(msg) -> println("Error: " ++ msg)
safe-div(10, 0)
// Or convert to Maybe
val maybe-result = with handler
ctl raise(msg) -> Nothing
Just(safe-div(10, 2))
Pattern Matching
type shape
Circle(radius: float64)
Rectangle(width: float64, height: float64)
Triangle(a: float64, b: float64, c: float64)
fun area(s: shape): float64
match s
Circle(r) -> pi * r * r
Rectangle(w, h) -> w * h
Triangle(a, b, c) ->
val s = (a + b + c) / 2.0
sqrt(s * (s - a) * (s - b) * (s - c))
fun main(): console ()
val shapes = [Circle(5.0), Rectangle(3.0, 4.0)]
shapes.foreach fn(s)
println("Area: " ++ area(s).show)
Perceus Memory Management
Koka uses Perceus — a compile-time reference counting system that:
- Has no GC pauses (deterministic)
- Automatically inserts drop/reuse operations
- Achieves performance comparable to manual memory management
- Enables "functional but in-place" optimization
Useful Links
Building research-grade data tools? Check out my developer tools on Apify for ready-made web scrapers, or email spinov001@gmail.com for custom solutions.
Top comments (0)