Audit your Annual Tax Report (Årsopgørelse)
If you are from Denmark, let the AI interview you into Futuruna's formal Personskat rule model, then compare the deterministic result with your own Annual Tax Report.
A programming language for law.
Write laws, contracts, and policies you can run, test, and audit.
Futuruna allows you or an AI to encode the rule of law into a rule model, and mix it with ordinary programming. Explore, automate and audit the law like never before.
Why Futuruna →AI setup
Give the setup guide to Claude Code, Claude Cowork, Codex, or ChatGPT Work. Your AI will install Futuruna and run the first example with you.
Read https://futuruna.com/ai-setup.md and set up Futuruna for me.The guide shows your AI how to install the right version for your computer, check the download, and run a working example. It should only say setup is complete after every check passes.
Read the setup guide →Each line begins with a semantic fly-in: a compact signal for types, functions, rules, values, flows, effects, or verification.
# Point(x: Float, y: Float)> distance(a: Point, b: Point) -> Float| is_valid(p) -> p.x > 0 && p.y > 0= origin = Point(0.0, 0.0)~ clicks = from_list([1, 2, 3]) |> map(|x| x * 2)@ print("Hello, Futuruna")? valid_point -> { @ print("verified") }Encode legal rules without giving up ordinary programming. Keep the model, the calculations, and the audit in one language, then compile it through Rust.
Express defaults, conditions, and named exceptions beside types, functions, values, streams, and effects. No separate legal rules engine is required.
Demand checks close to the rules they examine. Surface conflicts, gaps, unexpected outcomes, and the assumptions that produced them.
Keep statutory text, citations, effective dates, and explanatory metadata close to the executable definitions and rules they support.
Generate native programs through Rust's compiler and safety checks, with ownership inference for ordinary value-oriented Futuruna code.
Give AI systems explicit forms for rules, exceptions, effects, and audit demands instead of asking them to simulate those concepts through conventions.
A rune at the start of each statement provides a quick entry point into its role while preserving a compact syntax across programming domains.
-- define the universe
# Coffee = Espresso | Latte | Decaf
-- define what matters
> strength(c: Coffee) -> Int { match c { | Decaf -> 0 | _ -> 100 } }
-- assign reality
= your_order = Espresso
-- state the law
| real_coffee: your_order -> your_order != Decaf
-- watch it flow
~ real = from_list([Espresso, Latte, Decaf]) |> filter(|c| c != Decaf)
-- cross the boundary
@ print(show(count(real)) + " real coffees. Yours: " + show(strength(your_order)) + "mg")
-- demand proof
? real_coffee2 real coffees. Yours: 100mg
[ok] |real_coffee| holds (value: Espresso)Write Futuruna code and run it in your browser. Open full playground →
# Condition = Sunny | Cloudy | Stormy
# Weather(day: String, temp: Float, condition: Condition)
> describe(w: Weather) -> String {
match w.condition {
| Sunny -> show(w.temp) + " C, sunny"
| Stormy -> show(w.temp) + " C, storm"
| Cloudy -> show(w.temp) + " C, cloudy"
}
}
| advisory(w) -> "all clear"
| advisory(w) -> "heat warning" under w.temp > 35.0
| exception storm advisory(w) -> "danger" under w.condition == Stormy
= today = Weather("today", 22.0, Sunny)
= alert = advisory(today)
@ print(today.day + ": " + describe(today) + " -- " + alert)
~ forecast = from_list([today, Weather("tomorrow", 40.0, Sunny), Weather("in 2 days", 18.0, Cloudy), Weather("in 3 days", 10.0, Stormy)]) |> filter(|w| advisory(w) != "all clear")
= warning_count = count(forecast)
| has_warnings: warning_count -> warning_count > 0
? has_warnings: n -> {
@ print("Upcoming warnings (" + show(n) + "):")
~ forecast | w -> {
@ print(" " + w.day + ": " + advisory(w) + " -> " + describe(w))
}
} else {
@ print("No warnings -- all clear ahead")
}
Click 'Run' to execute...