<commit_before># Basic

Carry is actually a [very small](https://github.com/metametadata/carry/blob/master/src/carry/core.cljc)
Clojure/ClojureScript state management library which provides a skeleton for the whole application.
 
The library is distributed via [Clojars](http://clojars.org/carry) and has no dependencies.

All the additional features (debugging, UI binding, etc.) are not part of the core project
and can be provided by third-party packages. [Some of them](/index.html#packages) are already implemented
and hosted in Carry repo [contrib folder](https://github.com/metametadata/carry/tree/master/contrib).
Most of these packages are implemented using [Carry middleware pattern](#middleware).

The private/internal API uses `-` prefix and should not be used (e.g. `-this-is-some-private-thing`).

## App

In a Carry application all the code you write is encapsulated behind a single **app** instance. 
An app is a map with keys:

* `:model` - an in-memory representation of an app state
* `:dispatch-signal` - a function for interaction with an app

One can consider an app to be a black box which exposes its current state and modifies it on getting signals from an external world.
It can also affect an external world as a response to a signal, i.e. perform "side effects".

## Model

Model represents an entire state of an app. 
 
One can access app's model via `:model` key to obtain an object that can be dereferenced and watched.
An exception will be thrown on mutating such read-only reference:

```clj
(def my-model (:model my-app))

; Dereference to get model value.
@my-model
;=> {...}

; Start reacting to model changes.
(add-watch my-model :my-watch
           (fn [_key _ref old-state new-state]
             (when (not= old-state new-state)
               (println "model value has changed!"))))
               
((:dispatch-signal my-app) some-model-changing-signal)
;=> model value has changed!

; Stop watching.
(remove-watch my-model :my-watch)
               
; It's impossible to directly mutate a model.
(reset! my-model {:foo :bar})
;=> Error: ...
```

Carry requires a model value to be a map. This convention allows writing reusable packages that can store additional data into any Carry app.
As an example, [carry-history](https://github.com/metametadata/carry/tree/master/contrib/history) adds `:token` to a model.

## Signals

**Signal** is an object which represents a user's intention or, looking at it from a different angle, a system event. 
Signal can be synchronously sent to an app by calling its `dispatch-signal` function:

```clj
((:dispatch-signal my-app) my-signal)
```

Carry accepts signals of any type. But usually signal is a just keyword with "on-" prefix or
a serializable vector with a keyword and an additional payload:

```clj
:on-clear-completed
[:on-update-todo id val]
[:carry-history.core/on-enter token]
```

`dispatch-signal` always returns `nil`.

## Creating an App

In order to create an instance of a Carry app a user has to pass a **spec** into `app` function:<commit_msg>docs: explain why on- prefix is recommended for signals<commit_after># Basic

Carry is actually a [very small](https://github.com/metametadata/carry/blob/master/src/carry/core.cljc)
Clojure/ClojureScript state management library which provides a skeleton for the whole application.
 
The library is distributed via [Clojars](http://clojars.org/carry) and has no dependencies.

All the additional features (debugging, UI binding, etc.) are not part of the core project
and can be provided by third-party packages. [Some of them](/index.html#packages) are already implemented
and hosted in Carry repo [contrib folder](https://github.com/metametadata/carry/tree/master/contrib).
Most of these packages are implemented using [Carry middleware pattern](#middleware).

The private/internal API uses `-` prefix and should not be used (e.g. `-this-is-some-private-thing`).

## App

In a Carry application all the code you write is encapsulated behind a single **app** instance. 
An app is a map with keys:

* `:model` - an in-memory representation of an app state
* `:dispatch-signal` - a function for interaction with an app

One can consider an app to be a black box which exposes its current state and modifies it on getting signals from an external world.
It can also affect an external world as a response to a signal, i.e. perform "side effects".

## Model

Model represents an entire state of an app. 
 
One can access app's model via `:model` key to obtain an object that can be dereferenced and watched.
An exception will be thrown on mutating such read-only reference:

```clj
(def my-model (:model my-app))

; Dereference to get model value.
@my-model
;=> {...}

; Start reacting to model changes.
(add-watch my-model :my-watch
           (fn [_key _ref old-state new-state]
             (when (not= old-state new-state)
               (println "model value has changed!"))))
               
((:dispatch-signal my-app) some-model-changing-signal)
;=> model value has changed!

; Stop watching.
(remove-watch my-model :my-watch)
               
; It's impossible to directly mutate a model.
(reset! my-model {:foo :bar})
;=> Error: ...
```

Carry requires a model value to be a map. This convention allows writing reusable packages that can store additional data into any Carry app.
As an example, [carry-history](https://github.com/metametadata/carry/tree/master/contrib/history) adds `:token` to a model.

## Signals

**Signal** is an object which represents a user's intention or, looking at it from a different angle, a system event. 
Signal can be synchronously sent to an app by calling its `dispatch-signal` function:

```clj
((:dispatch-signal my-app) my-signal)
```

`dispatch-signal` always returns `nil`.

Carry accepts signals of any type. But usually signal is a just keyword with "on-" prefix or
a serializable vector with a keyword and an additional payload:

```clj
:on-clear-completed
[:on-update-todo id val]
[:carry-history.core/on-enter token]
```

Using prefixes is recommended because it helps distinguish signal names from action names.

## Creating an App

In order to create an instance of a Carry app a user has to pass a **spec** into `app` function:
{'fraction_non_alphanumeric': 0.09720437017994858, 'fraction_numerical': 0.0, 'mean_word_length': 3.85190958690569, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '721498', 'n_tokens_mistral': 1808, 'n_tokens_neox': 1741, 'n_words': 810}