FS FormScript

What FormScript is

A form is a program that asks questions. FormScript is the language those programs are written in.

That is the whole idea, and everything else in this tutorial follows from it. A form that asks "what is your date of birth?" is not a picture of a form and a list of rules — it is a program. The questions, the rules, the computed values, the validation and the output document are all one document, and the document is the program.

The first document

forms
form hello version = "1.0" {
  field name {
    type = string
    label = "Your name"
  }

  field greeting {
    type = string
    value = "Hello, " + name
  }

  output {
    name: string
    greeting: string
  }
}

Read it aloud:

  • form hello version = "1.0" — the document declares a form named hello and the version of the language it is written in.
  • field name — a question. Its type is string.
  • field greeting — not a question: a computed value. It is the text "Hello, " followed by whatever the answer to name is.
  • output — the shape of the document this form produces.

Answer the form with name=Ada and the output document is:

json
{ "name": "Ada", "greeting": "Hello, Ada" }

You can run that right now: open the playground, paste the document, and answer the question.

Why write it this way

The reason a form is a program, rather than a form plus rules, is that the same form has to be asked on a web page, on a phone, on a kiosk and in a printable document. When those are four different codebases, the rules drift: the web app validates the phone number, the PDF does not, and the two answers disagree about whether the form was ever valid.

One document, one set of rules, one answer — whatever renders it.

What it is not

FormScript has no loops you write by hand, no assignments to variables, and no exceptions. It has fields, expressions over those fields, and the runtime works out what to recompute and when. A field that has never been answered is unknown rather than empty, and an expression that cannot be evaluated is not a crash but a value — the specification calls it the error value.

There is no undefined in this language, and there is no way to write a program that stops halfway.

Where the language came from

It was written for forms that a regulator has to be able to read: a document precise enough that an implementation can be checked against it rather than admired. Every decision in the reference implementation traces to a numbered statement in the specification, and where the specification was wrong, it was repaired in the specification, in public, with the repair written down.

So this is a language you can read the definition of. The rest of this tutorial is that definition, in pieces.