https://github.com/attack-monkey/flat-code-guide
A guide to writing flatter, leaner javascript & typescript
https://github.com/attack-monkey/flat-code-guide
Last synced: about 1 month ago
JSON representation
A guide to writing flatter, leaner javascript & typescript
- Host: GitHub
- URL: https://github.com/attack-monkey/flat-code-guide
- Owner: attack-monkey
- Created: 2019-07-16T19:33:47.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2020-10-01T19:36:02.000Z (over 5 years ago)
- Last Synced: 2025-01-25T08:44:04.306Z (over 1 year ago)
- Homepage:
- Size: 121 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# CAUTION: https://github.com/attack-monkey/Lean-Functional-Typescript replaces this guide.
> That's not to say that there are not some useful concepts covered in FLAT.
```
___________
| | .'. `````|`````
|______ | .''```. |
| | .' `. |
| |_______ .' `. |
```
Welcome to flat.
Flat emphasizes the simplification of logic in code by:
- Reducing mutations
- Reducing nested logic
- Reducing the number of returns from functions
Simple Flat is really a set of principles, and doesn't require any additional libraries.
Reading this Readme and the chapter on Control Flow, will help you write much cleaner code.
Advanced Flat also:
- Uses Typescript which adds type-safety into your code!
- :hot_pepper: Uses **The Prelude** and a minimal set of other utility libraries to...
- Organise code into functions and pipes instead of object oriented hierarchies
> Anytime you see a mention to **The Prelude** you'll see a :hot_pepper: at the start of the line. If there is a mention to another library, you'll see a 🧩.
Flat takes an fp (functional programming) over oo (object oriented) approach - so there is an emphasis on organising code into functions and pipes rather than oo based hierarchies.
While Flat takes on fp principles, it doesn't dive anywhere near as deep.
Flat is primarily concerned with making flat untangled, well organised and safe code.
### Reducing mutations
Almost everything in your code should be immutable...
```javascript
// basic immutable addition
const a = 1
const b = a + 1
// adding keys to objects
const c = { cat: 'charlie' }
const d = { ...c, dog: 'xander' }
// adding array items
const e = [1,2,3]
const f = [ ...e, 4,5,6] // [1,2,3,4,5,6]
const g = [ ...e, ...f] // [1,2,3,1,2,3,4,5,6]
etc.
```
Don't use `var`.
Rarely use `let`
Mutating variables can lead to unwanted side effects and introduce hard to trace bugs.
Instead use immutable operations like the ones above, that generate a new state rather than mutating the existing state.
> Caveat: If writing a high compute piece of code that requires lots of recursion or traversing structures to create new immutable structures - then looping and mutation may be worth the loss of purity. Flat explains ways of handling mutation safely for these cases.
### Reducing Nested Logic
Nesting logic is when you put a logic block inside of another logic block. For example an `if` inisde another `if` or a `switch` inside an `if` etc.
Each time you nest some logic, you are tangling code that little bit more.
It makes code difficult to trace, and notoriously difficult to refactor.
Instead keep logic flat or 'normalised'.
By moving to immutable patterns ...
```javascript
const a = ...
const b = ...
const c = ... ? ... : ...
```
... and putting code blocks inside reusable functions, then you will find that nested logic no longer becomes a problem.
Welcome to flat coding :)
### Reducing the number of returns from functions
If you have functions that return values at different points in the function, then code becomes hard to trace.
Especially when combined with variable mutations and nested logic.
Instead use a single `return` and shift your logic to the right of the `return` using ternaries, switch-ternaries, short circuits, etc.
> multiple `return` statements are a symptom of imperative logic blocks like `if` and `switch`, which are 'Unsafe keywords' in flat.
> If your project already has them, theres not much you can do (unless you refactor), but don't introduce more.
### Organise code into functions and pipes, rather than class / prototype based oo hierarchies.
Advanced Flat organises code into functions, and functions into libraries (libs).
> :hot_pepper: You'll find `pipe` in **The Prelude**
```typescript
// Note that this is using typescript syntax
// functions
const upper = (str: string) => str.toUpperCase()
const lower = (str: string) => str.toLowerCase()
// String_ lib
const String_ = {
upper,
lower
}
```
An oo way to think about the above is that libs are classes with static methods.
Programs are built by using `pipe` to pass a value through a series of functions.
```javascript
pipe('cat', String_.upper, String_.lower)
```
or
```javascript
import { lower, upper } from '...'
pipe('cat', upper, lower)
```
Which is no different than...
```javascript
String_.lower(
String_.upper(
'cat'
)
)
```
... but visualises things as a pipeline rather a nested set of functions.
Pipes can be composed...
```javascript
const myPipe = compose(String_.upper, String_.lower)
```
and then have values piped through them.
```javascript
myPipe('cat')
// or
pipe('cat', myPipe, anotherPipe)
```
A given function can be used by any value that conforms to function's call signature. For example `upper` and `lower` from the above example are usable by any strings. This is different to a method that only works on objects created from a given class.
## Unsafe keywords
:warning: The following keywords are considered unsafe because they work against the intention of flat... use with caution!
- `if` - encourages mutation and multiple returns
- `switch` - encourages mutation and multiple returns
- `var` - Is a higher scoped varient of `let` which is no longer needed.
> If your project already has unsafe keywords - well unless you refactor, theres not much you can do, but think first before adding more.
## Loops vs Recursion
Loop constructs like `for` and `while` tend to be faster than recursion and are preferred in high compute situations. However they come at the cost of purity since they mutate variables in order to run a loop. For most cases recursion provides a pure way of achieving the same result with a tiny performance hit.
## Words that probably indicate that you are thinking in an oo way rather than flat / functional ...
- `class`
- `new`
- **`this`**
In most Flat code you won't need classes, prototypes or any other oo constructs. You will however most likely still need to use the `new` keyword when using other libraries.
## [Next: Control-Flow](https://github.com/attack-monkey/flat-code-guide/blob/master/Control-Flow.md)