top | item 41148517

How to build quickly

697 points| fagnerbrack | 1 year ago |learnhowtolearn.org

144 comments

order
[+] jimbokun|1 year ago|reply
This is incredibly simple yet incredibly powerful, and something that everyone who becomes proficient at delivering things of value learns eventually, but is rarely taught so succinctly.

By the way, for the programming case, this is a big part of the reason functional programming is so powerful. Avoiding shared state allows you to write your outline of smaller and smaller pieces, then write each piece as a stateless function, then pipe your data through a graph of these functions.

With other programming paradigms, you can't just knock out all the little pieces without thinking about the other pieces because the state is all tangled up. Which slows you down.

It's surprising how very simple the individual components can be, even for very complex systems, when following this approach.

[+] jahewson|1 year ago|reply
I’m not so convinced that this is a property of functional programming as much as simply good programming. I’ve seen functional programs that pass around huge data structures that couple functionality. I’ve never seen the benefit of performing elaborate monadic dances to avoid state that would have been simpler to represent in a non-functional language.
[+] intelVISA|1 year ago|reply
Yes. Ideally a codebase is just a monorepo of pure functions and apps are simply the control flow that weaves them. Write reusable libraries not microservices (silos).

Sadly incentives are not aligned for this at scale - easier to buy cloud SaaS n+1 whose sales team insist "this $badware solves a Hard Problem" while your devs sit in ceremonies all day.

[+] viraptor|1 year ago|reply
To be fair to other styles, we generally learned already that shared state is bad. It's avoided in basically every language/service these days. It may be enforced more strictly with functional programming. But "With other programming paradigms, you can't just knock out all the little pieces without thinking about the other pieces" is taking it too far. For example, you want to add email sending to your app? The library for it is a little piece of software independent of the rest.
[+] brabel|1 year ago|reply
> With other programming paradigms, you can't just knock out all the little pieces without thinking about the other pieces because the state is all tangled up. Which slows you down.

I don't think so. I use the style of programming described in the post, and my code is mostly OOP, but almost entirely without mutable state. You may claim "but that's not OOP", but I would reply that FP is not about having no shared state either (which a lot of people were quick to tell me when I myself made the mistake of confusing immutability with FP, as almost all FP languages allow mutation without much cerimony), that's just something encouraged in FP, and it's something that can be easily encouraged in OOP as well.

[+] CyberDildonics|1 year ago|reply
With other programming paradigms, you can't just knock out all the little pieces without thinking about the other pieces because the state is all tangled up. Which slows you down.

Of course you can. I don't know why people think you can't write functions that don't change a global state in any programming language. Pretty much any experienced programmer does that whenever they can.

[+] allenu|1 year ago|reply
This is how I work on my projects as an indie dev. When I start working on something significant (a new feature, for instance), I'll create a markdown file that has a summary of what I'm trying to achieve and then a TODOs section which turns into this massive outline of all the tasks that I'll need to do to complete the work.

At first, the outline just has a few tasks that are fairly high-level, but as I dive into each one, I add more nested sub-tasks. The nesting keeps going until I end up with sort of leaf nodes that can be done without depending on other tasks. This gives me a nice visual of how complex some tasks are versus others.

I generally prototype and design the implementation at the same time, and having this outline gives me a place to "dump" tasks and other work I'll need to do later, and you do often encounter more work than you expect, so an outline makes it easier to find a good "parent" for the task. Having a big outline also lets me jump around from high-level design to low-level implementation easily as well, which you need if you're prototyping and trying to find the right shape for your solution.

It's great as a motivator too since I can see when I complete something big when I check off a parent task that has a lot of nested children.

