The square roots of all evil
neilmadden.blog
neilmadden.blog
The fact that everyone uses his premature optimization is the root of evil remark is hilarious to me. The level of optimization in Knuths writing makes it evident that upfront efficiency effort is worthwhile. Just don't overdo it.
But don't trust me on that quote. Just open book 3 (chapter 5 and 6, sorting and searching) and go read the tape drive simulations of merge sort yourself. You can't miss the printouts, they're huge.
Fixed that for you.
If communism takes over the world and be given 30 years half the texts wouldnt make sense as it talks about something to do with capitalism? that doesnt exist.
The Y2K “problem” gives the canonical example. In a world of vast and very cheap and fast storage, it makes no sense to save two characters in a date. But back in the ‘70s and early ‘80s when I implemented dates like that cutting those two characters over a few million records saved significant money. Disk space used to cost a lot, RAM (or core memory) used to cost a lot more.
Knuth did not have that in mind when he wrote about premature optimization.
Just look into Gosper's hack someday and tell me that that would pass most reviews? (Which, I think is probably unfair? But I can't imagine many places being good with using standard int variables to represent subsets.)
also, great story:
It's "The Art of Computer Programming", volume 3 (Sorting and searching) by Donald Knuth. HTH
That is…not a great answer, unless you want to reinforce the meme that CS is a cult. Besides, the context you mention is utterly alien to millions of people.
People get born every day, and people learn the basics every day. We should be helping them grow, not gatekeeping. Your second sentence was more than enough.
Knuth's work wasn't part of my programming curriculum in an engineering program, either.
Or Basic Internet Search News.
This does a lot to find pragmatic tradeoffs between performance and abstraction. It also pushes you away from the over-abstraction that leads to the Second System Effect, as coined by The Mythical Man-Month.
If you have three distinct examples, and you need to do something that requires a fourth, you won’t be able to justify spending time writing an abstraction. You should just copy it again. The three existing examples don’t use an abstraction, and they work just fine, so there’s clearly no need for an abstraction… or so the argument goes. In the unlikely event that you’re allowed to write the abstraction, you definitely won’t be allowed to reimplement the existing examples to use it now, because those modules are not in scope and we don’t have the budget to test them again.
If you don’t create the abstraction up front, you’ve lost the chance to have an abstraction.
It's not the only way of working, but it tends to suit the challenges faced by very large teams with high turnover, diffuse/negligent code ownership, many juniors/early-career contributors, and low trust.
It also produces software that resembles papier maché -- increasingly thick, disordered, and glutinous, with poor visibility and low durability.
If your team isn't subject to the challenges that make papier maché coding necessary, encourage people to escape its cargo cult. Small teams of people who trust each other, where code has long-term owners who can speak to its purpose and direction, can dynamically sculpt and rework code more like clay. And you get better software when that can be done.
If you end up having a poorly fitting abstraction, then you'll be spending extra effort on doing things "properly", but not really getting any benefit out of it. You just loose the agility of hacking things quick'n'dirty, or you end up hacking around the bad abstraction, and get worst of both worlds.
The rest depends on having management that understands trade-offs between doing things properly and efficiently long-term vs getting stuff out of the door quickly (if you're a startup with a short runway, or racing to be the first to win some opportunity, shipping ugly hacks now may be the only way to survive to even have "later" to worry about).
That may be true, but it’s still a problem if you can never create new abstractions, because that prevents you from creating good abstractions too, not just bad ones.
If you need to repeat yourself, first copy and paste. If you need to a third time, then you can pull it into a function to generalize.
But like nearly everything with programming, hard and fast rules are bad, but it’s a good rule of thumb
The One created the Two
The Two created the Three
The Three created the Ten Thousand Things
Chapter 42 of the Daodejing
The Second System Effect has nothing to do with over-abstraction of code - it has nothing to do with code at all. The basic premise is:
First System: We barely did anything we dreamed of and can see 100s of ways to improve things, but we had to get something to market.
Second System: We’ve learned so much! Revenue enables big picture thinking! Everything we ever dreamed of let’s design and build!
It’s fundamentally a mistake at a business/product design level. That feeling of success leads to a release of constraints and then trying to bite off far more than can be chewed.
The fact that the business mistakes are easiest to spot from outside doesn't mean that the coding mistakes aren't there. Even though that level of detail is only visible from inside of the system.
https://en.wikipedia.org/wiki/Cyc
I'm also surprised that they didn't clarify that the true square root of all evil is 25.8069758011.
Square root of 216 or 6 x 6 x 6.
Ah yes, 665.99999999856098676121, such evil! :P
interface ILoadData<In, Out> {
Out Get(In input);
}So essentially this says that to implement this interface you must have a function that takes in something (you decide!) and outputs something (you decide!) and it's called Get. Totally useless.
1. A fear that it won't be possible to alter the program later based on better use-case information. (Sometimes justified, sometimes not.)
2. Excitement, engagement, and the ego-trip of Making A Cool Solution.
Part of the reason I prefer languages with strong static checking is that it makes those kinds of (1) rewrites easier to do.
It shares the same mindset as the saying: Fail to prepare is prepare to fail !
The challenges and the evils is in the details of the process of optimization, not that premature optimization is evil.
The article suggests that premature specialization and premature generalization might, instead, be the root of all evil. Really!
Well-written.
Often I see people criticise some project for being overly generalised or "over-engineered" simply because they don't have as full a picture as the project's maintainers.
opener(ender(mcts(ender(ply1(pieces+squares,temperature=25))
the goal is minimum code not through code golf but by design by composition.I personally have not seen premature optimization, but I may have led a charmed life.
Premature optimization is something I struggle with - "hey, if I do this a different way it'll be faster/smaller!" And then I end up spending too much time optimizing one data area of code when I should just do it the easy way and move on to the next problem. I can always come back and optimize later when everything is working and I can see where the problem areas are, but the temptation is often hard to fight.
Premature abstraction is harder because abstracting existing code can be problematic and there's more of a chance to introduce bugs. It takes intuition and planning to get it right the first time around, and by the time you realize you should have abstracted something it's often too late to fix without rewriting a large chunk of your code and your teammates' code.