# What is a Ferp Action?

## Actions

Actions are the only way to initiate new state changes and side-effects in Ferp. State changes must be complete and immutable, and side effects must always be declared, even if there are no side-effects. Actions are always pure functions that return `[state, sideEffect]`, and pure meaning it does not use any data not immediately accessible to the action. On the contrary, an invalid action would use things like `Math.random()` or `Date.now()`, which are external to the action function.

## Types of Actions

### Naked Action

Plain, or naked, actions are actions that need no parameters. For instance, a naked action could be something that only updates a single state property by incrementing it by 1. Let's see what that looks like:

```javascript
import { effects } from 'ferp';

const IncrementCounterByOne = (state) => [
  { ...state, counter: state.counter + 1 },
  effects.none(),
];
```

Depending on the shape of your state, you may find naked actions to be very fitting.

There are two ways to call an action, and here they are:

```javascript
import { app, effects } from 'ferp';

const IncrementCounterByOne = (state) => [
  { ...state, counter: state.counter + 1 },
  effects.none(),
];

const dispatch = app({
  init: [
    { counter: 0 },
    effects.act(IncrementCounterByOne), // run an action via effect
  ],
});

dispatch(IncrementCounterByOne); // run an action via dispatch
```

### Action Builder

Action builders are actions that can take parameters. This may mean a value can be passed from user input, or from some other external side-effect. Using the previous counter example, here's what it would look like if it took external input for the increment amount:

```javascript
import { effects } from 'ferp';

const IncrementCounterByN = (n) => (state) => [
  { ...state, counter: state.counter + n },
  effects.none(),
];
```

Similar to naked actions, there are two ways to run this action in your application:

```javascript
import { app, effects } from 'ferp';

const IncrementCounterByN = (n) => (state) => [
  { ...state, counter: state.counter + n },
  effects.none(),
];

const dispatch = app({
  init: [
    { counter: 0 },
    effects.act(IncrementCounterByN(10)), // run a builder action via effect
  ],
});

dispatch(IncrementCounterByN(999)); // run a builder action via dispatch
```

If you're not sure how the builder works, this is just a function that returns a function. Here's probably a more familiar version to read:

```javascript
import { effects } from 'ferp';

function IncrementCounterByNBuilder(n) {
  return function IncrementCounterByNAction(state) {
    return [
      { ...state, counter: state.counter + n },
      effects.none(),
    ];
  };
};
```

This is called a closure, and it's used in Javascript to encapsulate a scope. For instance, the variable `n` is available in the inner function (`IncrementCounterByNAction`), but `n` is not available outside of this closure (`IncrementCounterByNBuilder`).

To make this easier to understand, once we have this builder that returns an action, internally, Ferp does something like this:

```javascript
// You call...
dispatch(IncrementCounterByNBuilder, 999);

// Ferp does...
const yourAction = IncrementByNBuilder(999);
dispatch(yourAction);
```