I find a simple text file outline like this is so much more convenient than say an app or a web UI since I can just jump around the file and cut and paste outlined sections and indent or un-indent them to re-parent them. (Having to use something like JIRA to do this would be way too slow, especially when you're in a flow state.)

[+] darkteflon|1 year ago|reply
Same here. I wrote a little multitree-based TUI with vim-adjacent key bindings for exactly this purpose, since I find it generalises to all complex projects, software-related or not (and who can resist any excuse to write a TUI?), but a simple markdown file is just as good, really, and for software means you can keep it in the repo directly adjacent to other project docs.
[+] ukuina|1 year ago|reply
What do you do when an idea changes and now there are dozens of nested entries that need to be changed to match?
[+] leetrout|1 year ago|reply
Similar here - i use asana or linear for highlevel planning with a calendar and then as I write code I drop in TODOs and FIXMEs and such then just grep them out or use a VS Code extension called "TODO Tree" to track them.
[+] iman453|1 year ago|reply
Sounds like you’re not looking for an app since a text file works well, but I’ve been using Godspeed and it’s been amazing for this kinda workflow.
[+] kpw94|1 year ago|reply
The author provides an example of the bad "Loading bar writing" but unfortunately not a good example of what they call "Outline speedrunning writing"

pg, who's good at writing essays, does provide a good example of the latter, with https://byronm.com/13sentences.html.

This is the writing process that lead to https://paulgraham.com/13sentences.html. (the https://code.stypi.com/hacks/13sentences?doomed=true URL on pg's blog is a now a dead link. Previous discussion: https://news.ycombinator.com/item?id=6993060).

[+] gchamonlive|1 year ago|reply
What I do for my blog is I write everything at once. Then I figure out where to put images, then I publish it!

It makes me go back and read it carefully since I have already published it, and then I polish, rewrite sections and add stuff that I missed.

[+] jimbokun|1 year ago|reply
The other provides a very good example in one of the video illustrations, with the left hand side showing "loading bar" writing and right hand side simultaneously showing "outline speed running" writing.
[+] teo_zero|1 year ago|reply
This is a good way to maximize speed. I'm not convinced it's also a good way to master quality. Rushing ("speedrunning") to a first working version may force you to choose sub-optimal paradigms (algorithms, data types, etc.) that you won't have the time or the will to correct later.

I'd even postulate that's why we have so many crap applications today that are first on the market but slow, inefficient and user unfriendly.

If premature optimization is the root of all evils, totally disregarding it leads to painful refactoring.

[+] lee|1 year ago|reply
I think it's the opposite. I think quality often comes from evolution and iteration.

There've been so many projects where I get stuck because I want to maximize quality, so I get writer's block. The worse, is that sometimes you'll try to perfect something on your project that ultimately isn't of great value.

Building something quickly, and then iterating to perfect it seems to work for many people.

[+] znkr|1 year ago|reply
> I'd even postulate that's why we have so many crap applications today that are first on the market but slow, inefficient and user unfriendly.

That’s certainly one way to get a crappy application. Another way is to find optimal paradigms only to discover that the problem that needs to be solved has changed and now the optimal paradigms are technical debt that needs to be worked around.

[+] kmoser|1 year ago|reply
It can definitely lead to under-optimized code, but on the flip side, prematurely optimizing can waste time and lead to overly complex code that is difficult to maintain. The key is to know how much to optimize and when.

The point of the article isn't to show you how to produce a shoddy first version as soon as possible, but rather how to avoid things like analysis paralysis and prematurely focusing on style over substance. This applies not just to code but to pretty much anything you create.

By completing a skeleton as soon as possible, you get a better idea of the different components you'll need and how they will interact, before you flesh any of them out. I think there is real value in this approach.

[+] gamerDude|1 year ago|reply
Yes, but at the beginning you can't be totally sure that what you are building is right thing to build or the money/resources to be slow.
[+] MaxBarraclough|1 year ago|reply
Agree. In the context of software development, you might choose different tools (programming language especially) if your goal is rapid application development rather than general high quality and long-term maintainability. You can't easily go back and change those decisions.

This is one of the perennial software development questions: to what extent can you improve an existing solution with a flawed or now-inappropriate architecture or implementation? This topic turned up a couple of months ago. [0]

[0] https://news.ycombinator.com/item?id=40623263

[+] strken|1 year ago|reply
Much of the reason sucky applications suck is because the people who work on them can't change them quickly enough. If you can open up your IDE, grab a flame graph, and chuck out your shitty brute-force algorithm in favour of a dynamic programming one that you thought of in the shower, then one Friday morning you're likely to do just that.
[+] phforms|1 year ago|reply
I suspect that the “crap applications” issue arises not necessarily due to the method being wrong, but more likely due to people disregarding step 4 in the article: “Finally, once completely done, go back and perfect”.

It may be because of tight deadlines, lazyness (it’s “good enough” so why bother?) or eagerness to jump to the next project (because it is more exciting or profitable than doing the hard work of getting the details right).

I guess there is also a personality type factor that plays into it, because many people seem to just care about the hard requirements and cannot be bothered about things like performance, accessibility, design consistency, simplicity, maintainability, good documentation, etc., at least as long as nobody complains about it.

[+] tbm57|1 year ago|reply
I'm not as much of an overhead strategist, but I do have a rule that I follow that matches this article: if I hesitate to start working on a problem because it seems too difficult, it's because that problem has not yet been broken into small enough parts.
[+] layer8|1 year ago|reply
I tend to hesitate because I know exactly that it will be a lot of long and difficult work to break everything down into small enough parts, of which there will be a whole lot, and work through them and integrate them all.
[+] theZilber|1 year ago|reply
I agree, I follow the same principle. Also i would like to extend it to - "if you slow down when working on a problem, you might have stumbled upon something unexpected, identify it, and break it down.
[+] lackoftactics|1 year ago|reply
I've been diving into the science of learning, and the blog author clearly knows their stuff. For those intrigued by this field, here are some fascinating concepts worth exploring:

Bloom's Taxonomy (absolute game-changer), Inquiry-Based Learning, Deep Cognitive Processing & Higher-Order Thinking (closely tied to Bloom's Taxonomy), Generation Effect & Testing Effect, Deliberate Practice, Interleaving, Metacognition, Cognitive Load Theory, Problem-Solving Techniques: First Principles Thinking, Second-Order Thinking, Socratic Questioning, 5 Whys, Inversion, Divide and Conquer

