skip to content

The contract{} DSL

A contract block is declared as the very first statement of a function and requires opting into an experimental API. It adds no runtime behavior; it only feeds the compiler's flow analysis.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

What is the contract { } block in Kotlin, and why would you add one to a function?

level: juniorimportance: should knowfreq 35%

answer

  1. First statement of the function body
  2. kotlin.contracts.contract { }
  3. @OptIn(ExperimentalContracts::class)
  4. Tells compiler facts it can't infer
  5. Compiler trusts, doesn't verify

basics

~20 s

A contract is a small block at the start of a function that tells the compiler extra facts about how the function behaves, so it can do smarter checks like smart casts after you call your own function.

solid answer

~40 s

A contract { } is a declaration block placed as the very first statement of a function body. Inside it you call the contract DSL (from kotlin.contracts) to describe behavioral facts the compiler cannot infer on its own — e.g. 'if this returns true, the argument was non-null' (returns(...) implies(...)) or 'this lambda is invoked exactly once' (callsInPlace). The compiler trusts these facts and uses them at call sites for smart casts and definite-assignment analysis. The feature is experimental, so you must opt in with @OptIn(ExperimentalContracts::class). The compiler does NOT verify the contract is truthful — it is a promise you make, so an incorrect contract causes unsound behavior.

code

kotlin · 8 lines
kotlin
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract

@OptIn(ExperimentalContracts::class)
fun checkNotNull(value: Any?) {
    contract { returns() implies (value != null) }
    if (value == null) throw IllegalStateException()
}

go deeper

for a junior

Knows a contract gives the compiler extra facts and enables smart casts after helper calls.

for a middle

Can write a simple returns() implies contract and explains the opt-in and first-statement rules.

for a senior

Articulates that contracts are unchecked, erased at runtime, and distinguishes returns vs callsInPlace effects.

for a principal

Reasons about soundness risk of false contracts and the experimental/stability trade-offs of shipping them in a public API.

## What a contract is A **contract** is metadata you attach to a function telling the Kotlin compiler facts about the function's behavior that it cannot derive by analyzing the body. Normally the compiler only smart-casts or reasons about code it can see inline. When you extract logic into a helper function, that knowledge is lost at the call site. Contracts let you hand that knowledge back to the compiler. You declare a contract by calling the top-level `contract { }` function from the `kotlin.contracts` package as the **first statement** of the function body. ## The two kinds of effects Inside the `contract { }` block you describe **effects**: - **returns / conditional effects** — `returns() implies (x != null)` means: when this function returns normally, the compiler may assume `x != null`. Used to write custom `require`-like or `isNotNull`-like helpers that propagate smart casts. - **callsInPlace effects** — `callsInPlace(block, InvocationKind.EXACTLY_ONCE)` tells the compiler a lambda parameter is invoked in place (and how many times), enabling `val` initialization inside the lambda and definite-assignment analysis. ## Why it matters ```kotlin import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract @OptIn(ExperimentalContracts::class) fun require(condition: Boolean) { contract { returns() implies condition } if (!condition) throw IllegalArgumentException() } fun use(s: String?) { require(s != null) // After the call, the compiler smart-casts s to String: println(s.length) } ``` Without the contract, the compiler would NOT know that surviving `require(s != null)` proves `s` is non-null. ## Key rules - Must be the **first statement** in the function — before any other code. - Requires opt-in: `@OptIn(ExperimentalContracts::class)` (the `contract` function is `@ExperimentalContracts`). - The compiler **does not check** that your function actually honors the contract; it trusts you. A false contract is unsound. - Contracts are erased; they affect compile-time analysis only and have no runtime cost. - Only allowed on top-level / member functions with a body (not on lambdas, not on accessors with limitations).

  • Does the compiler verify your function actually obeys the contract?
    No. Contracts are unchecked promises; the compiler trusts them. A wrong contract produces unsound smart casts and is a real bug.
  • Where in the function must the contract { } call appear?
    As the very first statement, before any other expression or declaration in the body.

Like a signed affidavit you hand the compiler: it takes your sworn statement at face value without checking the evidence.

saying these in an interview costs you the question

  • Thinking the compiler validates the contract against the body
  • Believing contracts add runtime checks or cost
  • Putting contract { } anywhere other than the first statement
  • Confusing contracts with runtime assertions like require/check themselves

context

open as a page

What syntactic and structural rules constrain where and how a contract { } block can be declared?

level: middleimportance: should knowfreq 30%

basics

~10 s

The contract block must be the first line inside the function, it can only go on regular named functions with a body, and you must opt in to the experimental API.

open as a page

Which Kotlin standard library functions rely on contracts, and what observable behavior do those contracts unlock for callers?

level: middleimportance: should knowfreq 28%

basics

~10 s

Functions like require, check, requireNotNull, isNullOrEmpty, and the scope functions (let, run, also, apply, with, repeat) declare contracts so smart casts and val initialization work cleanly after you call them.

open as a page

Contracts are unchecked. What goes wrong if a contract { } block lies, and how would you reason about that risk when shipping a library?

level: seniorimportance: should knowfreq 22%

basics

~20 s

The compiler believes whatever the contract says without checking it. If the contract is false, the compiler makes wrong smart casts, so code that looks safe can throw at runtime. You must make sure the body truly honors the contract.

open as a page

Walk through the opt-in mechanics for the contracts DSL: what makes it experimental, how do you opt in at function vs module level, and what does that imply for a published API?

level: seniorimportance: nice to knowfreq 16%

basics

~20 s

The contract { } function is marked experimental, so the compiler warns or errors unless you opt in. You can opt in on one function with @OptIn, or for the whole module with a compiler flag. Either way you accept that the API could change.

open as a page