# Compositions
 
Composer makes it possible to assemble actions into rich workflows called _compositions_. An example composition is described in [../README.md](../README.md).

## Control flow

Compositions can express the control flow of typical a sequential imperative programming language: sequences, conditionals, loops, error handling. This control flow is specified using _combinator_ methods such as:
- `composer.sequence(firstAction, secondAction)`
- `composer.if(conditionAction, consequentAction, alternateAction)`
- `composer.try(bodyAction, handlerAction)`

Combinators are described in [COMBINATORS.md](COMBINATORS.md).

## Composition objects

Combinators return composition objects, i.e., instances of the `Composition` class.

## Parameter objects and error objects

A composition, like any action, accepts a JSON dictionary (the _input parameter object_) and produces a JSON dictionary (the _output parameter object_). An output parameter object with an `error` field is an _error object_. A composition _fails_ if it produces an error object.

By convention, an error object returned by a composition is stripped from all fields except from the `error` field. This behavior is consistent with the OpenWhisk action semantics, e.g., the action with code `function main() { return { error: 'KO', message: 'OK' } }` outputs `{ error: 'KO' }`.

Error objects play a specific role as they interrupt the normal flow of execution, akin to exceptions in traditional programming languages. For instance, if a component of a sequence returns an error object, the remainder of the sequence is not executed. Moreover, if the sequence is enclosed in an error handling composition like a `composer.try(sequence, handler)` combinator, the execution continues with the error handler.

## Data flow

The invocation of a composition triggers a series of computations (possibly empty, e.g., for the empty sequence) obtained by chaining the components of the composition along the path of execution. The input parameter object for the composition is the input parameter object of the first component in the chain. The output parameter object of a component in the chain is typically the input parameter object for the next component if any or the output parameter object for the composition if this is the final component in the chain.

For example, the composition `composer.sequence('triple', 'increment')` invokes the `increment` action on the output of the `triple` action.

Some combinators however are designed to alter the default flow of data. For instance, the `composer.retain(myAction)` composition returns a combination of the input parameter object and the output parameter object of `myAction`.

## Components

Components of a compositions can be actions, Javascript functions, or compositions.

Javascript functions can be viewed as simple, anonymous actions that do not need to be deployed and managed separately from the composition they belong to. Functions are typically used to alter a parameter object between two actions that expect different schemas, as in:
```javascript
composer.if('getUserNameAndPassword', params => ({ key = btoa(params.user + ':' + params.password) }), 'authenticate')
```

Compositions may be nested inside compositions in two ways. First, combinators can be nested, e.g.,
```javascript
composer.if('isEven', 'half', composer.sequence('triple', 'increment'))
```
Second, compositions can reference other compositions by name. For instance, assuming we deploy the sequential composition of the `triple` and `increment` actions as the composition `tripleAndIncrement`, the following code behaves identically to the previous example:
```javascript
composer.if('isEven', 'half', 'tripleAndIncrement')
```
Observe however, that the behavior of the second composition would be altered if we redefine the `tripleAndIncrement` composition to do something else, whereas the first example would not be affected.

## Nested declarations

A composition can embed the definitions of none, some, or all the composed actions as illustrated in [demo.js](../samples/demo.js):
```javascript
composer.if(
    composer.action('authenticate', { action: function ({ password }) { return { value: password === 'abc123' } } }),
    composer.action('success', { action: function () { return { message: 'success' } } }),
    composer.action('failure', { action: function () { return { message: 'failure' } } }))    
)
```
Deploying such a composition deploys the embedded actions.

A composition can also include the definition of another composition:
```javascript
composer.if('isEven', 'half', composer.composition('tripleAndIncrement', composer.sequence('triple', 'increment')))
```
In this example, the `composer.sequence('triple', 'increment')` composition is given the name `tripleAndIncrement` and the enclosing composition references the `tripleAndIncrement` composition by name. In other words, deploying this composition actually deploys two compositions:
- a composition named `tripleAndIncrement` defined as `composer.sequence('triple', 'increment')`, and
- a composition defined as `composer.if('isEven', 'half', 'tripleAndIncrement')` whose name will be specified as deployment time.

## Serialization and deserialization

 Compositions objects can be serialized to JSON dictionaries by invoking `JSON.stringify` on them. Serialized compositions can be deserialized to composition objects using the `composer.deserialize(serializedComposition)` method. The JSON format is documented in [FORMAT.md](FORMAT.md).
 In short, the JSON dictionary for a composition contains a representation of the syntax tree for this composition as well as the definition of all the actions and compositions embedded inside the composition.

## Conductor actions

Compositions are implemented by means of OpenWhisk [conductor actions](https://github.com/apache/incubator-openwhisk/blob/master/docs/conductors.md). The conductor actions are implicitly synthesized when compositions are deployed using the `compose` command or the `composer.deploy` method. Alternatively, the `composer.encode` method can encode compositions without deploying them. See [COMPOSER.md](COMPOSER.md) for details.