Each of these concepts can seriously level up your learning game. Happy googling/using llm!

[+] brailsafe|1 year ago|reply
Given the disaster that can be both google and llm, do you have any specific pieces of writing you found particularly high quality?
[+] twelvechairs|1 year ago|reply
2 counterpoints

- if you are pushing technical boundaries you may need to prove something is achievable before you go back and do the comparatively easy stuff (build the website, set up the company etc.)

- As context switching creates a huge cognitive load it can be useful to create discrete chunks of work and not just jump around all the time.

[+] jumploops|1 year ago|reply
This strategy can be applied to learning as well.

The concepts are very similar to those presented in “How to Read a Book”[0].

The general gist is: create a mental outline of the book/material (via the table of contents), dive into interesting chapters, resurface to the outline, dive again, etc.

This strategy is useful for quickly building a mental model and using your own interest as the guiding light.

Similar to building quickly, the focus is on your attention/what’s most important, rather than traversing from the beginning to the end serially.

Great post!

[0] https://en.m.wikipedia.org/wiki/How_to_Read_a_Book

[+] TechDebtDevin|1 year ago|reply
How to Read a Book, is ironically one of my favorite books.

I attribute a lot of my ability to learn to this book and a teacher in high school that forced us to read and understand it.

[+] dmvdoug|1 year ago|reply
It’s just the hermeneutic circle at work, nothing magical.
[+] DelaneyM|1 year ago|reply
I’m constantly amazed at how differently I learned to do things from my father than from school.

My father had all sorts of approaches similar to this, and it’s how I learned to write essays (outside-in) and research (inside-out), and which I later applied to programming. It made school trivial and fun, and it’s what I’m teaching my kids.

[+] aswegs8|1 year ago|reply
Sounds interesting. Can you provide some more examples?
[+] throwaway63467|1 year ago|reply
I think it’s often called the “tracer bullet principle” as well. Get a full version of your system working quickly from end to end, then improve each part incrementally. Powerful stuff indeed, also for your motivation and sense of accomplishment. Nothing sucks the joy out of work more than building and building and not getting any feedback.
[+] idk1|1 year ago|reply
What's interesting about this is, I have always done what the author describes and I just assumed when people wrote (for example) an essay, they would outline all the points and the structure first and then go and fill in each section and refine it over time. Same with ideas and projects, I would do rough outlines, then add fidelity. Same with programing, I'll make an outline and go and refine it all.

It's strange, I assumed this so strong I never thought anyone would ever start writing and essay from the beginning without considering more of it, similar to just starting projects or code, I guess they do and it works really well.

What's the break down of people's approches to things here, which bucket are you in?

[+] diggan|1 year ago|reply
> It's strange, I assumed this so strong I never thought anyone would ever start writing and essay from the beginning without considering more of it, similar to just starting projects or code, I guess they do and it works really well.

It really depends on the task/text at hand. With some things I set out to do, I know I want to reach a concrete goal, then it's easy to do an outline first with the finish point being the known goal, then fill out the middle-pieces.

But at other points, you're not 100% sure what the goal is. Then starting from the beginning and just going with the flow until you reach something that feels like the goal is the way to go, and you'll adjust as you go along.

