Last active
July 23, 2025 06:24
-
-
Save sanandnarayan/cb77dc2d9e119f8cda9e0d7a881b656b to your computer and use it in GitHub Desktop.
Complex vs Simple , TS example , Rich Hickey
This file contains hidden or 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
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Complexity vs. Simplicity Toolkit</title> | |
| <style> | |
| body{font-family:Arial,Helvetica,sans-serif;margin:0;padding:0;line-height:1.4;background:#fafafa;color:#222;} | |
| h1{text-align:center;padding:24px 0;margin:0;background:#1e1e1e;color:#fff;} | |
| section{display:flex;flex-wrap:wrap;border-bottom:1px solid #ddd;padding:24px;} | |
| .side{flex:1 1 50%;box-sizing:border-box;padding:0 16px;} | |
| .complex{background:#fff8f6;} | |
| .simple{background:#f6fff8;} | |
| h3{margin:0 0 8px 0;font-size:1.2rem;} | |
| p{margin:4px 0 12px 0;} | |
| pre{background:#f6f8fa;border:1px solid #e1e4e8;padding:12px;overflow:auto;border-radius:4px;font-size:0.9rem;} | |
| code{font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;} | |
| </style> | |
| </head> | |
| <body> | |
| <h1>Complexity ⇄ Simplicity Toolkit</h1> | |
| <!-- 1 --> | |
| <section> | |
| <div class="side complex"> | |
| <h3>State / Objects</h3> | |
| <p><strong>Complects:</strong> value, identity, time</p> | |
| <pre><code class="language-ts">class Counter { | |
| private n = 0; | |
| inc() { this.n++; } | |
| value() { return this.n; } | |
| } | |
| const c = new Counter(); | |
| c.inc();</code></pre> | |
| </div> | |
| <div class="side simple"> | |
| <h3>Values</h3> | |
| <p><strong>Get it via:</strong> final, persistent collections</p> | |
| <pre><code class="language-ts">const bump = (n: number) => n + 1; | |
| const n2 = bump(0);</code></pre> | |
| </div> | |
| </section> | |
| <!-- 2 --> | |
| <section> | |
| <div class="side complex"> | |
| <h3>Methods</h3> | |
| <p><strong>Complects:</strong> function + state + namespace</p> | |
| <pre><code class="language-ts">class User { | |
| constructor(public age: number) {} | |
| incrementAge() { this.age++; } | |
| } | |
| const u = new User(30); | |
| u.incrementAge();</code></pre> | |
| </div> | |
| <div class="side simple"> | |
| <h3>Functions / Namespaces</h3> | |
| <p><strong>Get it via:</strong> stateless methods</p> | |
| <pre><code class="language-ts">interface User { age: number } | |
| export const incrementAge = (u: User) => ({ ...u, age: u.age + 1 });</code></pre> | |
| </div> | |
| </section> | |
| <!-- 3 --> | |
| <section> | |
| <div class="side complex"> | |
| <h3>Variables (<code>var</code>)</h3> | |
| <p><strong>Complects:</strong> value + time</p> | |
| <pre><code class="language-ts">let clicks = 0; | |
| document.body.onclick = () => ++clicks;</code></pre> | |
| </div> | |
| <div class="side simple"> | |
| <h3>Managed refs</h3> | |
| <p><strong>Get it via:</strong> RxJS / Immer refs</p> | |
| <pre><code class="language-ts">const clicks = new BehaviorSubject(0); | |
| document.body.onclick = () => clicks.next(clicks.value + 1);</code></pre> | |
| </div> | |
| </section> | |
| <!-- 4 --> | |
| <section> | |
| <div class="side complex"> | |
| <h3>Inheritance / Switch</h3> | |
| <p><strong>Complects:</strong> multiple who/what pairs</p> | |
| <pre><code class="language-ts">abstract class Animal { abstract speak(): string; } | |
| class Dog extends Animal { speak() { return "woof"; } } | |
| function talk(a: Animal) { a.speak(); } | |
| talk(new Dog());</code></pre> | |
| </div> | |
| <div class="side simple"> | |
| <h3>Polymorphism a la carte</h3> | |
| <p><strong>Get it via:</strong> interfaces / protocols</p> | |
| <pre><code class="language-ts">interface Speak { speak(): string } | |
| const dog: Speak = { speak: () => "woof" }; | |
| const talk = (s: Speak) => s.speak();</code></pre> | |
| </div> | |
| </section> | |
| <!-- 5 --> | |
| <section> | |
| <div class="side complex"> | |
| <h3>Syntax‑driven branching</h3> | |
| <p><strong>Complects:</strong> meaning + order</p> | |
| <pre><code class="language-ts">function calc(op: "add" | "sub", a: number, b: number) { | |
| if (op === "add") return a + b; | |
| if (op === "sub") return a - b; | |
| } | |
| calc("add", 3, 4);</code></pre> | |
| </div> | |
| <div class="side simple"> | |
| <h3>Data‑driven dispatch</h3> | |
| <p><strong>Get it via:</strong> maps / arrays / JSON</p> | |
| <pre><code class="language-ts">const ops = { | |
| add: (a: number, b: number) => a + b, | |
| sub: (a: number, b: number) => a - b, | |
| }; | |
| const res = ops["add"](3, 4);</code></pre> | |
| </div> | |
| </section> | |
| <!-- 6 --> | |
| <section> | |
| <div class="side complex"> | |
| <h3>Imperative loops</h3> | |
| <p><strong>Complects:</strong> what + how</p> | |
| <pre><code class="language-ts">let total = 0; | |
| for (let i = 0; i < nums.length; i++) { | |
| total += nums[i]; | |
| }</code></pre> | |
| </div> | |
| <div class="side simple"> | |
| <h3>Set functions</h3> | |
| <p><strong>Get it via:</strong> <code>map</code>, <code>reduce</code>, etc.</p> | |
| <pre><code class="language-ts">const total = nums.reduce((a, b) => a + b, 0);</code></pre> | |
| </div> | |
| </section> | |
| <!-- 7 --> | |
| <section> | |
| <div class="side complex"> | |
| <h3>Actors</h3> | |
| <p><strong>Complects:</strong> what + who</p> | |
| <pre><code class="language-ts">class MailActor { | |
| private inbox: Msg[] = []; | |
| send(msg: Msg) { | |
| this.inbox.push(msg); | |
| this.process(); | |
| } | |
| private process() { | |
| /* handle inbox */ | |
| } | |
| } | |
| const mailer = new MailActor(); | |
| mailer.send(msg);</code></pre> | |
| </div> | |
| <div class="side simple"> | |
| <h3>Queues</h3> | |
| <p><strong>Get it via:</strong> libraries</p> | |
| <pre><code class="language-ts">const queue: Msg[] = []; | |
| queue.push(msg); | |
| const m = queue.shift();</code></pre> | |
| </div> | |
| </section> | |
| <!-- 8 --> | |
| <section> | |
| <div class="side complex"> | |
| <h3>ORM</h3> | |
| <p><strong>Complects:</strong> objects + SQL + state</p> | |
| <pre><code class="language-ts">await userRepository.save(user); | |
| const row = await userRepository.findOne({ where: { id } });</code></pre> | |
| </div> | |
| <div class="side simple"> | |
| <h3>Declarative data manipulation</h3> | |
| <p><strong>Get it via:</strong> SQL / LINQ / Datalog</p> | |
| <pre><code class="language-ts">const rows = await db.query` | |
| SELECT id, name | |
| FROM users | |
| WHERE id = ${id} | |
| `;</code></pre> | |
| </div> | |
| </section> | |
| <!-- 9 --> | |
| <section> | |
| <div class="side complex"> | |
| <h3>Conditionals everywhere</h3> | |
| <p><strong>Complects:</strong> scattered business rules</p> | |
| <pre><code class="language-ts">let discount = 0; | |
| if (cust.vip && order.total > 1000) { | |
| discount = 0.1; | |
| }</code></pre> | |
| </div> | |
| <div class="side simple"> | |
| <h3>Rules</h3> | |
| <p><strong>Get it via:</strong> rule tables / engines</p> | |
| <pre><code class="language-ts">const rules = [ | |
| { if: (c: Cust, o: Ord) => c.vip && o.total > 1000, discount: 0.1 }, | |
| ]; | |
| const d = rules.find(r => r.if(cust, order))?.discount ?? 0;</code></pre> | |
| </div> | |
| </section> | |
| <!-- 10 --> | |
| <section> | |
| <div class="side complex"> | |
| <h3>Inconsistency</h3> | |
| <p><strong>Complects:</strong> partial updates, uncertainty</p> | |
| <pre><code class="language-ts">await db.update(...); | |
| await db.insert(...); // risk of partial failure</code></pre> | |
| </div> | |
| <div class="side simple"> | |
| <h3>Consistency</h3> | |
| <p><strong>Get it via:</strong> transactions, immutable values</p> | |
| <pre><code class="language-ts">await db.transaction(async tx => { | |
| await tx.update(...); | |
| await tx.insert(...); | |
| });</code></pre> | |
| </div> | |
| </section> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment