Service

The functional blocks of an ApolloGeese solution

Because this is a more in depth article, example implementations will be provided in three formats, preceeded by a description, like so:

A description for illustrational purposes (in CLON examples, enclosure between { instances = { and }; } is implied)
// C# example code
this.Uh("?");
// You look gorgeous today

// Basic CLON example code
{
    instances = {
    };
}

// Pleasant CLON example code
{
    instances = {
    };
}

That doesn't mean you should use anything else than Pleasant CLON. Pleasant CLON is just so much more pleasant.

The Anatomy of a Service

A service typically abstracts one (and only one) regularly implemented algorithm or automation and makes it available under a short, descriptive name. A service may be instantiated like this:

Instantiate a new UsefulService and name it 'newService' (not a recommended naming scheme outside of example documentation)
// C#
Service newService;
newService = new UsefulService();

// BCLON
newService = {
type = "UsefulService";
};

// PCLON
newService = UsefulService();

Calling

Because a Service is intended to fulfill precisely one functionality, it has only one entry point by which it may be activated; in CLON, a reference to the service that is to be activated, suffices for activating. There are a few exeptions to this.

We however don't assume a Service can produce precisely one output, so each Service has multiple named points of exit. We call these branches.

Instantiate a UsefulService and name it 'calledService', instantiate an AnotherService and name it 'callingService'. Assign the calledService to the done-branch of the callingService.
// C#
Service calledService;
calledService = new UsefulService();
Service callingService;
callingService = new AnotherService();
callingService.Branches["done"] = calledService;

// BCLON
calledService = {
    type = "UsefulService";
};
callingService = {
    type = "AnotherService";
    done_branch = instances.calledService;
};

// PCLON
calledService = UsefulService();
callingService = AnotherService() {
    done->instances.calledService;
};

In CLON, anything in the top level of instances is considered 'exposed'. (this is the case in above examples) More on the matter here: exposure with Module and CLON

Settings

Optionally, a service may expose a couple of mutable properties (which is fancy speak for Settings). These settings will be loaded after construction of the service.

Initiate a UsefulService named 'newService' and configure it with the parameter "test" set to 1.
// C#
Settings settings = new Settings();
settings["test"] = 1;
newService = new UsefulService();
newService.SetSettings(settings);

// BCLON
newService = {
    type = "UsefulService";
    modconf = {
        test = 1;
    };
}

// PCLON
newService = UsefulService(test = 1);

Self-invoking

The notion that only Service branches are able to activate other Services, is somewhat paradoxical, and also false. There's a selection of Services that have a remarkable property of initiating a program flow autonomously and/or based upon external triggers.

An incomplete list of Services that are capable of starting program flow: