From c41be87c4565903979f72be909513b4d88e49ee0 Mon Sep 17 00:00:00 2001 From: Marco Ieni <11428655+MarcoIeni@users.noreply.github.com> Date: Wed, 20 Jan 2021 16:16:12 +0100 Subject: [PATCH] Create separated page in functional programming (#184) --- SUMMARY.md | 1 + functional/index.md | 72 +++++------------------------------------ functional/paradigms.md | 66 +++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 64 deletions(-) create mode 100644 functional/paradigms.md diff --git a/SUMMARY.md b/SUMMARY.md index e267753..9128dba 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -40,6 +40,7 @@ - [Deref Polymorphism](./anti_patterns/deref.md) - [Functional Programming](./functional/index.md) + - [Programming paradigms](./functional/paradigms.md) - [Additional Resources](./additional_resources/index.md) - [Design principles](./additional_resources/design-principles.md) diff --git a/functional/index.md b/functional/index.md index eeab41b..b29e9ca 100644 --- a/functional/index.md +++ b/functional/index.md @@ -1,66 +1,10 @@ # Functional Usage of Rust -Rust is an imperative language, but it follows many functional programming paradigms. -One of the biggest hurdles to understanding functional programs when coming from an imperative background is the shift in thinking. -Imperative programs describe __how__ to do something, whereas declarative programs describe __what__ to do. -Let's sum the numbers from 1 to 10 to show this. - -## Imperative - -```rust -let mut sum = 0; -for i in 1..11 { - sum += i; -} -println!("{}", sum); -``` - -With imperative programs, we have to play compiler to see what is happening. -Here, we start with a `sum` of `0`. -Next, we iterate through the range from 1 to 10. -Each time through the loop, we add the corresponding value in the range. -Then we print it out. - -| `i` | `sum` | -|:---:|:-----:| -| 1 | 1 | -| 2 | 3 | -| 3 | 6 | -| 4 | 10 | -| 5 | 15 | -| 6 | 21 | -| 7 | 28 | -| 8 | 36 | -| 9 | 45 | -| 10 | 55 | - -This is how most of us start out programming. We learn that a program is a set of steps. - -## Declarative - -```rust -println!("{}", (1..11).fold(0, |a, b| a + b)); -``` - -Whoa! This is really different! What's going on here? Remember that with declarative programs -we are describing __what__ to do, rather than __how__ to do it. -`fold` is a function that [composes](https://en.wikipedia.org/wiki/Function_composition) functions. The name is a convention from Haskell. - -Here, we are composing functions of addition (this closure: `|a, b| a + b)`) with a range from 1 to 10. -The `0` is the starting point, so `a` is `0` at first. -`b` is the first element of the range, `1`. `0 + 1 = 1` is the result. -So now we `fold` again, with `a = 1`, `b = 2` and so `1 + 2 = 3` is the next result. -This process continues until we get to the last element in the range, `10`. - -| `a` | `b` | result | -|:---:|:---:|:------:| -| 0 | 1 | 1 | -| 1 | 2 | 3 | -| 3 | 3 | 6 | -| 6 | 4 | 10 | -| 10 | 5 | 15 | -| 15 | 6 | 21 | -| 21 | 7 | 28 | -| 28 | 8 | 36 | -| 36 | 9 | 45 | -| 45 | 10 | 55 | +Rust is an imperative language, but it follows many +[functional programming](https://en.wikipedia.org/wiki/Functional_programming) paradigms. + +> In computer science, *functional programming* is a programming paradigm where +> programs are constructed by applying and composing functions. +> It is a declarative programming paradigm in which function definitions are +> trees of expressions that each return a value, rather than a sequence of +> imperative statements which change the state of the program. diff --git a/functional/paradigms.md b/functional/paradigms.md new file mode 100644 index 0000000..3107f75 --- /dev/null +++ b/functional/paradigms.md @@ -0,0 +1,66 @@ +# Programming paradigms + +One of the biggest hurdles to understanding functional programs when coming from an imperative background is the shift in thinking. +Imperative programs describe __how__ to do something, whereas declarative programs describe __what__ to do. +Let's sum the numbers from 1 to 10 to show this. + +## Imperative + +```rust +let mut sum = 0; +for i in 1..11 { + sum += i; +} +println!("{}", sum); +``` + +With imperative programs, we have to play compiler to see what is happening. +Here, we start with a `sum` of `0`. +Next, we iterate through the range from 1 to 10. +Each time through the loop, we add the corresponding value in the range. +Then we print it out. + +| `i` | `sum` | +|:---:|:-----:| +| 1 | 1 | +| 2 | 3 | +| 3 | 6 | +| 4 | 10 | +| 5 | 15 | +| 6 | 21 | +| 7 | 28 | +| 8 | 36 | +| 9 | 45 | +| 10 | 55 | + +This is how most of us start out programming. We learn that a program is a set of steps. + +## Declarative + +```rust +println!("{}", (1..11).fold(0, |a, b| a + b)); +``` + +Whoa! This is really different! What's going on here? +Remember that with declarative programs we are describing __what__ to do, rather than __how__ to do it. +`fold` is a function that [composes](https://en.wikipedia.org/wiki/Function_composition) functions. +The name is a convention from Haskell. + +Here, we are composing functions of addition (this closure: `|a, b| a + b`) with a range from 1 to 10. +The `0` is the starting point, so `a` is `0` at first. +`b` is the first element of the range, `1`. `0 + 1 = 1` is the result. +So now we `fold` again, with `a = 1`, `b = 2` and so `1 + 2 = 3` is the next result. +This process continues until we get to the last element in the range, `10`. + +| `a` | `b` | result | +|:---:|:---:|:------:| +| 0 | 1 | 1 | +| 1 | 2 | 3 | +| 3 | 3 | 6 | +| 6 | 4 | 10 | +| 10 | 5 | 15 | +| 15 | 6 | 21 | +| 21 | 7 | 28 | +| 28 | 8 | 36 | +| 36 | 9 | 45 | +| 45 | 10 | 55 |