forked from enricopolanski/functional-programming
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
66 changed files
with
27,241 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Dependencies | ||
/node_modules | ||
|
||
# Production | ||
/build | ||
|
||
# Generated files | ||
.docusaurus | ||
.cache-loader | ||
|
||
# Misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Website | ||
|
||
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. | ||
|
||
### Installation | ||
|
||
``` | ||
$ yarn | ||
``` | ||
|
||
### Local Development | ||
|
||
``` | ||
$ yarn start | ||
``` | ||
|
||
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. | ||
|
||
### Build | ||
|
||
``` | ||
$ yarn build | ||
``` | ||
|
||
This command generates static content into the `build` directory and can be served using any static contents hosting service. | ||
|
||
### Deployment | ||
|
||
Using SSH: | ||
|
||
``` | ||
$ USE_SSH=true yarn deploy | ||
``` | ||
|
||
Not using SSH: | ||
|
||
``` | ||
$ GIT_USER=<Your GitHub username> yarn deploy | ||
``` | ||
|
||
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = { | ||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
--- | ||
slug: / | ||
--- | ||
|
||
# What is functional programming | ||
|
||
> Functional Programming is programming with pure functions. Mathematical functions. | ||
A quick search on the internet may lead you to the following definition: | ||
|
||
> A (pure) function is a procedure that given the same input always return the same output without any observable side-effect. | ||
The term "side effect" does not yet have any specific meaning (we'll see in the future how to give a formal definition), what matters is to have some sort of intuition, think about opening a file or writing into a database. | ||
|
||
For the time being we can limit ourselves to say that a side effect is _anything_ a function does besides returning a value. | ||
|
||
What is the structure of a program that uses exclusively pure functions? | ||
|
||
A functional program tends to be written like a **pipeline**: | ||
|
||
```ts | ||
const program = pipe( | ||
input, | ||
f1, // pure function | ||
f2, // pure function | ||
f3, // pure function | ||
... | ||
) | ||
``` | ||
|
||
What happens here is that `input` is passed to the first function `f1`, which returns a value that is passed to the second function `f2`, which returns a value that is passed as an argument to the third function `f3`, and so on. | ||
|
||
**Demo** | ||
|
||
[`00_pipe_and_flow.ts`](https://github.com/wwmmzz/functional-programming/blob/master/src/00_pipe_and_flow.ts) | ||
|
||
We'll see how functional programming provides us with tools to structure our code in that style. | ||
|
||
Other than understanding what functional programming _is_, it is also essential to understand what is it's goal. | ||
|
||
Functional programming's goal is to **tame a system's complexity** through the use of formal _models_, and to give careful attention to **code's properties** and refactoring ease. | ||
|
||
> Functional programming will help teach people the mathematics behind program construction: | ||
> | ||
> - how to write composable code | ||
> - how to reason about side effects | ||
> - how to write consistent, general, less ad-hoc APIs | ||
What does it mean to give careful attention to code's properties? Let's see with an example: | ||
|
||
**Example** | ||
|
||
Why can we say that the `Array`'s `map` method is "more functional" than a `for` loop? | ||
|
||
```ts | ||
// input | ||
const xs: Array<number> = [1, 2, 3] | ||
|
||
// transformation | ||
const double = (n: number): number => n * 2 | ||
|
||
// result: I want an array where each `xs`' element is doubled | ||
const ys: Array<number> = [] | ||
for (let i = 0; i <= xs.length; i++) { | ||
ys.push(double(xs[i])) | ||
} | ||
``` | ||
|
||
A `for` loop offers a lot of flexibility, I can modify: | ||
|
||
- the starting index, `let i = 0` | ||
- the looping condition, `i < xs.length` | ||
- the step change, `i++`. | ||
|
||
This also implies that I may introduce **errors** and that I have no guarantees about the returned value. | ||
|
||
**Quiz**. Is the `for loop` correct? | ||
|
||
> See the [answer here](quiz-answers/for-loop.md) | ||
Let's rewrite the same exercise using `map`. | ||
|
||
```ts | ||
// input | ||
const xs: Array<number> = [1, 2, 3] | ||
|
||
// transformation | ||
const double = (n: number): number => n * 2 | ||
|
||
// result: I want an array where each `xs`' element is doubled | ||
const ys: Array<number> = xs.map(double) | ||
``` | ||
|
||
We can note how `map` lacks the same flexibility of a `for loop`, but it offers us some guarantees: | ||
|
||
- all the elements of the input array will be processed | ||
- the resulting array will always have the same number of elements as the starting one | ||
|
||
In functional programming, where there's an emphasis on code properties rather than implementation details, the `map` operation is interesting **due to its limitations** | ||
|
||
Think about how easier it is to review a PR that involves `map` rather than a `for` loop. |
Oops, something went wrong.