8 ms·
Great article. I just want to comment on this quote from the article: "Really good developers do 90% or more of the work before they ever touch the keyboard;"
by brabel 3y ago
Great article. I just want to comment on this quote from the article:
"Really good developers do 90% or more of the work before they ever touch the keyboard;"
While that may be true sometimes, I think that ignores the fact that most people can't keep a whole lot of constraints and concepts in their head at the same time. So the amount of pure thinking you can do without writing anything at all is extremely limited.
My solution to this problem is to actually hit the keyboard almost immediately once I have one or more possible ways to go about a problem, without first fully developing them into a well specified design. And then, I try as many of those as I think necessary, by actually writing the code. With experience, I've found that many times, what I initially thought would be the best solution turned out to be much worse than what was initially a less promising one. Nothing makes problems more apparent than concrete, running code.
In other words, I think that rather than just thinking, you need to put your ideas to the test by actually materializing them into code. And only then you can truly appreciate all consequences your ideas have on the final code.
This is not an original idea, of course, I think it's just another way of describing the idea of software prototyping, or the idea that you should "throw away" your first iteration.
In yet different words: writing code should be actually seen as part of the "thinking process".
- vorticalbox 3y agoThis is what I do I right off the bat wrote down an line or two about what I need to do. Then I break that down into small and smaller steps. Then I hack it together to make it work. Then I refactor to make it not a mess.
- jbverschoor 3y agoPen, paper, diagrams.
- deleted 3y ago[deleted]
- lwhi 3y agoXmind and draw.io
- ChrisMarshallNY 3y agoI tend to iterate. I get a general idea, then start writing code; usually the "sticky" parts, where I anticipate the highest likelihood of trouble. I've learned that I can't anticipate all the problems, and I really need to encounter them in practice. This method often means that I need to throw out a lot of work. I seldom write stuff down[0], until I know that I'm on the right track, which reduces what I call "Concrete Galoshes."[1] [0] https://littlegreenviper.com/miscellany/evolutionary-design-specification/ https://littlegreenviper.com/miscellany/evolutionary-design-... [1] https://littlegreenviper.com/miscellany/concrete-galoshes/ https://littlegreenviper.com/miscellany/concrete-galoshes/
- JKCalhoun 3y agoI do the same, iterate. When I am happy with the code I imagine I've probably rewritten it roughly three times. Now I could have spent that time "whiteboarding" and it's possible I would have come close to the same solution. But whiteboarding in my mind is still guessing, anticipating - coding is of course real. I think that as you gain experience as a programmer you are able to intuit the right way to begin to code a problem, the iterating is still there but more incremental.
- ChrisMarshallNY 3y agoI don’t think this methodology works, unless we are very experienced. I wanted to work that way, when I was younger, but the results were seldom good. Good judgment comes from experience. Experience comes from bad judgment. -Attributed to Nasrudin
- marktani 3y agoWho's Nasrudin? Apparently this quote has been attributed to an Uncle Zeke :) [0] [0]: https://quoteinvestigator.com/2017/02/23/judgment/ https://quoteinvestigator.com/2017/02/23/judgment/
- ChrisMarshallNY 3y ago
- prerok 3y agoI could not agree more, it's rare to write a program where you know all the dependencies, libraries you will use and the overall effect to other parts of the program by heart. So, gradual design process is best. I would point out, though, that that part also touched understanding requirements, which is many times a very difficult process. We might have a technical requirement conjured, by someone less knowledgeable about the inner workings, from a customer requirement and the resolution of the technical requirement may not even closely address the end-users' use-case. So, a lot of time also goes into understanding what it is that the end-users actually need.
- lwhi 3y agoI think first on a macro level, and use mind maps and diagrams to keep things linked and organised. As I've grown older, the importance of architecture over micro decision has become blindingly apparent. The micro can be optimised. Macro level decisions are often permanent.
- eternityforest 3y agoI think this is probably a lot of the value of YAGNI. The more crap you add the harder it is to fix bad architecture. And the crap is often stuff that would be trivial to add if the bad architecture weren't there, so if you fix that you can add the feature when you need it in a week.
- lwhi 3y agoI think that's probably part of it; but on a really simple level with YAGNI you're not expending effort on something that isn't needed which reduces cost. What I try to do is think about the classes of functionality that might be needed in the future. How could I build X feature in a years time? Leave doors open, not closed.
- ben_w 3y ago> While that may be true sometimes, I think that ignores the fact that most people can't keep a whole lot of constraints and concepts in their head at the same time. Indeed, and this limitation specifically is why I dislike VIPER: the design pattern itself was taking up too many of my attention slots, leaving less available for the actual code. (I think I completely failed to convince anyone that this was important).
- kragen 3y agoare you talking about the modal text editor for emacs
- thaumasiotes 3y agoI would bet he meant this: https://www.techtarget.com/whatis/definition/VIPER https://www.techtarget.com/whatis/definition/VIPER
- indigoabstract 3y agoI had the same thought as I read that line. I think he's actually describing Linus Torvalds there, who, legend has it, thought about Git for a month or so and when he was done thinking, he got to work coding and in six days delivered the finished product. And then, on the seventh day he rested. But for the rest of us (especially myself), it seems to be more like an interplay between thinking of what to write, writing it, testing it, thinking some more, changing some minor or major parts of what we wrote, and so on, until it feels good enough. In the end, it's a bit of an art, coming up with the final working version.
- tsss 3y agoWell that explains why Git has such a god awful API. Maybe he should've done some prototyping too.
- indigoabstract 3y agoYeah, could be.. IIRC, he said he doesn't find version control and databases interesting. So he just did what had to be done, did it quickly and then delegated, so he could get back to more satisfying work. I can relate to that.
- deleted 3y ago[deleted]
- mejutoco 3y agoOn the other side the hooks system of git is very good api design imo.
- QuercusMax 3y agoWhat do you mean by API? Linus's original got didn't have an API, just a bunch of low level C commands ('plumbing'). The CLI ('porcelain') was originally just wrappers around the plumbing.
- Maxatar 3y ago
- kragen 3y agoyeah, i just sketched out some code ideas on paper over a few days, checked and rechecked them to make sure they were right, and then after i wrote the code on the computer tonight, it was full of bugs that i took hours and hours to figure out anyway. debugging output, stepping through in the debugger, randomly banging on shit to see what would happen because i was out of ideas. i would have asked coworkers but i'm fresh out of those at the moment i am not smart enough this week to debug a raytracer on paper before typing it in, if i ever was things like hypothesis can make a computer very powerful for checking out ideas
- devsda 3y agoI agree this is how it often goes. But this also makes it difficult to give accurate estimates because you sometimes need to prototype 2,3 or even more designs to workout the best option. > writing code should be actually seen as part of the "thinking process". Unfortunately most of the times leadership dont' see things this way. For them the tough work of thinking ends with architecture or another layer down. Then the engineers are responsible only for translating those designs into software just by typing away with a keyboard. This leads to mismatch in delivery expectations between leadership and developers.
- lwhi 3y agoIn my opinion, you shouldn't need to prototype all of these options .. but you will need to stress test any points where you have uncertainty. The prototype should provide you with cast iron certainty that the final design can be implemented, to avoid wasting a huge amount of effort.
- marcosdumay 3y agoIf you know so little that you have to make 3 prototypes to understand your problem, do you think designing it by any other process will make it possible make an accurate estimate?
- Aerroon 3y agoThe way I read that is that only 10% of the work is writing out the actual implementation that you're sticking with. How you get there isn't as important. Ie someone might want to take notes on paper and draw graphs while others might want to type things out. That's all still planning.
- swat535 3y agoRight, I always thought this is what TDD is used for, very often I design my code in tests and let it kind of guide my implementation. I kind of imagine what the end result should be in my head (given value A and B, these rows should be X and Y), then write the tests in what I _think_ would be a good api for my system and go from there. The end result is that my code is testable by default and I get to go through multiple cycles on Red -> Green -> Refactor until I end up being happy with. Does anyone else work like this?
- shuvuvt5 3y agoTDD comes up with some really novel designs sometimes. Like, I expect it should look one way but after I'm done with a few TDD cycles I'm at a state that's either hard to get there or unnecessary. I think this is why some people don't like TDD much, sometimes you have to let go of your ideas, or if you're stuck to them, you need to go back much earlier and try again. I kind of like this though, makes it kind of like you're following a choose your own adventure book.
- gnz00 3y agoI prefer to write an initial implementation, and then in the testing process figure out which interfaces simplify my tests, and then I refactor the implementation to use those interfaces. Generally, this avoids unnecessary abstraction, as the interfaces for testing tend to be the same ones you might need for extensibility.
- sho 3y agoSometimes, when I feel like I know the basic domain and can think of something reasonable that I could use as a "north star" test end-point, I work like this. Think anything that could be a unit test, or even a simple functional test. But when I don't know the domain, or if it's some complex system that I have to come up from scratch, writing tests first often makes no sense at all. Then I'd usually start literally drawing on paper, or typing descriptions of what it might do, then just start coding, and the tests come much, much later. Right tool for the job, as always! The only thing I can't stand is blind zealotry to one way or the other. I've had to work with some real TDD zealots in the past, and long story short, I won't work with people like that again.
- bakuninsbart 3y agoSame, and since we are on the topic of measuring developer productivity; usually my bad-but-kinda-working prototype is not only much faster to develop, it also has more lines of code, maximizing my measurable productivity!
- nick__m 3y agoI completely agree with you. This article is on the right track but it completely ignore the importance of exploratory programming to guide that thinking process.
- makerdiety 3y agoMathematics was invented by the human mind to minimize waste and maximize work productivity. By allowing reality mapping abstractions to take precedence over empirical falsifications of propositions. And what most people can't do, such as keeping in their heads absolutely all the concepts of a theoretical computer software application, is an indication that real programmers exist on a higher elevation where information technology is literally second nature to them. To put it bluntly and succinctly. For computer software development to be part of thinking, a more intimate fusion between man and machine needs to happen. Instead of the position that a programmer is a separate and autonomous entity from his fungible software. The best programmers simulate machines in their heads, basically.
- marcosdumay 3y ago> The best programmers simulate machines in their heads, basically. Yes, but they still suck at it. That's why people create procedures like prototyping, test driven design, type driven design, paper-prototypes, API mocking, and etc.
- makerdiety 3y agoThe point is that there are no programmers that can simulate machines in their heads. These elite engineers only exist in theory. Because if they did exist, they would appear so alien and freakish to you that they would never be able to communicate their form of software development paradigms and patterns. These rare type of programmers only exist in the future, assuming we're on a timeline toward such a singularity. And we're not, except for some exceptions that cultivate a colony away from what is commonly called the tech industry. EDIT: Unless you're saying that SOLID, VIPER, TDD, etc. are already alien invaders from a perfect world and only good and skilled humans can adhere to the rules with uncanny accuracy?
- deleted 3y ago[deleted]
- iraqmtpizza 3y agoString theory was invented by the human mind to minimize productivity and maximize nerd sniping. Pure math.
- mihaic 3y agoI'd like to second that, especially if combined with a process where a lot of code should get discarded before making it into the repository. Undoing and reconsidering initial ideas is crucial to any creative flow I've had.
- andsmedeiros 3y agoI don't think the quote suggests that a programmer would mentally design a whole system before writing any code. As programmers, we are used to thinking in problems as steps needing resolution and that's exactly the 90% there. When you're quickly prototyping to see what fits better as a solution to the problem you're facing, you must have already thought what are the requirements, what are the constraints, what would be a reasonable API given your use case. Poking around until you find a reasonable path forward means you have already defined which way is forwards.
- tibbar 3y agoThe secret to designing entire applications in your head is to be intimately familiar with the underlying platform and gotcha's of the technology you're using. And the only way to learn those is to spend a lot of time in hands-on coding and active study. It also implies that you're using the same technology stack over and over and over again instead of pushing yourself into new areas. There's nothing wrong with this; I actually prefer sticking to the same tech stack, so I can focus on the problem itself; but I would note that the kind of 'great developer' in view here is probably fairly one-dimensional with respect to the tools they use.
- graemep 3y agoYou make me feel a lot better about my skill set!
- wredue 3y agoI don’t like that line at all. Personally, I think good developers get characters on to the screen and update as needed. One problem with so much upfront work is how missing even a tiny thing can blow it all up, and it is really easy to miss things.
- theptip 3y agoAgree with your point. I think “developers that do 90% of their thinking before they touch the keyboard are really good” is the actual correct inference. Plenty of good developers use the code as a notepad / scratch space to shape ideas, and that can also get the job done.
- tippytippytango 3y agoI also find it critical to start writing immediately. Just my thoughts and research results. I also like to attempt to write code too early. I'll get blocked very quickly or realize what I'm writing won't work, and it brings the blockage to the forefront of my mind. If I don't try to write code there will be some competing theories in my mind and they won't be prioritized correctly.
- layer8 3y agoThat quote is already a quote in the article. The article author himself writes: > What is really happening? > • Programmers were typing on and off all day. Those 30 minutes are to recreate the net result of all the work they wrote, un-wrote, edited, and reworked through the day. It is not all the effort they put in, it is only the residue of the effort. So at least there the article agrees with you.
- jayd16 3y agoI'd take the phrase with a grain of salt. What's certain true is that you can't just type your way to a solution. Whether you plan before pen meets paper or plan while noodling is a matter of taste.
- 0x20cowboy 3y agoI think it was Feynman who said something to the effect of “writing is thinking”.
- narag 3y agoThere's more than one way to do it. How I work: - First I make a very general design of modules, taking into account how they are going to communicate with each other, all based in experience with previous systems. - I foresee problematic parts, usually integration points, and write simple programs to validate assumptions and test performance. - I write a skeleton for the main program with a dumbed-down GUI. From that point on, I develop each module and now, yes, there's a lot of thinking in advance.
- BurningFrog 3y agoI used to think a lot before coding. Then I learned TDD, and now I can discover the design while I code. It's a huge improvement for me!
- knodi123 3y agoditto. My coworkers will sit down at the whiteboard and start making ERDs, and I'll just start writing a DB migration and sketching up the models. They think I'm crazy, because I have to do rollbacks and recreate my table a few times as I think of more things, and I wind up deleting some code that I already wrote and technically worked. Who cares? Time-wise, it comes out the same in the end, and I find and solve more hidden surprises by experimenting than they do by planning what they're going to do once they're finally ready to type. I think it's just two ways of doing the same thing.
- gofreddygo 3y agoI agree with the spirit of "writing code" as part of the thinking process but I have to point out a few very dangerous pitfalls there. first is the urge to write the whole prototype yourself from scratch. Not necessary, better avoided. You should just hack some things together, or pick something close to what you want off github. Idea is to have something working. I am a big proponent of implementing my ideas in a spreadsheet, then off to some code. Second is modern software solutions are complex (think kubernetes, cloud provider quirks, authentication, sql/nosql, external apis) and easy to get lost in the minutiae, they shroud the original idea and takes strenuous effort to think clearly through the layers. To counter this, I keep a single project in my language of choice with the core business logic. No dependencies. everything else is stubbed or mocked. It runs in the IDE, on my laptop, offline with tests. This extra effort has paid off well to focus on core priorities and identify when bullshit tries to creep in. You could also use diagrams or whatever but working executable code is awesome to have. third is to document my findings. Often I tend to tinker with the prototype way beyond the point of any meaningful threshold. its 2am before i know it and i kinda lose the lessons when i start the next day. Keeping a log in parallel with building the prototype helps me stay focussed, be clear in what my goals are and avoid repeating the same mistakes. fourth is the rather controversial topic of estimation. When i have a running prototype, I tend to get excited and get too optimistic with my estimates. Rookie mistake. Always pad your estimates one order of magnitude higher. You still need to go through a lot of bs to get it into production. Remember that you will be working with a team, mostly idiots. Linus works alone.
- delian66 3y ago"Most people" are not "Really good developers".
- zelphirkalt 3y agoAlso not every task requires deep thought. If you are writing some CRUD, it is usually not going to be all that much thinking, but more touching the keyboard.
- eternityforest 3y agoI wish I had thought a little more about this CRUD. I hand wrote HTML forms and that was not a great plan. I made a dialog generator class in about a half hour that replaced dozens of CreatePermission.html type garbage I wrote a decade ago.
- soco 3y agoGermans say "probieren geht über studieren" which means, rather try it than think it too much.
- blksv 3y ago(not so much of a reply, but more of my thoughts on the discussion in the replies) I would say the topic is two-sided. The first is when we do greenfield development (maybe, of some new part of an already existent software): the domain is not really well known and the direction of the future development is even less so. So, there is not much to think about: document what is known, make a rough layout of the system, and go coding. Too much investing in the design at the early stages may result in something (a) overcomplicated, (b) missing very important parts of the domain and thus irrelevant to the problem, (c) having nothing to do with how the software will evolve. The second (and it is that side I think the post is about) is when we change some already working part. This time it pays hugely to ponder on how to best accommodate the change (and other information the request to make this change brings to our understanding of the domain) into the software before jumping to code. This way I've managed to reduce what was initially thought to take days (if not weeks) of coding to writing just a couple of lines or even renaming an input field in our UI. No amount of exploratory coding of the initial solution would result in such tremendous savings in development time and software complexity.
- ABoredBirb 3y agoMy pet theory is that developers exist on a spectrum between "planner" and "prototyper" - one extreme spends a lot of time thinking about a solution before putting it into code - hopefully hitting the goal on first attempt. The other iterates towards it. Both are good to have on the team.
- eschneider 3y agoI'm not sure why folks think they need to hold all this in their head. For me, at least, the "think about the problem stage" involves a lot of: * Scribbling out some basic design notes. * Figuring out the bits I'm not completely sure about * Maybe coding up some 'prototype' code to prove out the bits I'm less sure about * Repeat until I think I know what I'm doing/validated my assumptions * Put together a 'more formal' design to share with the team. Sometimes my coworkers think of things that I hadn't, so it's not quite a formality. :) * Code the thing up. By the time I get to the "code it up" stage, I've probably put in most of the work. I've written things down as design, but nothing hyperdetailed. Just what I need to remind myself (and my team) of the decisions I've made, what the approach is, the rejected ideas, and what needs doing. Some projects need a fair bit on paper, some don't.
- fennecfoxy 3y agoIt's not even that, it's also the iceberg effect of all our personal knowledge-bases; I'd rather experiment on my machine figuring out how I want to do something rather than read endless documentation. Documentation is a good starter/unblocker but once I've got the basics down then I'll run wild in a REPL or something figuring out exactly how I want to do something. Pure thinking planning is a good way to end up with all sorts of things that weren't factored in, imo. We should always encourage play during the planning process.
- JohnFen 3y ago> writing code should be actually seen as part of the "thinking process" I agree. This is how I work as well. I start coding as quickly as possible, and I fully plan on throwing away my first draft and starting again. I do a fair bit of thinking beforehand, of course, but I also want to get the hidden "gotchas" brought to light as quickly as possible, and often the fastest way is to just start writing the code.
- jmbwell 3y agoI don't get great results myself from diving into coding immediately. I personally get better results if I have some storyboards, workflows, ins/outs, etc. identified and worked-over first. But when I do get down to writing code, it very much takes an evolutionary path. Typically the first thing I start writing is bloated, inefficient, or otherwise suboptimal in a variety of ways. Mostly it's to get the relationships between concepts established and start modeling the process. Once I have something that starts looking like it'll work, then I sort of take the sculptor's approach and start taking away everything that isn't the program I want. So yeah, a fair amount of planning, but the first draft of anything I write, really, code or otherwise, is something for me, myself, to respond to. Then I keep working it over until it wouldn't annoy me if I was someone else picking it up cold.