Skip to main content
Relations are Tide’s core feature. If Tide were a normal language, you’d ask: “How do I define functions?” In Tide you ask: “What relation do I want to describe?”

A relation is a set of clauses

A relation starts with a name and a where block:
relation double where
  double(x) = x * 2

query double(21)
Each clause looks like:
  • a head: double(x)
  • an equals: =
  • a body expression: x * 2

Pattern matching in the head

Heads can match on literal values.
relation sign where
  sign(0) = 0
  sign(n) = 1  when n > 0
  sign(n) = -1 when n < 0

query sign(10)
query sign(-10)
query sign(0)
The idea: the head chooses which shape of input we’re talking about.

Guards decide between overlapping clauses

When multiple clauses could match, a when guard can refine the choice.
relation clamp01 where
  clamp01(x) = 0 when x < 0
  clamp01(x) = 1 when x > 1
  clamp01(x) = x

query clamp01(-2)
query clamp01(0.3)
query clamp01(2)

Recursion (yes, it’s that kind of language)

Because a clause body is “just an expression”, relations can call themselves:
relation factorial where
  factorial(0) = 1
  factorial(n) = n * factorial(n - 1) when n > 0

query factorial(6)

Evaluation model (today)

Tide is still alpha, but the interpreter is currently designed to feel:
  • deterministic (you get the same result every time)
  • clause-driven (it picks a clause, then evaluates its expression)
If you ever hit a surprising edge case, the fastest way to help is to open an issue with:
  • the relation definition
  • the query you ran
  • the output you got
That feedback loop is how Tide’s semantics will solidify.