# Special Formulas & Functions

SEL 102: Lists and Growth Rates

SEL formulas aren't limited to basic arithmetic. Let's learn about some very handy special formulas and functions: lists and growth rates, and lists of growth rates!

# Lists

What if you want an event to represent a list of values? Simple:

`=[1,2,3,4]`

Is a valid SEL formula.

So is:

`* [1, 2, 3, 4] # Spaces are ignored`

When you declare a list, an event will pop the first value off the list each time it is triggered. So after the above SEL formula runs once, the internal state of the event will be a shorter list, i.e. `[2,3,4]` then `[3,4]`, then ``.

What happens when a list gets to a single element? The final element in the list will be used until the simulation terminates. So in our example, if you ran a 5-month simulation and the above event recurred monthly, the number `4` would be returned by the event for the fifth month.

If you want the event to return zero for months after the 4th, you would simply declare the list with a final `0` element: `=[1,2,3,4,0]`.

## Repeating Lists

Sometimes it's helpful to repeat a list from the beginning, rather than repeating the final element. To do so, append an `*` to the end of the list:

`=[1,2,3,4]*`

This will generate an infinite sequence of 1, 2, 3, 4, then 1 again: 1, 2, 3, 4, 1, 2, 3, 4, ...

This is useful for situations where the same pattern needs to be repeated over some time interval. One list element could represent each month of a calendar year, for example.

Please note: as of this writing, repeating lists are not available when lists are used inside function calls or to define growth rates.

### 📘Why lists?

Lists are useful when you want to feed a specific series of numbers to a model. A good example is the number of sales prospects entering a funnel for an e-commerce business with strong seasonality, or the volume of customers arriving at a restaurant each day of the week. Any time you want to send specific values out of an event, you should reach for a list.

# Growth Rates

When building a model, you often need values to change dynamically over time based on some growth rate.

We'll cover what a `Source` is on the next page, but for now, observe the `@ 8%` in the following function:

`=Source(100 @ 8%)`

This means we want the number `100` to compound `@` an `8%` rate each time the event is triggered. So this event will first return 100, then 108, then 116.64, 125.97, etc. until the simulation terminates.

Things that compound grow extremely fast, and to extremely large quantities. In reality, in most systems, growth tends to slow down over time. To emulate this, SEL supports growth rate lists:

`=Source(100 @ [8, 7, 6, 5]%)`

This function will cause the event to return 100, 108, 115.56, 122.49, 128.61. Can you guess the next value? Applying our lesson about Lists, the event will re-use the final element of `5%` and grow 128.61 to 135.04.

With this, we can slow -- or accelerate -- the growth of an event's return values.

And yes, we can also use negative numbers to shrink a value over time!

`=Pool(100 @ -5%)`

is a handy way to represent a shrinking pool of customers, money, or revenue!

Growth rates can be compounding (%'s) or linear (constant #'s):

`=Source(100 @ 10)`

Will return `[100, 110, 120, 130 ...]`

And why not mix and match?

`=Source(100 @ [10, 20, 30, 10%])`

Will return `[100, 110, 130, 160, 176.6 ...]`!

### 👍See an example of Growth Rates in practice:

Profit & Loss (P&L) Forecast

# Change Rates

What if we want our growth rates to also change over time? Enter Change Rates!

Change rates come after growth rates using the same `@` operator.

These are all valid function calls to Source using a change rate expression to modify a growth rate over time:

`=Source(100 @ 10% @ -10%) # -> [100, 110, 119.9, 129.61, ...]`
`=Source(100 @ 10% @ [5,10]%) # -> [100, 105, 115.5, 127.05, ...]`
`=Source(100 @ 10 @ 10) # -> [100, 110, 130, 160, ...]`
`=Source(100 @ 10 @ [1,2,3]) # -> [100, 110, 121, 133, ...]`

Change rates are useful to accelerate or decelerate your growth rate over time.

## Minimum and Maximum Growth Rates

Sometimes you want to accelerate or decelerate your growth rate to a minimum or maximum rate, then hold that rate constant. You can achieve this effect in SEL using the spread operator `...`:

`=Source(100 @ 100...5% @ -10%)`

This will start at 100, then decrease the growth rate from 100% to 5% by -10% and then hold at 5%.

This also works for linear (non-compounding) rates, like so:

`=Source(100 @ 100...30 @ -10)`

This will start at 100, then add 100, then 90, then 80, then ... 40, then 30. Then 30 repeating.

# Unit Rates

What if we want to express a value in terms that do not match the recurring pattern of the event itself? We can use unit rates:

`=Source(100k<\$/year>)`

The `/year` expression is more than a label. It allows you to express constants in units (such as annual salary) that are familiar to you and your reader, while setting the event to repeat on a different frequency. If the above event were set to repeat monthly, it would automatically convert 100,000 per year to its monthly equivalent (8,333), and flow that through the source.

List of acceptable time periods to follow a forward slash, spelled exactly like so: `year`, `month`, `week`, `day`, `semimonth`, `biweek`, `quarter`, and yes, `fortnight`.

### 🚧Unit Rates are not Tags

Though similar in syntax (using `<` and `>`), unit rates are not the same as tags. A unit rate will always include a `/` forward slash, and the parser will not treat a unit rate as a tag.

## Units for Growth Rates

Unit Rates are also useful for automatically converting the growth rates of an expression, for example, you could represent a credit card with a \$4,000 balance and 19% APR (annual percentage rate) like so:

`=Pool(4k @ 19<%/year>)`

If you set this pool to recur monthly, the 19% will be automatically converted to `1.583...%` (19 divided by 12).

This is also useful for yields. For example, an investment account with a \$10,000 initial balance and 10% APY (annual percentage yield) can be expressed:

`=Pool(10k @ 10<%y/year>)`

### ❗️Rates Require Recurrence

If you use a unit rate in an event that isn't recurring, the simulator will return an error. In order for the value to grow, the event needs to recur.

Notice the `y` immediately following the `%`. This tells Summit to treat the 10% as a yield rate. With a yield rate, you are indicating that this \$10k should grow by \$1k over the course of a year. If you simply divide 10 by 12 (as in the above example), you will get a slightly higher value than \$11k after 1 year. By using `%y`, the interpreter will automatically convert the 10% to a rate that, when compounded at the rate defined by the event's recurring pattern, will hit exactly \$11k after 12 months (`year`).

The `/year` portion of the yield definition can be set to any of the acceptable values for a Unit Rate.

### 📘APY vs. APR

As a simple rule of thumb, when modeling assets with a growth rate, you will likely want to use `%y`, but when modeling a debt, you'd likely be using the standard `%`.

What’s Next

Now that we've learned about expressions, let's look at ways to modify the default behavior of events, using event classes.