Composite Types (Structs) Constructors Parameterization

Composite Types (Structs)

Constructors

In JSOS, structs have a constructor property .new. This is actually not just a regular function, it's a multimethod! This means that, just like with all other multimethods, you can define new methods on it:

import { Type, Struct, isA, def, JSNumber, JSString } from "@fed1/jsos";

const { MyAbstractType } = Type;

const { MyType } = Struct({
    name: JSString,
    id: JSNumber
}, [MyAbstractType]);

def(MyType.new, [JSString, JSNumber], (name, id) => MyType.new({name, id}));

const mct = MyType.new("Foo", 1);

Each custom constructor method should return with a call to the default constructor, which expects a regular JSObject containing all the properties required by the struct.

Parameterization

The types created using Struct or MStruct can have type parameters as well. This allows for a version of generic programming.

Both Struct and MStruct can be called as functions to supply the root types of the to-be-created parameterized struct.

When you specify root types, you are required to supply the struct's schema wrapped in a function instead of as a regular object.

This wrapper function is then given the actual types that are supplied to be used in place of the root types. The supplied types need to be either the root type itself or subtypes of the root type, and they need to be in the same order as the specified root types.

Here's an example of how to define and use parametric types:

import { Type, Struct, TNumber, TReal } from "@fed1/jsos";

const { MyType } = Type;

const { ParaStruct } = Struct(TNumber)(T => ({
    x: T,
    y: T
}))(MyType);

const psReal = ParaStruct(TReal).new({
    x: 5.5,
    y: 2.3
});

When ParaStruct(TReal).new() is called, the supplied function is given the TReal that is used as a replacement for the TNumber used in the call to Struct(TNumber). Functions given as an argument instead of a schema object are expected to produce a schema object where all the parameters have been inserted at the appropriate places.

What this means in the example above is that any type created with ParaStruct must have x and y values that are some kind of number type.

The example only demonstrates this for one parameter, but any number of parameters can be specified for a struct.