diff --git a/docs/basics/functional-programming-and-jotai.mdx b/docs/basics/functional-programming-and-jotai.mdx new file mode 100644 index 0000000000..f1e08485ef --- /dev/null +++ b/docs/basics/functional-programming-and-jotai.mdx @@ -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 ( +
+ Hello, {nameAtom}! You have visited this page {countAtom} times. +
+ ) +}) +``` + +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 ( +
+ Hello, {nameAtom}! You have visited this page {countAtom} times. +
+ ) +})() +``` + +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 = /* ... */ +declare function of(plainValue: T): SomeMonad +declare function map( + anInstance: SomeMonad, + transformContents: (contents: T) => V +): SomeMonad +declare function join(nestedInstances: SomeMonad>): SomeMonad +``` + +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! diff --git a/readme.md b/readme.md index 0f5d339add..3c4408968b 100644 --- a/readme.md +++ b/readme.md @@ -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]() +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)