6 ms·
Yes, abstraction and generalization are properties you'd rather look for the second time around. Someone was already warning about this 25 years ago [1]: You h
by astrobe_ 2y ago
Yes, abstraction and generalization are properties you'd rather look for the second time around. Someone was already warning about this 25 years ago [1]:
You have a boring problem and hiding behind it is a much more interesting problem. So you code the more interesting problem and the one you've got is a subset of it and it falls out trivial. But of course you wrote ten times as much code as you needed to solve the problem that you actually had.
Ten times code means ten times cost; the cost of writing it, the cost of documenting it, it the cost of storing it in memory, the cost of storing it on disk, the cost of compiling it, the cost of loading it, everything you do will be ten times as expensive as it needed to be. Actually worse than that because complexity increases exponentially.
This person did his own CAD software from scratch in order to make custom chips [2].
[1] https://www.ultratechnology.com/1xforth.htm https://www.ultratechnology.com/1xforth.htm
[2] https://en.wikipedia.org/wiki/Charles_H._Moore https://en.wikipedia.org/wiki/Charles_H._Moore
- zelphirkalt 2y agoAlthough of course solving the abstract problem does not have to be 10 times as much code. The best solutions are often those, that recognize the more general problem, solve it with little and elegant code, then turn to the specific problem, expressing it in terms of the abstract problem and thereby solving it in just a few lines of code. Such an approach should usually be accompanied by some documentation. To give a trivial example: Binary search or any other bog standard algorithm. You would want to have an implementation for the algorithm and named as such and then only apply it in the specific case you have. Sorting algorithms. You don't want to rewrite it all the time. Actually rewriting it all the time would be the thing that creates "10 times" the code.
- mattmanser 2y agoNo. Just no. This is the exact thought process that leads to unnecessary abstraction. This is the attitude that the article is criticizing. A good rule of thumb is never abstract unless you genuinely have done the same thing twice already. i.e. only write an abstraction after you've written the boring, simple, concrete, implementation twice and are about to write it a third time.
- jcelerier 2y agoAt no point in my life my code has been made worse because I've used an existing sort function instead of writing a buggy one
- SleepyMyroslav 2y agoIf we ignore 'buggy' part I think you projecting current good state back into not so good old times. I am pretty sure you will not replace radix sort that uses domain knowledge of reduced value range with qsort circa C++98. Things became much better after relatively recent improvements in generalist sorting libraries: when pattern defeating quick sort variants became norm, when mostly sorted cases got covered ... Tbh I do have a case from 2013-16 when I regret not doing it for one AAA project on ps4.
- xtracto 2y agoI am wondering where the "generalize code after doing it for the 3rd time" rule of thumb comes from? I also subscribe to it, and read it somewhere 15/20 years ago. Was it the Mythical Man Month book Maybe?
- laserlight 2y agoSee the C2 Wiki article: https://wiki.c2.com/?ThreeStrikesAndYouRefactor https://wiki.c2.com/?ThreeStrikesAndYouRefactor
- 0x696C6961 2y agoThe rule of three should obviously not be applied to well known data structures and algorithms ...
- II2II 2y agoWell known data structures and algorithms are well know because they have been used more than three times. That said: if you are dealing with a situation where you have to implement them yourself, you may want to consider whether the rule of three applies. (Clearly this depends upon the situation.)
- fnqi8ckfek 2y ago[dead]
- dustingetz 2y agoimo more like the 50th time around, and by a computer scientist, and not on company time until after the abstraction POC is validated, for example both React and Angular were side projects before the firm decided to invest. Software development outcomes today are driven by: ignorance, narcissism, and self preservation
- Sesse__ 2y agoHave you ever looked at how useless Chuck Moore's stuff is? Like, the chip designs are of the type “384 independent Forth chips with tiny amounts of RAM and mediocre interconnects, and if you want to actually do anything with them, you'll need to use 128 of them to program your own DDR3 controller”. Or, he demonstrates how awesome Forth is by showing that you can do “the guts of a disk driver” in five lines, except that it's the dog-slow PIO mode. It turns out that if you can just change the problem statement, then sure, you can write very simple things. But if you have a real problem to solve (and you can't just say “no, I want to solve a simpler problem”), the Chuck Moore way of thinking doesn't really produce, well, good solutions. It simply doesn't scale to anything large, and not everything can be made small. https://yosefk.com/blog/my-history-with-forth-stack-machines.html https://yosefk.com/blog/my-history-with-forth-stack-machines... (2010) is a fairly interesting experience from someone on the outside trying to work in the same way. It… didn't work that well.
- astrobe_ 2y ago> Have you ever looked at how useless Chuck Moore's stuff is? I've seen someone well known in the Forth community say something like that to Chuck. I think he said "what can I do with that?" If GA144 is useless, it's only because it has not been put to good use, in my opinion. I think it was more-or-less his answer too, IIRC. I work with system-on-chip or system-on-modules. You know, the ARM-based chips with tons of peripherals. I also worked with similar chips before the ARM era. The complexity of these chips is as of today, absurd. I/O is multiplexed to make the chip usable for various things, but one has to configure all of them and watch out for conflicts. Then there's also zillions of configurable clocks in order to reduce the power consumption. Solutions to problems that spawn new problems, not in the "divide and conquer" style, unfortunately. This resulted in "device tree" configuration in Linux, a runtime configuration system, because CPU companies excrete a new variant every week. Maybe I fool myself, but I can see a GA144 bit-banging IRDA, LCD, SPI, etc. in a much more efficient and flexible way. > (2010) is a fairly interesting experience from someone on the outside trying to work in the same way. It… didn't work that well. And here in 2025 there's still Forth-based companies alive, like MPE or Forth, Inc. More specifically, this author writes, [...] it was harder than we thought. Presumably that was partly the result of not reading "Stack Computers: the new wave", and not studying the chip designs of Forth's creator Chuck Moore, either. I have a feeling that knowledgable people would have sneered at this machine: it was trivial to compile Forth to it, but at the cost of complicating the hardware. Implementing a stack-based processor without reading the literature on them is a bit foolish, don't you think? The rest is in the same vein; I can see why a person who was essentially a Forth newbie had a bad experience with this kind of project. If this article "debunks" Forth, it is by showing that just because something it is simple, doesn't mean it is easy. Because the world is not simple and simplifying is much harder than let Complexity loose.
- Izkata 2y agoWhile I generally agree with that, the problem is teams, mixes of skill levels, and future time constraints. There's no guarantee the person doing the second implementation knows about the first one, realizes they can be pulled into a better abstraction, or has the time to do it. On the flipside, it's possible the other person (or the first person with more experience) comes up with something better than the first possible version of abstraction. So it ends up being a trade-off you have to decide on at the start, rather than a simple rule, based on team experience and how big (or small [0]) the abstraction actually us. [0] https://www.folklore.org/Negative_2000_Lines_Of_Code.html https://www.folklore.org/Negative_2000_Lines_Of_Code.html
- JoeAltmaier 2y agoTen times? Foo. Maybe double. But that's still twice the cost, for only a potential win. Better check first that it helps somebody write better/more correct/quicker code. E.g. we wanted to change our text-screen video driver to allow a full-screen overlay (many years ago). The programmer assigned the task was changing the text-blit code to know about certain lines on the screen that were going to be the 'nested' window, which could be 'up' and masking a subset of the window below, or 'down' and the full screen should be displayed as normal. He'd been hacking away, changing every case in the code to 'know about' the particular window that was planned. Pulling his hair out, getting nowhere. I suggested a simple indirection buffer, where each line of a virtual display was pointed to indirectly. To put the subwindow 'up' or 'down' you just pointed those lines of the main screen to a buffer, and pointed the lines of the subwindow to the hardware store for video text. All his changes folded into 'access display indirectly'. Trivial. Then the up/down code became a loop that changed a pointer and copied some text. That was actually an abstraction, and actually much shorter/faster/simpler to understand and change. Later we could change the window dimensions, have multiple windows etc with no change to the video driver.