Make calculations with expression blocks, process arrays and tensors, conditional expressions, JavaScript.

```
var iframer = require('./iframer')
```

## Why expressions¶

An expression is any valid unit of code that resolves to a value. (source)

To make a model useful, data is not enough. It's usually transformed in different ways to get a result. Expressions in StatSim are blocks that describe such transformations. An expression block includes the name field that makes it possible to use expression output later in the model. The second field is the actual expression. It shows the expression itself.

## Simple formulas¶

StatSim is based on WebPPL which is based on JavaScript. So almost any expression you can write in JavaScript, you can also write in StatSim. WebPPL adds its own list of helper functions so you can also use it with JS native functions. Examples of correct expressions include:

`10 + 1`

`x * (y - 5)`

where`x`

and`y`

are declared somewhere else`fn(x)`

where`fn`

is a function

## Math object¶

Sometimes basic arithmetic operators are not enough. If you want to use a mathematical constant (like `PI`

or `E`

) or a function (like `sin`

, `cos`

etc) you can call `Math`

object in your expression:
`Math.PI`

`Math.sin(5)`

`Math.min(x,y)`

Full list of `Math`

properties and methods find here: Math (MDN)

## Example: Loan calculator¶

At the moment we know how to add input parameters to the model (data blocks) and set relationship between them (expressions). Let's make something a little more useful model than one that sums `a`

and `b`

. Our new model calculates loan monthly payments. Inputs are `Principal`

(amount of borrowed money, dollars), `Rate`

(annual percentage rate, percents) and `Term`

(amount of time in which the loan will be repayed, months). We assume our loan is a fixed rate mortgage, with the corresponding formula for monthly payments:

To make use of the formula we should convert annual percentage rate in `%`

to the monthly rate using the formula:

So, in our model we should have 3 data inputs and 2 expressions (the first one to calculate monthly rate, the second for the final output). Corresponding expressions are:

`AnnualRate / (12 * 100)`

`Principal * MonthlyRate * Math.pow(1 + MonthlyRate, Term) / (Math.pow(1 + MonthlyRate, Term) - 1)`

You can see that we use the `Math`

object and its function `pow(x,n)`

that raises `x`

to the power of `n`

. In our case x is `1 + MonthlyRate`

and `n`

is `Term`

. This expression is quite long and has repeating pattern. It's a good practice to separate such repeating blocks. So let's create one more expression that calculates value `Math.pow(1 + MonthlyRate, Term)`

and call it `Pow`

. Our final expression is

`Principal * MonthlyRate * Pow / (Pow - 1)`

```
iframer('https://statsim.com/app/?a=%5B%7B%22b%22%3A%5B%7B%22n%22%3A%22Principal%22%2C%22sh%22%3Afalse%2C%22t%22%3A2%2C%22u%22%3Atrue%2C%22dims%22%3A%22%22%2C%22v%22%3A%22200000%22%7D%2C%7B%22n%22%3A%22AnnualRate%22%2C%22sh%22%3Afalse%2C%22t%22%3A2%2C%22u%22%3Atrue%2C%22dims%22%3A%22%22%2C%22v%22%3A%229%22%7D%2C%7B%22n%22%3A%22Term%22%2C%22sh%22%3Afalse%2C%22t%22%3A2%2C%22u%22%3Atrue%2C%22dims%22%3A%22%22%2C%22v%22%3A%22360%22%7D%2C%7B%22n%22%3A%22MonthlyRate%22%2C%22h%22%3Afalse%2C%22sh%22%3Afalse%2C%22t%22%3A1%2C%22v%22%3A%22AnnualRate%20%2F%20%2812%20%2A%20100%29%22%7D%2C%7B%22n%22%3A%22Pow%22%2C%22h%22%3Afalse%2C%22sh%22%3Afalse%2C%22t%22%3A1%2C%22v%22%3A%22Math.pow%281%20%2B%20MonthlyRate%2C%20Term%29%22%7D%2C%7B%22n%22%3A%22Payment%22%2C%22h%22%3Afalse%2C%22sh%22%3Atrue%2C%22t%22%3A1%2C%22v%22%3A%22Principal%20%2A%20MonthlyRate%20%2A%20%20Pow%20%2F%20%28Pow%20-%201%29%22%7D%5D%2C%22mod%22%3A%7B%22n%22%3A%22Mortgage%20Calculator%22%2C%22e%22%3A%22Monthly%20payment%20calculator%20for%20a%20fixed%20rate%20mortgage.%22%2C%22s%22%3A1%2C%22m%22%3A%22deterministic%22%7D%2C%22met%22%3A%7B%22sm%22%3A1000%7D%7D%5D')
```

In this example, we created three data blocks as input parameters, and three expressions, where `Payments`

is the model output (`Show in output`

flag). We also use the `Math.pow()`

function that takes two arguments and raises the first one to the power of second. You can also create your own functions.

## Functions¶

You can create functions just as you created expressions. Choose a proper name and then instead of writing operators and regular method, type a special function template `function (x,y) {return x * y}`

. In round brackets put function parameters (inputs), after `return`

write the output expression. Then you can use that function in other blocks. Currently I'm not sure if it's a good idea to separate functions in a separate block type. What do you think?

## Array expressions¶

When your input is not a scalar value like `5`

or `true`

but a list of values (array), you can't just use the same scalar operators and write expressions as `a + b`

where `a`

and `b`

are arrays. To compose array expressions use built-in functions.

`map(fn, arr)`

`mapN(fn, n)`

`reduce(fn, init, arr)`

`filter(predicate, arr)`

`sum(arr)`

`product(arr)`

`listMean(arr)`

- ...

I'll not list all the functions. Just check the reference here

## Conditional expressions¶

Express should return value. That's why you can't use `if`

,`else`

,`while`

and other JavaScript statements that don't return values when executed. Luckily there's a conditional expression that can be used to control what value is returned. It looks like this:

`(condition) ? true_expression : false_expression`

If `condition`

is true the whole expression evaluates to `true_expression`

otherwise to `false_expression`

.
Read about conditional (ternary) operator here