Building extensible architectures with JSOS How JSOS's types and multimethods provide extensibility Decoupling methods from classes Decoupling type hierarchy and concrete types Example: Creating a new container type Use Case 1: Extending a base software by providing customer-specific modules Use Case 2: Letting users extend your software by writing plugins

Building extensible architectures with JSOS

JSOS was designed from the ground up to make building extensible software easy. Learn how it can help you create a JavaScript project that can easily be extended by modules or plugins.

How JSOS's types and multimethods provide extensibility

Most programming languages can be categorized into the following groups:

  • Object-oriented languages where the object is the fundamental building block
  • Functional languages where the function is the fundamental building block

In object-oriented languages, it's easy to create new types (classes) that work with existing methods. On the other hand, it's not that easy to write new methods for existing types.

In functional languages, it's trivial to write new functions that work on existing types, but making new types work with existing functions is hard.

A truly extensible software is a software where both creating new types for existing functions and creating new functions for existing types is easy.

JSOS solves this issue for JavaScript code by decoupling methods from classes and splitting the type hierarchy into abstract and concrete types.

Decoupling methods from classes

In JSOS, methods are part of generic functions called multimethods instead of belonging to any class or type. A multimethod presents itself as just another function. You can call it like any other function in JavaScript, and you can also pass it around as a callback. From the perspective of the consumer of a multimethods, it isn't any different than all the other functions they encounter.

However, internally, multimethods delegate the actual work to an appropriate method that is registered to the multimethod. And this dispatch to the appropriate method happens by looking at the types of the arguments that are provided when calling the multimethod like a function.

Decoupling type hierarchy and concrete types

The type system built into JSOS makes a fundamental distinction between what it calls abstract and concrete types.

An abstract type is a type that lives somewhere in the type hierarchy but can never be instantiated to a concrete value or object. An abstract type can have one or more parent types and also be a parent to any number of other abstract and concrete types. If an abstract type is not explicitly bound to a parent in the type hierarchy, it is assigned the 'TAny' type as a parent automatically.

A concrete type (or data type) is a type that represents actual values in your software. Concrete types always have at least one abstract type as a parent and cannot itself be a parent to any other type.

Example: Creating a new container type

Let's go through an example of how to create a new type that works with existing code. Let's say that you need to create a new kind of object that acts as a container of items. Of course you would want this container to work with your existing algorithms that involve iterating over a list of items.

To accomplish this in JSOS, all you have to do is implement a trait called Iterable for your type. A trait is a kind of interface specification that basically says "if a type works with these specific multimethods, it conforms to this trait".

Use Case 1: Extending a base software by providing customer-specific modules

Use Case 2: Letting users extend your software by writing plugins