# Fabula’s Computation Logic

One of Fabula’s most interesting features is its computation (success/failure) logic. Due to this feature, Fabula parts with the traditional concept of ‘program exception’, as well as with the inevitable Boolean data type.

An important concept that needs to be introduced first is the concept of a computation’s success or failure.

There are two kinds of computations in Fabula: an expression and a statement.

An expression computes and returns some anonymous value based on the values of input variables. When for any reason it is not possible (e.g. we are trying to compute an array element beyond the index range), we say that the expression fails. When an expression has failed, it has no meaningful result, and therefore any other expressions that rely on this result must also fail.

Expressions will be discussed separately. From the computation logic point of view, an expression will always fail if any subexpression fails; the only exception is a conditional expression – if the condition fails, the second alternative is evaluated.

In general, a statement differs from an expression only in one respect: its results have explicit names. We call them output variables. Depending on the kind of the statement, it may have zero, one or more output variables. Regardless of the number of the output variables, the statement may succeed or fail.

There are six kinds of statements in Fabula: `<is>`, `<def ...>`, `<unwrap>`, `<all>`, `<any>` and `<not>`.

The simplest statement is `<is>` with the following syntax:

`<is>` expression `</is>`

Such a statement simply evaluates the expression and fails if it failed; if it succeeded, the result is ignored. Most often, the expression used in <is> returns a value of the null data type (see Fabula’s Type System). Such expressions are called relations. For example:

```<is>index = input.click</is>
```

Another elementary statement is <def …>:

`<def var="name">` expression `</def>`

This statement evaluates the expression and defines a new variable with the given name attached to that value. The variable can be used as input in expressions in the appropriate scope.

For example:

```<def var="value">state.position[index]</def>
```

<unwrap> is a convenience feature, allowing to define a group of variables from the properties of a composite object. The syntax:

`<unwrap>` expression `</unwrap>`

For example:

```<unwrap>{name: "Fabula", rank: 9999}</unwrap>
```

defines two variables – `name` with value “Fabula” and `rank` with value 9999.

To compose more complex statements, `<all>`, `<any>` and `<not>` constructs are used.

<all> is called conjunction and has the syntax:

<all> statement … </all>

This statement succeeds when all the statements inside it succeed. Each statement can use as input any variables defined by the preceding statements, but not vice versa. Conjunction returns all the output variables defined by the statements inside. For example:

```<all>
<is>state.content.cross</is>
<is>input.win</is>
<def var="newcontent">{wincross:}</def>
</all>
```

<any> is called disjunction and has the syntax:

<any> statement … </any>

This statement succeeds when any of the statements inside it succeeds. The statements can’t use each other’s output variables. Disjunction returns only the output variables returned by each of the statements inside. For example:

```<any>
<is>data.a = state.square</is>
<is>data.b = state.square</is>
<is>data.c = state.square</is>
</any>
```

<not> is called negation and has the syntax:

<not> statement </not>

This statement succeeds when the statement inside it fails and fails when it succeeds. Any output variables of the internal statement are ignored.

The statement composition rules are designed to ensure that

1. by looking at any statement, one can always figure out what variables the statement defines (its output)
2. when a statement succeeds, all its output variables are defined
3. if a statement has failed, any statements using its outputs will not be evaluated; no special checking for undefined variables is needed