Skip to content

Formulas

A formula is a set of equations between named properties. Give it any properties you know and it works out the rest.

formula Trip(speed, time):
  distance = speed * time
Trip(speed = 60 km/hour, time = 2 hours)

The result is a record. Read one property with ::, or with from.

formula Trip(speed, time):
  distance = speed * time
Trip(speed = 60 km/hour, time = 2 hours)::distance
distance from Trip where speed = 60 km/hour, time = 2 hours

Any property can be the unknown. Supply the distance and the time, and smoot solves for the speed.

formula Trip(speed, time):
  distance = speed * time
Trip(distance = 120 km, time = 2 hour)::speed
time from Trip where distance = 240 km, speed = 80 km/hour

Arguments are always named. Positional arguments are an error, because a formula’s inputs have no natural order.

A formula with no argument list promotes every free name in its equations to a property.

formula Pythagoras:
  a^2 = b^2 + c^2
Pythagoras(b = 3, c = 4)::a
formula Motion:
  speed = distance / time
time from Motion where distance = 240 km, speed = 80 km/hour

A parameter can carry a default and a hint. let inside a body is a working value that does not appear in the result. A when guard is checked against the inputs and, after solving, against the outputs.

formula Loan(principal: Currency, rate, years = 30):
  let monthly rate = rate / 12
  let n = years * 12
  payment = principal * monthly rate / (1 - (1 + monthly rate) ^ (0 - n))
Loan(principal = $250,000, rate = 6%)::payment
Loan(payment = $1,500, rate = 6%)::principal
formula Pyramid(base: Length, angle: Angle) when base > 0 m:
  height = (base / 2) * tan(angle)
Pyramid(base = 4 m, angle = 45 deg)::height
Pyramid(base = -1 m, angle = 45 deg)

Long calls can span lines inside the parentheses.

A property can be a whole other formula. Its equations join the outer system, so a back-solve reaches inside.

formula Rect(w, h):
  area = w * h
formula Box(height):
  base = Rect(h = 3 m)
  volume = base::area * height
Box(height = 4 m, volume = 24 m^3)::base::w

A formula call standing alone in a body merges its properties into the host. That is how shapes/2d defines Square from Rectangle.

The shapes live in the bundled shapes/2d and shapes/3d modules (see §Imports); these are always there.

FormulaProperties
Density(mass, volume)density
CompoundInterest(principal, rate, periods)amount
Percentage(part, whole)rate
PercentChange(original, rate)result
Proportion(a, b, c)d
ReturnOnInvestment(invested, returned)roi
CompoundInterest(principal = 1000, rate = 5%, periods = 10)::amount to 2 dp
CompoundInterest(amount = 2000, rate = 5%, periods = 10)::principal to 2 dp

to and as apply to every field that fits.

import "shapes/2d"
rect = Rectangle(width = 3 m, height = 4 m)
rect to ft to 1 dp