How to build quickly
learnhowtolearn.org
learnhowtolearn.org
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.
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.
In dynamic languages like Clojure it is far too easy to couple functionality and write implicitly imperative but superficially functional code. Something I'm guilty of because it's too easy to do and takes a lot of experience and discipline to avoid.
Isolating state is the key principle. Philosophically you could say a program following this principle written in an object oriented or procedural language is more "functional" than a program that passes around a big tangle of state in a single data structure written in a functional language.
I don't know how true that really is. JavaScript added `class` relatively late in it's lifespan, and most JavaScript/TypeScript projects use `class` to hide shared state/mutations behind that interface, in the name of `encapsulation`, rather than just passing stateless data from function to function.
Both patterns obviously has their places, no silver bullets and all that, but you'll have a hard time finding any relatively popular JS/TS project that doesn't overtly rely on shared state one way or another.
> you'll have a hard time finding any relatively popular JS/TS project that doesn't overtly rely on shared state one way or another
That's sampling bias. Where's the thousands of the event driven DOM UI Haskell projects, which doesn't rely on shared state?
Agree, but JS's syntax and constructs are almost begging the user to encapsulate their state in classes and instances and share those instances between function calls, rather than passing the data itself around. This is very visible if you browse the various JS APIs as well.
Can't "sendEmail" be a function near the edge of the network that does the IO of actually pushing the bytes across the network, decoupled from the "pure" functions at the heart of your application?
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.
Interestingly, Erlang is very much a functional language. But Erlang procedures are a lot like Smalltalk objects, as explained by Joe Armstrong. You send messages to a pid (process id) which then update some state held by the process and possibly sends back a value in response. But the new state is always computed by a pure function.
Maybe this is similar to your design philosophy?
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.
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.)
Sometimes I'll delete the nested entries outright, but usually I'll just keep them around until I get to a point where I'm close to completing the feature and then I'll re-visit them to see if they still apply or if I need to reincorporate them into the new design.
I use this tool: https://github.com/lelanthran/frame/blob/master/docs/FrameIn...
It allows me to drop a node in the tree, dropping all children along with it. Or rename arbitrary nodes in the tree, or move them around.
The cli tree flow is very likely better, but those destructive pops -- it would be hard for me to let go of the ability to look back at the end of the day retrospectively and see the path that was explored.
It's a trade-off: aggressively pruning the noise leaves a lot of signal. I have also found that, when writing down goals/objectives/tasks/whatever, knowing in advance that they are going to be discarded once done makes them more focused on achieving the goal, rather than trying to document what is done.
Essentially, when adding nodes, I add directives to be filled, not documentation for what was done. This keeps me focused on achieving the goal without getting side-tracked by putting in explanatory documentation for future me.
The notes I make are to allow future me to implement $thing, not future me to understand $thing.
It's probably the former
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).
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.
I also time boxed myself when writing. I wouldn't write unless I had a really clear topic in mind, then I'd give myself an hour to get it published. A few times I ran out of time and ended it with a "follow-up post coming soon to dive into ___" type message and that worked just fine.
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.
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.
There’s the stories of college professors who split their class into two groups, one group that is graded on quality of a single photo/pottery submission, and the other group graded solely on quantity of work produced, and the group tasked with producing quantity always produces higher quality.
I guess I don’t see why building a car or rocket would be different, other than we now know how to do it well.
When people were first building rockets, it was just a blooper real of failures.
Is there some distinction along figuring out the theory/physics, versus figuring out the application, real world, material science angle? Like I could see spending a long time on the theory side, but once that’s understood, it seems like figuring out which materials can produce the required physics is quick iteration’s bread-and-butter.
Truth is, for most things in life, good enough is just good enough. Lots of things we do have a short shelf life anyways.
I guess deciding the right level of goodness (or perfectness) of the tasks/projects we do in life is a big skill in itself
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.
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.
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.
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]
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!
- 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.
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!
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.
- How to read a book by Adler
- How to read a paper[0]
- How to study[1]
Serves as an entrypoint and gatekeeper. Reminds me every time how to spend my time effectively there.
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.
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?
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).
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.
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
I'll create the base directories(e.g. www, api, auth). Then the components (e.g config, data, geo, mailer, utils, web etc) In each component I'll make a readme.md with what the component should do. Sometimes this leads to large components and when that happens I break the component directory into smaller ones (e.g. web-client, web-server, web-routes, web-middleware etc) and add a readme to those. Then (what I planned to do but usually skip) add function names to the interface file based on the readme, then work on the implementation (I usually end up going straight to this and wish I had created the interface "guide" cause now I've gone off track and need to clean it up)
Not sure if this is a common way to polylith, or if I'm doing it wrong. It helps me keep track better than trying to search through outlines and notes that are scattered all over the place, or in an app I dont feel like opening or logging into, usually ending with me re-writing the same thing 2-3+ times.
[0] https://polylith.gitbook.io/polylith
[1] https://cljdoc.org/d/polylith/clj-poly/0.2.20/doc/production...
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.
To me, MVP means "Do part A to a good enough level of perfection where customers will buy it, then release and get customers, support them while then working on part B as a value-add.." - often, in my mind, all parts, ABC add up to the whole package value. I don't want to break it apart.
I'm actually trying to do more planning and outlining first, and it has worked reasonably well for me.
Start with an outline of the different systems and how they connect, then outline one of those systems, the inputs and outputs to it. Then break down further into how does it get the input, where does it put the output, etc.
It has been remarkable in that I can actually feel joy for what I'm making again. I have also tried to start a blog with doing this type of "open design" - but blog writing requires its own planning and refining, which is an extra workload that I didn't intend to put on myself..
You can see the process here https://youtu.be/UGVOE2eHl0I
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.
Making an outline is also important for writing. However doing research also has its place. See this here https://cse.buffalo.edu/~rapaport/howtostudy.html#makeoutlin... (also previously discussed on HN)
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.
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.
My current thinking on a solution to this conundrum is this: try to craft the best architecture and engineering you can up-front _vertically_, but drastically reduce the workload by paring things down _horizontally_.
> 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.
https://en.wikipedia.org/wiki/Bottom%E2%80%93up_and_top%E2%8...
Except you can also do top down design without the slapdashery, and it will usually be equally fast and a lot better.
I agree about top-down design vs "progress-bar" design though (I do like this term!).
But of course, there's nothing stopping you from creating slapdash progress-bar code either. Which is the worst possible outcome, obviously.
However, I do not know how to follow this advice: "DO NOT PERFECT AS YOU GO. This is a huge and common mistake" because, when you develop something critical and apply TDD, testing actually is a synonym of perfecting your approach to solving an issue. Not to mention that testing comes before code itself: it pushes you to think carefully, and come out with the best strategy before iterating any further.
The first draft can, should even, be sketchy: it doesn't have to work all the way through; one can think of it as a prototype to help you understand the problem better[0]. It can even be discarded, for example if it's too far away from what is actually needed.
In that setting, TDD might be more suitable for a second or a third pass, once you have a solid grasp of the code's structure.
[0]: https://en.wikipedia.org/wiki/The_Mythical_Man-Month#The_pil...
The most fascinating thing about human intellect is how we all land in the same places, we just give them different names upon discovery.
Then, it feels very boring to finish up the filling of outlines and I get a feeling that dragging myself over a bed of gravel is easier than finishing up the whole thing.
Definition : "A divide-and-conquer algorithm recursively breaks down a problem into two or more sub-problems of the same or related type, until these become simple enough to be solved directly. The solutions to the sub-problems are then combined to give a solution to the original problem."
The real key is communication and trust. It only worked well for us because we communicated frequently, the CTO/lead was really good at acting as a conduit between everyone working on related projects, and we all really offered each other the trust to let each other run with it and adjust on the fly.
It was really common for us to go into a week with a clear idea of what the next feature to build was, only to end the week with the person working on it finding a different path or a reason not to build that at all, often with an alternative to propose. We'd discuss it as a team when needed, but it was always clear that the person who was working on it was the expert on it at the moment and had a lot of sway in direction for that feature.
It isn't easy, and it did actually fall apart when the team scaled to 10+ people, but there may have been ways we could have adjusted and avoided that too.
Also lol at the comment that speedrunning and iteration lets you get the junk out of the way so you can really focus on where quality matters… a paragraph away from saying speedrun and iterate and then feel good about being 90% done while you sit around twiddling with the title bar styling.
(came up with the concept when struggling to write my PhD thesis)
Hope it helps!
this is bascially how i do it if you look at my notion doc for the idea, and the first commits of the codebase
The same applies to fluff software, but only to fluff software. If you have to create a page with a dozen buttons with a bunch of click handlers, hook those up to basic AJAX calls, then yes, you can speedrun that as well. Because it's extremely easy work that involves no thinking.
Many things in life are kind of mundane and tedious. Fake school work, taxes, cleaning, ironing, to give just a few examples. And having strategies to blast through that kind of work effectively is useful. But these strategies absolutely unhelpful when you're trying to do anything creative or difficult.
You can't write a great spy novel with an outline like: 'introduce spy character', 'successful mission 1 in present time', 'flash back to failed earlier mission', 'introduction of big bad guy', 'flash back to tragic backstory', 'spy gets assigned special mission only his handler knows about'. Filling out an outline like this produces an uninspired, boring, formulaic trash. You end up with bad airport reading, the equivalent of AI slop.
To give another example: PG spends MONTHS on a single essay. He is not bottlenecked by a missing outline. Speedrunning the wiring process doesn't help. Figuring out exactly what you want to say is the hard part. Putting words on paper is trivial in comparison.
As for the spy novel, i think the outlining is actually quite similar to how Sylvester Stallone described his writing process[0]. You wouldn't fill the outline with generic beats, you would put in your basic plan for the story.
It's the same for software. By time time you understand the problem well enough that you can write down a list of things to be done you're already way past the "thinking hard" stage.
Sylvester Stallone wrote the script for rocky in 3 days. He could do this because he had already figured out the concepts, the theme, the characters and their personalities way ahead of time. He had worked on it in his head for years. By the time he started typing 90% of the work was already done. Nothing Stallone wrote later in his career was as good as his original rocky script.
Yes, he didn't come up with the ideas from scratch as he was writing them. It took years to gain the experience and expertise. Yet he still saw the value in outlining when the time came to write it down.
> Filling out an outline like this produces an uninspired, boring, formulaic trash
So write a better outline. George R. R. Martin and Agatha Christie both used extensive notes and outlines as part of their writing process.
> She made endless notes in dozens of notebooks, jotting down erratic ideas and potential plots and characters as they came to her “I usually have about half a dozen (notebooks) on hand and I used to make notes in them of ideas that struck me, or about some poison or drug, or a clever little bit of swindling that I had read about in the paper”.
> She spent the majority of time with each book working out all the plot details and clues in her head or her notebooks before she actually started writing.
https://www.agathachristie.com/about-christie/how-christie-w...
I think the main confusion is about the speedrunning aspect. You don't speedrun gathering thoughts, you speedrun turning those thoughts (that took weeks, months, or years to develop) into writing. You may not struggle with writing, but a lot of people absolutely are.
outlining = asking questions
i think the education system encourages the loading bar style. we are taught how to answer questions. i think AI will push education more towards the second type where the emphasis on asking questions.
like in a tech interview, instead of asking you some leetcode puzzle, i will ask you to ask me questions about the subject to demonstrate your knowledge. kind of socratic style.
3b. Realize that your outline is wrong. You did not fully understand the problem when you wrote it. Go back to step 1.
5. Realize that you are never completely done. You will not go back and perfect.
The result is... better than not making an outline, but it's hardly a game-changing approach.
I'm reminded of something that Mike Bloomberg wrote in his book: Make a detailed plan for your work. Write down every detail until you're satisfied that you know how to proceed. Then throw the plan away, because it is now worthless.
this could be the most powerful thread ive come across on HN