Values and defaults
A field can hold three different kinds of thing, and they are not interchangeable:
| The kind | Written as | Who decides it |
|---|---|---|
| an answer | what the person types | the person |
| a default | default = 60 |
you, until somebody answers |
| a computed value | value = … |
the document, always |
default — the answer until there is one
form loan version = "1.0" {
field term {
type = integer
label = "Term in months"
default = 60
}
}
Until the applicant answers, term holds 60. When they answer 36,
term holds 36 and the default is gone. A default is never computed and
never recalculated; it is simply the answer until there is another one.
value — the document computes it
form loan version = "1.0" {
field term { type = integer }
field amount { type = number }
field monthly { type = number value = pmt(0.05 / 12, term, amount) }
field total { type = number value = monthly * 12 }
}
monthly is not a question. It is an expression over two other fields, and it
is recomputed whenever either of them changes.
You never assign to a value. There is no = that writes; the = in
value = … is the same = that declares a property, and the right-hand side
is an expression the runtime evaluates.
When a value recomputes
The runtime builds a dependency graph from the expressions and works out what to recompute. It is not a rule you write:
monthlyreadstermandamount, so it recomputes when either changes.totalreadsmonthly, so it recomputes whenmonthlychanges — which is whentermoramountchanges.
You never write "recompute this when that changes". You write what a value means, and the graph follows.
There is one subtlety, and it is worth stating plainly: a value that reads a field which is not applicable does not get a stale answer, it gets unknown. See section 10.
A value and a default together
// E-CONFLICT-01: a value and a default contradict each other.
form loan version = "1.0" {
field notes {
type = string
default = "computed"
value = "computed"
}
}
This document is wrong, and the reference implementation says so:
E-CONFLICT-01. A value and a default on the same field say contradictory
things about the same field — one says "this is what the answer is", the other
says "this is what the answer is until somebody answers". Pick one.
The output document
A form produces a document, and you say what it looks like in an output
block:
form loan version = "1.0" {
field term { type = integer }
field amount { type = number }
field monthly { type = number value = pmt(0.05 / 12, term, amount) }
output {
term: integer
amount: number
monthly: number
}
}
The output block is a schema, not a projection. term: integer says
"the output document has a key term whose type is integer" — the value
comes from the field of the same name. You do not write term: term.
A computed field appears in the output like any other, under its own name.
Section 13 covers the output document properly, including what happens to a field that was never answered.