Targets · TypeScript · Example
Example
The whole language in one short program — a module with a record, a tagged union, a function with per-platform native bodies, and a function that wires up state, a write-back and a return — and the complete TypeScript it renders to. It is the same program shown on the language page.
Contents
How a Program becomes TypeScript, in parts. Start with the introduction, then follow each part into the rendered output and the runtime it links against.
- Introduction — what the TypeScript target is, and how to read the rest of this section.
- Capabilities — which high-level features are possible, built in or through a library.
- Example — a full program using every keyword, and the TypeScript it renders to.
- Naming considerations — how Program's dotted names are carried into TypeScript.
- Entry point — starting a program and attaching it to a root element.
- Drivers — the native drivers that provide the interface, animation and network.
- Runtime — the Reactive and Context machinery the rendered code links against.
- Native modules — the hand-written JavaScript behind
NATIVEfunctions. - Keywords — how each of Program's keywords renders to TypeScript.
- Project setup — the files and commands to build and run the rendered program.
- Reserved words — the words TypeScript keeps for itself, and how a colliding name is escaped.
Every keyword, in one program
Each keyword has its own page under keywords; here they are all together.
MODULE App
TYPE Profile
FIELD Text name
FIELD Maths.Integer age
TYPE Status
OPTION App.Profile active
OPTION Text pending
FUNCTION Text Greet
INPUT Text name
NATIVE js "return 'Hi ' + name;"
NATIVE dart "return 'Hi ' + name;"
NATIVE swift "return \"Hi \" + name"
FUNCTION Text Welcome
INPUT BINDING App.Profile profile
HOLE Text row
INPUT Text line
STATE Maths.Integer count = 0
STATE LOCKED Network.Web.Response saved = null
REVERSE App.Profile submit
LET Network.Web.Response response = Network.Web.Client.Post profile
SET saved = response
LET Text label = Maths.Integer.ToString count
= label
Rendered TypeScript
The same output as JavaScript, with Program's
types written out. The module is a namespace; the record is a class with typed fields;
the union is a discriminated type with constructors; the function carries its input, hole and return
types, and reactive values are ReactiveValue<T>.
namespace App {
export class Profile {
constructor(public name: string, public age: number) {}
}
export type Status =
| { tag: 'active'; value: App.Profile }
| { tag: 'pending'; value: string };
export const Status = {
active: (value: App.Profile): Status => ({ tag: 'active', value }),
pending: (value: string): Status => ({ tag: 'pending', value }),
};
export function Greet(name: string): string {
return 'Hi ' + name; // the js NATIVE body, valid TypeScript
}
export function Welcome(
profile: App.Profile,
row: (line: string) => ReactiveValue<string>,
): ReactiveValue<string> {
const count = Program._Runtime.Reactive.State<number>(0);
const saved = Program._Runtime.Reactive.StateLocked<Network.Web.Response>(null);
Program._Runtime.Reactive.Reverse(submit, () => {
const response = Network.Web.Client.Post(profile);
Program._Runtime.Reactive.Set(saved, response); // SET
});
const label = Maths.Integer.ToString(count);
return label;
}
}
Reading it
Indentation becomes nested closures, as in every target; the difference here is purely the annotations Program's types add. Dotted names pass straight through as nested namespaces — see naming considerations. The per-keyword mapping is on keywords.