Functions

The first calls in a Reactive.Function body are its arguments. A function that returns a value ends with return name, and that name is already in the function.

Reactive.Function("Greeting", () => {
  const person = Reactive.Input(People.Person);

  Layout.Row(() => {
    Content.Text("Hello, ");
    Content.Text(person.name);
  });
});
Greeting takes a Person. The field read is a calculation.

Arguments

Arguments are lines at the top of the function. Those lines are Reactive.Input and Reactive.Hole. Each line carries a type, so every argument is type-checked.

Inputs

Reactive.Input(Type) is readable. The const on the left is the name of the argument. The caller passes a readable value, or a binding. The function reads the name. It does not write it.

Reactive.Function("Greeting", () => {
  const person = Reactive.Input(People.Person);

  Content.Text(person.name);  // read the input
});

const ada = People.Person("Ada Lovelace", 36);
Greeting(ada);  // pass a readable value
The function reads person. The caller passes a Person.

Holes

Reactive.Hole("name") is a block the caller fills. The function runs that block. Reactive.Hole(Type, "name") is a hole that returns that type. The block of a hole contains only inputs and holes.

Reactive.Function("Panel", () => {
  const content = Reactive.Hole("content");

  content();  // run the caller's block
});

Panel(() => {
  Content.Text("Hello");
});
The hole's name is not written at the call. The block is the argument.

Calling

A call that returns is a const. A call that does not return is the call on its own line. Arguments are passed in order. The last hole is the block, and the hole's name is not written again.

const ada = People.Person("Ada Lovelace", 36);
Greeting(ada);

Panel(() => {
  Content.Text("Hello");
});
Greeting takes the person. Panel takes the block, and the hole's name is not written again.

Generics

A generic type is a parameter of the function. The function uses that parameter as the type of an input. The call is curried. The first call passes the types. The second call passes the normal arguments.

Reactive.Function("Show", (Value) => {
  const item = Reactive.Input(Value);  // an argument of the generic type

  Content.Text(item);
});

const name = Reactive.State(Text.Plain)("Ada");
Show(Text.Plain)(name);  // types, then the normal arguments
Show takes one type, then one value of that type.