TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Code the shortest path first

134 pointsby evanlhalmost 2 years ago

33 comments

i-use-nixos-btwalmost 2 years ago
An alternative: Build a PoC first.<p>The reason coding the shortest path first feels better is that you hit milestones early. However, it is a major generator of technical debt, and fleshing out the project is the hard part that takes longer and introduces breaking changes.<p>Taking time to plan, getting the API planned in advance, generalising the code (obviously not TOO much), and so on might feel less rewarding at first, because the early milestones are the hard part. But do it right and you end up seeing everything fall into place in quick succession, according to plan - and that’s a much greater sense of achievement IMO. It is often also a quicker way of seeing large projects to completion, though it doesn’t always feel like it at the time.<p>Building a Proof of Concept allows you to get the best of both worlds. It allows you to be naive, it allows you to write the bare minimum, and it gets something working that others can try out and give feedback on. As a bonus, it doesn’t generate technical debt, because you don’t build on the PoC - you use it as a reference while building the actual thing.
评论 #36518103 未加载
评论 #36518606 未加载
评论 #36523368 未加载
评论 #36522451 未加载
评论 #36519662 未加载
t43562almost 2 years ago
Usually one understands a project poorly at the start and much better at the end.<p>So to agree with the article I think it&#x27;s unwise to make all your decisions at the point where you know the least.<p>By getting something working you improve your understanding and then you can choose optimisations and abstractions in a judicious manner - no point in optimising things that end up having no impact and no point in introducing abstractions that in practice never will be used.<p>There are those who imagine that you can completely plan work before lifting a finger and it&#x27;s a problem to struggle with them sometimes. Another one is when some aspect of the outcome is big in people&#x27;s minds.<p>I was once on a project where we thought we&#x27;d be charging people based on their usage of the product. This made the reporting system very critical because if we messed anything up we&#x27;d be cheating our customers or giving them freebies. In the end we realised nobody wanted to pay that way so this huge design consideration which made everything much more complicated was gone. This sort of pattern happens often and it was a mistake to start that way. But that was a requirements mistake rather than a programming one and this is why your requirements are so critical. A single sentence in a document can double the cost of a project and your customers often don&#x27;t realise that.
评论 #36520043 未加载
评论 #36522756 未加载
kqralmost 2 years ago
There&#x27;s a fine line between shortest path first and most certain path first. It&#x27;s tempting to jump in and do the things you know for sure how they will work – these are the things with the lowest need for exploration. Early-stage, you should focus on the things that are most uncertain, the things that have a chance of dooming the entire project if you don&#x27;t understand them better.<p>You can still take the shortest path while focusing on the most uncertain first, but it is another concern that needs to be prioritised.
评论 #36518689 未加载
Tade0almost 2 years ago
I think this advice is a little vague and therefore easy to get wrong.<p>My approach converged to something that can be understood as a form of progressive enhancement, so basically providing the simplest usable version of a given feature, bearing in mind that eventually you&#x27;ll have to expand it to what was originally requested - but that&#x27;s all in separate tickets.<p>Some examples:<p>Six different payment processors? Start with one or two.<p>SPA frontend? Start with server-rendered. The tech is there to smoothly transition from one to the other, but it&#x27;s possible that this will never be required.<p>That colour picker shaped like a peacock, following the mouse with its gaze? Just use a regular colour picker, but make it easily swappable. Where&#x27;s that in the requirements anyway?<p>What&#x27;s interesting is that more often than not enhancements lose priority in favour of new features.<p>Meanwhile some universal techniques like preferring pure functions where reasonable, using immutable data structures and actually having an architecture take as much time as doing sloppy work and go a long way into ensuring maintainability.
评论 #36519136 未加载
tuukkahalmost 2 years ago
I notice they link to The Pragmatic Programmer here:<p>&gt; <i>If it’s a true greenfield project you are “prototyping”, if it’s part of an existing project you are making a “tracer bullet”.</i><p>In the C2 wiki, someone paraphrases it like this:<p>&gt; <i>In PragmaticProgrammer, they talk about TracerBullets in the context of building an ArchitecturalPrototype - a bare-bones skeleton of your system that is complete enough to hang future pieces of functionality on. It&#x27;s exploratory, but it&#x27;s not really a prototype because you are not planning to throw it away - it will become the foundation of your real system.</i> <a href="https:&#x2F;&#x2F;wiki.c2.com&#x2F;?TracerBullets" rel="nofollow noreferrer">https:&#x2F;&#x2F;wiki.c2.com&#x2F;?TracerBullets</a><p>Wikipedia has a description in the context of Scrum here: <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Scrum_(software_development)#Tracer_bullet" rel="nofollow noreferrer">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Scrum_(software_development)#T...</a><p>Does anyone remember more about what Pragmatic Programmer says about this topic?
评论 #36518653 未加载
agentultraalmost 2 years ago
Prototyping is a wonderful thing we <i>should</i> do more of.<p>However, in my experience, when you take this approach the majority of organizations will make the prototype the product. You will never throw out that code. It will simply be added on to, papered over, and mixed up with everything else. What started off as a fine prototype becomes a error-ridden ball-of-mud that nobody understands anymore. Where working on that code takes longer and longer and carries a higher risk of introducing even more errors.<p>The key thing with prototypes is that you have to mercilessly rip that code out before people start extending it and relying on it otherwise it&#x27;s going to stick around.
评论 #36520459 未加载
评论 #36521256 未加载
评论 #36520415 未加载
lhnzalmost 2 years ago
Maybe I&#x27;m not senior enough, but I think this misses the point. If I&#x27;m not prototyping, I don&#x27;t try to &quot;code the shortest path first&quot;, I try to code using the most popular libraries, and the most concrete, broad-strokes, fundamental abstractions, towards a goal of improving understandability.<p>At the end of the day, most code is deleted anyway. But even then people still need to understand it. I am attempting to write in the &quot;lingua franca&quot; and to make it clear to myself and others what I understand about the problem.
评论 #36518695 未加载
评论 #36518813 未加载
joshdataalmost 2 years ago
This is a similar idea to how I understand the Elephant Carpaccio exercise by Henrik Kniberg &amp; Alistair Cockburn (2013), from what I&#x27;ve been able to Google. The key idea is that work should be broken down into &quot;vertical slices&quot; where vertical means that the entire user story is captured, or as it&#x27;s described at <a href="https:&#x2F;&#x2F;uploads-ssl.webflow.com&#x2F;5e3bed81529ab12a517031ab&#x2F;5ece238ef1473a6416860f46_Elephant_Carpaccio_exercise.pdf" rel="nofollow noreferrer">https:&#x2F;&#x2F;uploads-ssl.webflow.com&#x2F;5e3bed81529ab12a517031ab&#x2F;5ec...</a>, &quot;very thin slices, each one still elephant-shaped.&quot; The first vertical slice might be a mockup or very-low-fidelity prototype of the complete project and subsequent slices are enhancements following user stories. Horizontal slices might be, say, system components or other subtasks that leave you without something prototype-looking until all of the slices are complete. At least, this is how I&#x27;ve interpreted what I&#x27;ve read about it.
评论 #36520924 未加载
评论 #36552017 未加载
jruzalmost 2 years ago
You’re mixing product decisions with code decisions.<p>Product should make sure to create an MVP aka the fastest solution for A-B.<p>Code should be done right no matter what, you’re being paid as an expert to do that, if they would want whatever crappy code gets it done they would do it themselves with some nocode solution and test the hypothesis.
评论 #36518014 未加载
评论 #36518459 未加载
评论 #36518295 未加载
sktrdiealmost 2 years ago
Like with everything in life, I&#x27;ll answer this article with a strikingly &quot;it depends&quot;.<p>What are your business requirements? How much budget do you have? Deadlines? Do you already have a clearly defined audience?<p>If you&#x27;re a company like Figma then dedicating resources to crafting the hell out of the product &amp; pushing the envelope in terms of maintainability, tests, performance &amp; software craftmanship is a must. Probably going directly from A -&gt; B is not scalable.<p>If you&#x27;re a company with 200 costumers and 3 developers then I feel it&#x27;s the opposite. Dedicating time &amp; resources into all those premature optimizations might kill your company.<p>I remember seeing something along the lines of &quot;Over-engineering cited as major cause of product failure. Because it never ships.&quot;
YuukiReyalmost 2 years ago
I 100% agree with this. Whenever I force myself to really, really do the simplest and dumbest thing first it leads to a better outcome.<p>I get to a working version of the feature quicker. From that, I get more insights. Sometimes I even realize that the simple and dumb version is good enough already.<p>I would say that this is the single most efficient rule&#x2F;heuristic I have for making sure my productivity stays high.
gcanyonalmost 2 years ago
I fell deep into this trap just yesterday, solving a Project Euler problem in Python. It involved a 2-million+ digit number. I&#x27;m just starting with Python, and while I know it transparently handles large integers, out of an abundance of caution I spent an hour optimizing to avoid dealing with greater-than-64-bit values, since the result needed is modulo a &lt;64 bit value.<p>My code ran in about 4 seconds.<p>Then I thought I&#x27;d try a slightly larger optimization that involved ~128 bit values. That ran in a second, so obviously the switch to large integers either doesn&#x27;t happen at 64 bits, or Python just handles it really well.<p>Then I thought to just do the math and let Python sort the results. One line of Python. Took ~20 seconds to write. Calculated the 2-million digit number and <i>then</i> did the modulo. Ran in a small fraction of a second. &lt;sigh&gt;
a_calmost 2 years ago
Want to add that the shortest path is only obvious from hindsight. And someone&#x27;s shortest path maybe shorter than yours. Incremental iteration seems all the rage nowadays, but it didn&#x27;t take one&#x27;s taste and experience into account. If one&#x27;s shortest path is long and winded, no amount of iteration will bring you to any sorts of local optima. The ultimate judgement is whether the things you built is getting use. If a tree falls in a forest and no one heard it, it didn&#x27;t make a sound. It doesn&#x27;t matter your code is good or bad. Build a mental map that leads you to building things useful
niruialmost 2 years ago
Based on the context provided through the article, I think what the author actually wanted was a Minimum Viable Product, that is, instead of coding the shortest path first, you remove the need for unnecessary paths (and without cutting corners). This should create a reasonably correct product that is safe to use and easy to build on top of.<p>But I do agree about the CI&#x2F;CD part. In my case however, it&#x27;s because many of these CI&#x2F;CD services uses their own propriety config formats which are unfriendly for local testing. I can&#x27;t remember how much time I&#x27;ve spent on hot-trying Travis CI just to get the build process right. I imagine things could feel a lot different if the services supports NixOS or just Dockerfile based script, because I can at least try the script locally before invoking the online service.
cosmiccatnapalmost 2 years ago
There are so many articles that float through here that can be summed up as &quot;do this, unless you should do that&quot; with a title equivalent to &quot;why you should always do this&quot;<p>Does this article present findings from other projects? Does it have a personal code story? Does it use any data or even antidotal evidence to support it&#x27;s claims.<p>The answer to all of these is NO it does not...it&#x27;s just a half hearted article talking about a fundamental problem in modern programming with no real solutions other that an axe to grind that they can&#x27;t even really elaborate on the origins of.
dt3ftalmost 2 years ago
I built FlingUp following the quickest path and compared to what we build at work.. FlingUp is lightyears ahead. Not held down by mindless patterns, very easy and quick to extend and build upon. Adding 1 new db field at work requires half a day of work until it is available for use on the frontend. The applications at work are so ridiculously overengineered that I sometimes feel we had too much money and time to throw at the codebase, engineers were experimenting and playing with pattern of the month. Maintainability is pretty much gone.
tru1ockalmost 2 years ago
Make it work, make it right, make it fast.<p><a href="https:&#x2F;&#x2F;wiki.c2.com&#x2F;?MakeItWorkMakeItRightMakeItFast" rel="nofollow noreferrer">https:&#x2F;&#x2F;wiki.c2.com&#x2F;?MakeItWorkMakeItRightMakeItFast</a>
shireboyalmost 2 years ago
I get what he’s saying, but definitely several gotchas. The main project I work on these days has code that definitely isn’t the shortest path already checked in to main and running in prod. I’m that guy- set up ci&#x2F;cd, apm, upgraded frameworks, and am working on major refactor. I tell management we can move faster on features and bugfixes if we can reduce the complexity of existing code.<p>But I do struggle with how far to take that. I worry I’m getting too deep and need to focus on features.
koromakalmost 2 years ago
The problem for me is that the shortest path often has <i>nothing</i> to do with the &quot;best&quot; path. Committing to it means you&#x27;re never actually going to get it working right. You&#x27;re going to get a knot in your stomach a year later when edits come down to your crappy MVP feature that feels like shit to work on.
gjvcalmost 2 years ago
A by-product of coding up a working solution is one of <i>better understanding the problem</i>. Unfortunately, this valuable result is invisible to many, and its existence seldom acknowledged. Documentation can serve as a proxy for it, to make it somewhat tangible.
xiphias2almost 2 years ago
This is great, one modification that I would make is to add CI&#x2F;CD and testing when there&#x27;s a regression that was not expected, or when it makes development simpler. That way I don&#x27;t have to think about the ,,right time&#x27;&#x27; to introduce these.
nickelproalmost 2 years ago
I agree with the sentiment but not the examples:<p>&gt; spend days setting up a CI&#x2F;CD pipeline<p>This should&#x2F;does take minutes. It&#x27;s like 15 lines of YAML for most CI providers. Ideally it&#x27;s a part of the template you use for new code.<p>&gt; use a cool new library they just found<p>Integrating a useful lib that makes the code simpler should be done from day 1. Don&#x27;t code your own platform lib and switch to SDL halfway through development. Don&#x27;t code your &quot;tracer bullet&quot; on Win32 API calls when you&#x27;re going to be using libuv. And like CI&#x2F;CD, integrating libraries into the build should be painless<p>&gt; if it’s software that’s going to ship, it needs tests<p>Oftentimes the tests are the only way you know if the code is even minimum viable, even manages to be the &quot;tracer bullet&quot;. Ok you implemented a new feature, what says the code even runs and doesn&#x27;t segfault immediately if there&#x27;s not a test to build the new code into and run? Not comprehensive tests, but <i>something</i>
评论 #36518802 未加载
sumanthvepaalmost 2 years ago
This is excellent advice. I would only modify it to say that one should first focus on getting something working, not necessarily the shortest path Then you can refactor and improve the code before you actually deploy it to production.
m3kw9almost 2 years ago
Yeah the over optimize before getting the proof of concept&#x2F;getting it working minimally should always be recognized as gambling, as the n you may lose all that optimization if the stuff doesn’t work with it down the line
heisenbitalmost 2 years ago
It reminds me of Go (not the language). Beginners play straight lines, then one learns fancy moves and complicates everything while high ranked players patterns again exhibit straighter simpler forms.
roflyearalmost 2 years ago
I like &quot;throw away your first solution&quot; or &quot;be prepared to throw away your first solution.&quot;<p>And the difference between a senior dev and a junior dev is knowing when to stop.
urauraalmost 2 years ago
Recently I ask ChatGPT to do that. I become the one to improve it.
ankaAralmost 2 years ago
While reading I was thinking of Dan Harmon&#x27;s about writing.<p>It is the same.<p>Just write&#x2F;code then, when the thing is done, start the reviewing stage.<p>Anyway, you never know everything about your project when you start it.
baseballpuckalmost 2 years ago
This is a balancing act. Spending the time later to undo all of the technical debt accumulated can take even longer.
评论 #36479101 未加载
评论 #36517970 未加载
hkonalmost 2 years ago
For sideprojects, definitely, there is simply not enough time otherwise.
评论 #36519847 未加载
Kalanosalmost 2 years ago
be agile? haha. I refer to this as punching a hole all the way through and then pull the rest through. punch + pull.
herval11almost 2 years ago
Once you become super senior you actually realize what the author said here is not completely correct. This guy has experience, but he hasn&#x27;t reached nirvana.<p>There is a singular high level design pattern&#x2F;abstraction that you can use in actuality to start off your projects.<p>There is no name for this pattern but it is essentially this:<p>Segregate io and mutations away from pure functions. Write your code in modular components such that all your logic is in pure functions and all your io and mutations are in other modules.<p>Why does this style of organization work? Because delineation and organization of every form of application you can think of benefits from breaking out your program organization along this pattern.<p>Your pure functions will be the most modular, reusable, and testable. You will rarely need to rearchitect logic in pure functions... Instead typically you write new modules and rearrange core functions and recompose them in different ways with newly added pure functions to get from A to B.<p>The errors and organizational mistakes will happen at the io layer. Those functions likely need to be replaced&#x2F;overhauled. It&#x27;s inevitable. Exactly like the author says this section of your program is the most experimental because you are exploring a new technological space.<p>But the thing is you segregated this away from all your pure logic. So then you&#x27;re good. You can modify this section of your project and it remains entirely separate from your pure logic.<p>This pattern has several side effects. One side effect is it automatically makes your code highly unit testable. All pure functions are easily unit tested.<p>The second side effect is that it maximizes the modularity of your program. This sort of programming nirvana where you search for the right abstraction such that all your code reaches maximum reusability and refractors simply involve moving around and recomposing core logic modules is reached with pure functions as your core abstraction primitive.<p>You&#x27;re not going to find this pattern listed in a blog post or anything like that. It&#x27;s not well known. A software engineer gains this knowledge through experience and luck. You have to stumble on this pattern in order to know it. Senior engineers as a result can spend years following the hack first philosophy in the blog post without ever knowing about a heavy abstraction that can be reused in every single context.<p>If you don&#x27;t believe me. Try it. Try some project that segregates logic away from IO. You will indeed find that most of your edits and reorganization of the logic happens with things that touch io. Your pure logic remains untouched and can even be reused in completely different projects as well!
评论 #36527134 未加载
000ooo000almost 2 years ago
tl;dr: long form version of &quot;make it work, then make it pretty&quot;
评论 #36518023 未加载