Types
ReactiveJS provides Structured Records (a set of fields which are all present in a value) and Tagged Unions (a set of fields where just one is present at any one time), both supporting Generic Types.
Reactive.Module("People", () => {
Reactive.Struct("Person", () => {
Reactive.Field(Text.Plain, "name");
Reactive.Field(Maths.Integer.Number, "age");
});
Reactive.Union("Contact", () => {
Reactive.Field(Text.Plain, "email");
Reactive.Field(Text.Plain, "phone");
});
});Struct types
A struct type contains a set of fields which are all present in any instance of this type.
Definition
Give the struct a Reactive.Field for each field. Field takes the type, then the
name. A field is ordinary data.
Reactive.Struct("Person", () => {
Reactive.Field(Text.Plain, "name");
Reactive.Field(Maths.Integer.Number, "age");
});Creation
The callback's parameters are the generic types. A callback with no parameters is the constructor. Call it with the field values in the order the fields were declared. A callback with parameters takes those types and returns the constructor.
const ada = People.Person("Ada Lovelace", 36);Field Values
Reach a field with plain dotted access. ada.name is the reactive value for that field.
Content.Text(ada.name);Tagged union types
Tagged union types hold exactly one of a set of named variants at a time. The tag says which variant is in play, and each variant carries a value of its own type.
Definition
An option is the same Reactive.Field line. Option names are lowercase. A locked payload does not
lock the union value. Reading the option does.
Reactive.Union("Contact", () => {
Reactive.Field(Text.Plain, "email");
Reactive.Field(Text.Plain, "phone");
});Creation
Construct a union by calling the variant: MyModule.UnionName.variantName(...). That call selects
the variant. The callback's parameters are the generic types. A callback with no parameters puts those
variant constructors on the union. A callback with parameters takes those types and returns the union
whose variants are the constructors.
const how = People.Contact.email("ada@engine.org");People.Contact.email builds the email variant.Variant Values
how.email is an optional of that option's type. It is present when the union is that option.
Collection.Optional is a context. some carries the value. none carries
Collection.Void. Collection.Optional.Default returns the value, or the fallback when
the optional is none.
const address = Collection.Optional.Default(how.email, "");
Content.Text(address);Generic types
A generic type takes one or more types and uses those types in its fields. One definition then builds a struct or a union for each set of types you pass.
Defining generic types
The parameters of the callback are the generic types. A field uses a parameter as its type. A struct lists every field. A union lists its options, and a value has one of them.
Reactive.Module("People", () => {
// a record: both fields are present, each of its own type
Reactive.Struct("Pair", (Left, Right) => {
Reactive.Field(Left, "left");
Reactive.Field(Right, "right");
});
// a union: one option is present, and ok carries the given type
Reactive.Union("Result", (Value) => {
Reactive.Field(Value, "ok");
Reactive.Field(Text.Plain, "error");
});
});Using them
Call the name with the types. A struct call returns the constructor, and that constructor takes the field values in order. A union call returns the variants, and a variant call builds the value.
// create a Pair of a string and an integer
const NameAndAge = People.Pair(Text.Plain, Maths.Integer.Number);
const ada = NameAndAge("Ada Lovelace", 36);
// create a Result of a string
const TextResult = People.Result(Text.Plain);
const saved = TextResult.ok("saved");Built-in types
String, integer, and float come from the driver that implements their context. The integer type is
Maths.Integer.Number. Logic.Maybe is the boolean, and If reads it.
An array is Collection.Array.Of(ElementType). Examples write strings as Text.Plain
and floats as Maths.Real.
Reactive.Type("Name", Other) names an alias of Other. An alias is a different type
from the type it names. A place that expects a type accepts an alias of that type. A sibling alias is not
accepted.