Other times a mix between the two is optimal, where you think you knew what the goal was, but as you're half-way of filling out the outline, you see that another goal would be better fitted, and you adjust. Or you realize what the goal was all-along as you're nearing the finish, and you go back and adjust.

Basically, there is no single path/process that fits all types of problems or people even. You try out different things until you find the way(s) that fit you and the stuff you typically handle.

[+] akudha|1 year ago|reply
I had a boss who was a very good programmer and a writer. He used to spend hours just writing the table of contents, hours. Once he is satisfied, he will finish writing the actual text very, very fast.

While he would write and rewrite ToC multiple times, he rarely edited the actual content, no matter how long it was.

I suppose different strategies work for different people

[+] smu|1 year ago|reply
As a hobby project, I started a market research/overview of the Belgian cybersecurity ecosystem [1].

This required me to write a lot more than before, although I've always enjoyed writing.

In the beginning, I wrote beginning -> end, with just a high outline in my mind. Now, I write bullets first and then expand into paragraphs. This has helped me write a lot quicker and I think the articles have become easier to read (which matters a lot online, where everyone reads diagonally).

[1] https://becyberscape.com

[+] captainkrtek|1 year ago|reply
This is a great article that summarizes a method I’ve already used for my work over the years. When writing a new project from scratch ill make a bunch of structure (defining modules, writing pseudo code) then start to fill things out piece by piece. Often times ill need to adjust the structure as I go but helps for building a mental model of a new project (at least for me)
[+] 3abiton|1 year ago|reply
Do you mind sharing a concrete example of one your project s?
[+] andrewstuart|1 year ago|reply
This message is suspiciously like being told to draw the outline of an owl then draw the rest of the fucking owl.

https://seths.blog/2014/01/how-to-draw-an-owl/

The word recursively does a lot of work in the post.

Every project I go into thinking I can do it quick and it never works that way because the minimal viable or minimum lovable thing is a long way from the minimum actual concept of what I have in mind. I feel that I need to build enough that the user is engaged with it.

I feel like those first explorers willing to try out a new thing are incredibly valuable and their attention should not be wasted on the outline, but they should be presented with the owl.

[+] tzs|1 year ago|reply
I did something like that the first time I had to write a device driver, but I did it kind of stupidly.

It was in college and I had a part time job doing doing system administration and programming for the high energy physics department. They had an RX02 8" floppy drive that they wanted to use on their VAX 11/780 which was running Unix/32V and I was assigned to write the driver.

I basically started with a C file that just had empty functions for all the functions that I knew Unix expected a driver to have, and then started filling those functions with comments recording what I had figured out that they had to do.

Each started with just a few high level comments. Then I'd add more comments breaking those down, and so on, until I finally had all the information I'd need in there and could start coding.

That's when I then did something stupid. As I started implementing the things the comments described I replaced the comments with the code.

I got about half way through before I realized that I should adding the code below the comments rather than replacing the comments.

[+] ilrwbwrkhv|1 year ago|reply
This really works. When I used to work at big tech, I had a reputation for being incredibly fast and this is the method I used.

This is also one of the reasons why I never moved away from Workflowy as an outlining tool. Nothing else has come close to it.

If I have to add one thing, it is that when you are recursively building your outline, it might grow really big and that might overwhelm you so I recommend a pruning step where you prune some of the nodes to make the overall outline tighter as a final step before proceeding on building. But do not worry too much and cut nodes ruthlessly. Often times you can get stuck at this point if you think too much.

[+] mbforbes|1 year ago|reply
For me, this approach works great with one enormous exception: I must already know exactly what I'm going to write about.

I have tried outlining my writing countless times. But inevitably, the real work of thinking meticulously comes with the writing itself. In composing prose at the finest level of detail, I discover the true shape of the topic through its nuance.

I always throw out my outlines, no matter how many times I have iterated on them. My high level thinking couldn't sufficiently understand the topic.

PG expressed this well: writing is thinking, at least for some of us.

[+] layer8|1 year ago|reply
In particular if you have to build on existing systems, a top-down approach doesn’t always work well, because the overall design may well depend on details of the existing parts you have to integrate with. In that case, starting with prototyping a vertical slice of the functionality can be the better approach.
[+] matheusmoreira|1 year ago|reply
> DO NOT PERFECT ANYTHING UNTIL DONE

> without caring about quality AT ALL

I really need to master this. I spend absurd amounts of time thinking about the littlest things. It can take a long time for me to mentally accept that the code is fine and ready to be committed to the repository and published.