Stringification with multimethods and traits Creating the trait and multimethod Creating our own type Using our extensible stringification capabilities for logging

Stringification with multimethods and traits

This example shows how JSOS enables you to easily create extensible functions and types.

First, we will create a multimethod for converting things to strings and a Stringifyable trait that signals that a type can be turned into a string.

Then we will add a new type that implements stringification by extending the previously written code.

You can find the full example code in the git repository of JSOS.

Creating the trait and multimethod

First, lets create a trait that represents when a type can be stringified, and a multimethod that can do the stringification.

/* ------------------------------------------------------- stringification.js */

import { Trait, TraitItem, Generic, TAny } from "@fed1/jsos";

export const { stringify } = Generic;

export const { IStringifyable } = Trait(
    [stringify, TAny] // describes a method's expected signature
);

Creating our own type

Now we can create our own type and make it IStringifyable by implementing stringify for the trait.

/* --------------------------------------------------------------- my-type.js */

import { Type, Struct, def, JSString, JSNumber } from "@fed1/jsos";
import { IStringifyable, stringify } from "./stringification.js";

// 'Type' creates new abstract types
export const { TMyAbstractType } = Type;

// 'Struct' creates new concrete types
export const { MyType } = Struct({
    name: JSString.where(s => s.length > 0), // creates a dependent type
    id: JSNumber.where(n => n > 0)
})(TMyAbstractType); // subtype

// Add another constructor for convenience
def(MyType.new, [JSString, JSNumber], (name, id) => ({name, id}));

// Make our type an IStringifyable
MyType.implement(IStringifyable, [
    def(stringify, [TMyAbstractType], t => `Name: ${ t.name }, ID: ${ t.id }`)
]);

Using our extensible stringification capabilities for logging

Then we can create a multimethod for logging stuff that can print any object whose type implements IStringifyable to the console.

/* --------------------------------------------------------------- logging.js */

import { Generic, def } from "@fed1/jsos";
import { IStringifyable, stringify } from "./stringification.js";

export const { log } = Generic;

def(log, [IStringifyable], s => console.log(stringify(s)));

Finally, we can use the new log multimethod.

/* ----------------------------------------------------------------- index.js */

import { log } from "./logging.js";
import { MyType } from "./my-type.js";

log(MyType.new("John", 21)); // Name: John, ID: 21

Note: JSOS already comes with a built-in stringify multimethod.