Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mention connections to functional programming in README and docs #2726

Merged
merged 3 commits into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions docs/basics/functional-programming-and-jotai.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: Functional programming and Jotai
nav: 6.04
---

### Unexpected similarities

If you look at getter functions long enough, you may see a striking resemblence
to a certain JavaScript language feature.

```tsx
const nameAtom = atom('Visitor')
const countAtom = atom(1)
const greetingAtom = atom((get) => {
const name = get(nameAtom)
const count = get(countAtom)
return (
<div>
Hello, {nameAtom}! You have visited this page {countAtom} times.
</div>
)
})
```

Now, compare that code with `async`–`await`:

```tsx
const namePromise = Promise.resolve('Visitor')
const countPromise = Promise.resolve(1)
const greetingPromise = (async function () {
const name = await namePromise
const count = await countPromise
return (
<div>
Hello, {nameAtom}! You have visited this page {countAtom} times.
</div>
)
})()
```

This similarity is no coincidence. Both atoms and promises are **Monads**, a
concept from **functional programming**. The syntax used in both examples is
called **do-notation**, a syntax sugar for the plainer monad interface.

---

The monad interface is responsible for the fluidity of the atom and promise
interfaces. The monad interface allowed us to define `greetingAtom` in terms of
`nameAtom` and `countAtom`, and allowed us to define `greetingPromise` in terms
of `namePromise` and `countPromise`.

For the mathematically inclined, a structure (like `Atom` or `Promise`) is a
monad if you can implement the following functions for it. A fun exercise is
trying to implement `of`, `map` and `join` for Atoms, Promises and Arrays.

```typescript
type SomeMonad<T> = /* ... */
declare function of<T>(plainValue: T): SomeMonad<T>
declare function map<T, V>(
anInstance: SomeMonad<T>,
transformContents: (contents: T) => V
): SomeMonad<V>
declare function join<T>(nestedInstances: SomeMonad<SomeMonad<T>>): SomeMonad<T>
```

Monads have been an interest to mathematicians for 60 years, and to programmers
for 40. There are countless resources out there on patterns for monads, such
as `Traversable`–`sequence`. Take a look at them!
7 changes: 7 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,13 @@ function Controls() {
...
```

### Note about functional programming

Jotai's fluid interface is no accident — atoms are monads, just like promises!
Monads are an [established](<https://en.wikipedia.org/wiki/Monad_(functional_programming)>)
pattern for modular, pure, robust and understandable code which is [optimized for change](https://overreacted.io/optimized-for-change/).
Read more about [Jotai and monads.](https://jotai.org/docs/basics/functional-programming-and-jotai)

## Links

- [website](https://jotai.org)
Expand Down