I’ve learned at Amazon that writing about what you want to build, and why, and why not do something else - in a way that others can clearly comprehend, and before ever touching a line of code - helps you think even more clearly.
While I disagree with this approach in general - manually executing a task and following the data flow is the best way to understand a new system - I will say that with the rise of LLMs, writing documentation, stubs and comments first may be the fastest way to bootstrap a new project.
Maybe it does for some people but based on all of the functional specifications I've implemented over the years, they are by far the exception. Maybe designing and documenting first is OK if it's done by people who've already learned how systems work by building and maintaining a lot of them, though.
The documents used in Amazon at that lifecycle stage aren't functional specifications. The point is to justify launching a few project to management. You should be able to clearly explain why it's worth expending resources.
It really doesn't, unless you've already implemented a variation of the thing before.
There is a time for reflection and planning/thinking about a given software problem, but you're mostly wasting time doing so in-depth before you've done/looked through a rudimentary implementation.
Your planned architecture will be worse then the one from the person that interated several times while introspecting the resulting code, discovering misconceptions on the way.
Do note that this initial implementation is only there to learn the domain of the software, basically.
The phase can be skipped if you're not really changing anything and mostly just reimplement something you've done before. At that point, you're not doing something new however.
> initial implementation is only there to learn the domain
I've been trying to do a kind of documentation-driven development, where I write a fairly detailed README file before I write a single line of code. It hasn't gone as smoothly as I imagined, I think it takes practice to get more effective - similar to test-driven dev. And it made me realize my usual approach is "to think by coding", and to explore the problem space with a rough draft of a program.
It must be a common approach, as I've heard people say "Throw away the first draft." Not only in programming but about writing in general. Ah, there's even a term for it:
You don't have to save everything you build. Many times I've implemented a feature and felt unsatisfied with it, reverted, and built the same thing again.