Context

A Reactive.Context is a set of functions with a dynamic implementation. Those functions are called like any other function. The block contains only inputs, outputs, bindings, and holes. A struct, a function, or a constant of the same name lives in the module, not in the context.

Reactive.Context("Content", () => {
  Reactive.Hole("Text", () => {
    Reactive.Input(Text.Plain);
  });
  Reactive.Hole("Title", () => {
    Reactive.Input(Text.Plain);
  });
});
A Content context, with Text and Title holes.

With

Reactive.With sets some contexts, then runs with those implementations in place. A context is set by calling it with a block. Each hole is set the same way. The parameters of a hole block are that hole's inputs, in order. After the settings, the block calls the hole that fills them.

Reactive.With(() => {
  Content(() => {
    Text((text) => {
      const textValue = Ui.Value.text(text);
      const attributes = Collection.Map.Gather(() => {
        Collection.Map.Gather.Entry("text", textValue);
      });
      const component = Ui.Component("Ui.Text", attributes);
      Reactive.Emit("components", component);
    });
    Title((text) => {
      Content.Text(text);
    });
  });
  children();
});
One With. Title calls the Content.Text from underneath this layer.

One With is one layer. A body written in that layer calls the implementation underneath it: a context set by an outer With, or the driver that was already there. It does not call a body written in the same block, including its own. A nested With sees the layer above. The code after the settings uses the layer just installed.

The same name

A context may share its name with a module or with a function. Button.Select is both. The function takes the output and the options hole, sets the context, and calls the hole. The context is the hole Option.

Reactive.Function("Select", () => {
  const settableValue = Reactive.Output(OptionValueType);
  const options = Reactive.Hole("options");

  Reactive.With(() => {
    Button.Select(() => {
      Option((value, content) => {
        Button.Setter(settableValue, value, content);
      });
    });
    options();
  });
});

Reactive.Context("Select", () => {
  Reactive.Hole("Option", () => {
    Reactive.Input(OptionValueType);
    Reactive.Hole("content");
  });
});
The function and the context share the name. The function fills Option.

Drivers

The implementation at the top is a driver, injected before the program runs. A call of that context during the refresh enters the driver. A With inside the program can take the same context for itself. Those calls do not reach the driver.