{"id":21669381,"url":"https://github.com/attack-monkey/flat-code-guide","last_synced_at":"2026-05-17T13:13:45.223Z","repository":{"id":91874008,"uuid":"197256061","full_name":"attack-monkey/flat-code-guide","owner":"attack-monkey","description":"A guide to writing flatter, leaner javascript \u0026 typescript","archived":false,"fork":false,"pushed_at":"2020-10-01T19:36:02.000Z","size":124,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-01-25T08:44:04.306Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/attack-monkey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-16T19:33:47.000Z","updated_at":"2020-10-01T19:36:05.000Z","dependencies_parsed_at":null,"dependency_job_id":"afeb4825-ea14-4461-9b45-e41483b88eb1","html_url":"https://github.com/attack-monkey/flat-code-guide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/attack-monkey%2Fflat-code-guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/attack-monkey%2Fflat-code-guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/attack-monkey%2Fflat-code-guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/attack-monkey%2Fflat-code-guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/attack-monkey","download_url":"https://codeload.github.com/attack-monkey/flat-code-guide/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244570269,"owners_count":20474021,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-25T12:21:34.406Z","updated_at":"2026-05-17T13:13:45.217Z","avatar_url":"https://github.com/attack-monkey.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# CAUTION: https://github.com/attack-monkey/Lean-Functional-Typescript replaces this guide.\n\n\u003e That's not to say that there are not some useful concepts covered in FLAT.\n\n```\n ___________                                      \n|            |              .'.       `````|````` \n|______      |            .''```.          |      \n|            |          .'       `.        |      \n|            |_______ .'           `.      |      \n                                                  \n```\n\nWelcome to flat.  \nFlat emphasizes the simplification of logic in code by:\n\n- Reducing mutations\n- Reducing nested logic\n- Reducing the number of returns from functions\n\nSimple Flat is really a set of principles, and doesn't require any additional libraries.\nReading this Readme and the chapter on Control Flow, will help you write much cleaner code.\n\nAdvanced Flat also:\n\n- Uses Typescript which adds type-safety into your code!\n- :hot_pepper: \u0026nbsp; Uses **The Prelude** and a minimal set of other utility libraries to...\n- Organise code into functions and pipes instead of object oriented hierarchies\n\n\u003e Anytime you see a mention to **The Prelude** you'll see a :hot_pepper: \u0026nbsp; at the start of the line. If there is a mention to another library, you'll see a 🧩.\n\nFlat 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.\n\nWhile Flat takes on fp principles, it doesn't dive anywhere near as deep. \nFlat is primarily concerned with making flat untangled, well organised and safe code.\n\n### Reducing mutations\n\nAlmost everything in your code should be immutable...\n\n```javascript\n\n// basic immutable addition\nconst a = 1\nconst b = a + 1\n\n// adding keys to objects\nconst c = { cat: 'charlie' }\nconst d = { ...c, dog: 'xander' }\n\n// adding array items\nconst e = [1,2,3]\nconst f = [ ...e, 4,5,6] // [1,2,3,4,5,6]\nconst g = [ ...e, ...f] // [1,2,3,1,2,3,4,5,6]\netc.\n\n```\n\nDon't use `var`.  \nRarely use `let`\n\nMutating variables can lead to unwanted side effects and introduce hard to trace bugs.  \nInstead use immutable operations like the ones above, that generate a new state rather than mutating the existing state.\n\n\u003e 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.\n\n### Reducing Nested Logic\n\nNesting 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.\nEach time you nest some logic, you are tangling code that little bit more.  \nIt makes code difficult to trace, and notoriously difficult to refactor.  \nInstead keep logic flat or 'normalised'.\n\nBy moving to immutable patterns ...\n\n```javascript\n\nconst a = ...\nconst b = ...\nconst c = ... ? ... : ...\n\n```\n\n... and putting code blocks inside reusable functions, then you will find that nested logic no longer becomes a problem.\n\nWelcome to flat coding :)\n\n### Reducing the number of returns from functions\n\nIf you have functions that return values at different points in the function, then code becomes hard to trace.  \nEspecially when combined with variable mutations and nested logic.  \nInstead use a single `return` and shift your logic to the right of the `return` using ternaries, switch-ternaries, short circuits, etc.\n\n\u003e multiple `return` statements are a symptom of imperative logic blocks like `if` and `switch`, which are 'Unsafe keywords' in flat.\n\u003e If your project already has them, theres not much you can do (unless you refactor), but don't introduce more.\n\n### Organise code into functions and pipes, rather than class / prototype based oo hierarchies.\n\nAdvanced Flat organises code into functions, and functions into libraries (libs).\n\n\u003e :hot_pepper: \u0026nbsp;You'll find `pipe` in **The Prelude**\n\n```typescript\n\n// Note that this is using typescript syntax\n\n// functions\nconst upper = (str: string) =\u003e str.toUpperCase()\nconst lower = (str: string) =\u003e str.toLowerCase()\n\n// String_ lib\nconst String_ = {\n  upper,\n  lower\n}\n\n```\n\nAn oo way to think about the above is that libs are classes with static methods. \n\nPrograms are built by using `pipe` to pass a value through a series of functions.\n\n```javascript\n\npipe('cat', String_.upper, String_.lower)\n\n```\n\nor\n\n```javascript\n\nimport { lower, upper } from '...'\n\npipe('cat', upper, lower)\n\n```\n\nWhich is no different than...\n\n```javascript\n\nString_.lower(\n  String_.upper(\n    'cat'\n  )\n)\n\n```\n\n... but visualises things as a pipeline rather a nested set of functions.\n\nPipes can be composed...\n\n```javascript\n\nconst myPipe = compose(String_.upper, String_.lower)\n\n```\n\nand then have values piped through them.\n\n```javascript\n\nmyPipe('cat')\n\n// or\n\npipe('cat', myPipe, anotherPipe)\n\n```\n\nA 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.\n \n## Unsafe keywords\n\n:warning: The following keywords are considered unsafe because they work against the intention of flat... use with caution!\n\n- `if` - encourages mutation and multiple returns\n- `switch` - encourages mutation and multiple returns\n- `var` - Is a higher scoped varient of `let` which is no longer needed.\n\n\u003e If your project already has unsafe keywords - well unless you refactor, theres not much you can do, but think first before adding more.\n\n## Loops vs Recursion\n\nLoop 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.\n\n## Words that probably indicate that you are thinking in an oo way rather than flat / functional ...\n\n- `class`\n- `new`\n- **`this`**\n\nIn 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.\n\n## [Next: Control-Flow](https://github.com/attack-monkey/flat-code-guide/blob/master/Control-Flow.md)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fattack-monkey%2Fflat-code-guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fattack-monkey%2Fflat-code-guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fattack-monkey%2Fflat-code-guide/lists"}