[HN Gopher] Rob Pike's Rules of Programming (1989)
       ___________________________________________________________________
        
       Rob Pike's Rules of Programming (1989)
        
       Author : vismit2000
       Score  : 798 points
       Date   : 2026-03-18 09:59 UTC (13 hours ago)
        
 (HTM) web link (www.cs.unc.edu)
 (TXT) w3m dump (www.cs.unc.edu)
        
       | embedding-shape wrote:
       | "Epigrams in Programming" by Alan J. Perlis has a lot more, if
       | you like short snippets of wisdom :)
       | https://www.cs.yale.edu/homes/perlis-alan/quotes.html
       | 
       | > Rule 5. Data dominates. If you've chosen the right data
       | structures and organized things well, the algorithms will almost
       | always be self-evident. Data structures, not algorithms, are
       | central to programming.
       | 
       | Always preferred Perlis' version, that might be slightly over-
       | used in functional programming to justify all kinds of hijinks,
       | but with some nuance works out really well in practice:
       | 
       | > 9. It is better to have 100 functions operate on one data
       | structure than 10 functions on 10 data structures.
        
         | Intermernet wrote:
         | I believe the actual quote is:
         | 
         | "Show me your flowchart and conceal your tables, and I shall
         | continue to be mystified. Show me your tables, and I won't
         | usually need your flowchart; it'll be obvious." -- Fred Brooks,
         | The Mythical Man Month (1975)
        
           | bfivyvysj wrote:
           | This is the biggest issue I see with AI driven development.
           | The data structures are incredibly naive. Yes it's easy to
           | steer them in a different direction but that comes at a long
           | term cost. The further you move from naive the more often you
           | will need to resteer downstream and no amount of context
           | management will help you, it is fighting against the literal
           | mean.
        
             | andsoitis wrote:
             | > This is the biggest issue I see with AI driven
             | development. The data structures are incredibly naive.
             | 
             | Bill Gates, for example, always advocated for thinking
             | through the entire program design and data structures
             | before writing any code, emphasizing that structure is
             | crucial to success.
        
               | neocron wrote:
               | Ah Bill Gates, the epitome of good software
        
               | dotancohen wrote:
               | Yes, actually. Gates wrote great software.
               | 
               | Microsoft is another story.
        
               | jll29 wrote:
               | And Paul Allen wrote a whole Altair emulator so that they
               | could use an (academic) Harvard computer for their little
               | (commercial) project and test/run Bill Gates' BASIC
               | interpreter on it.
        
               | andsoitis wrote:
               | > Ah Bill Gates, the epitome of good software
               | 
               | While developing Altair BASIC, his choice of data
               | structures and algorithms enabled him to fit the code
               | into just 4 kilobytes.
        
               | PaulDavisThe1st wrote:
               | I'd like to see Gates or anyone else do that for a
               | project that lasts (at least) a quarter century and sees
               | a many-fold increase in CPU speed, RAM availability, disk
               | capacity etc.
        
             | Intermernet wrote:
             | Naive doesn't mean bad. 99% of software can be written with
             | understood, well documented data structures. One of the
             | problems with ai is that it allows people to create
             | software without understanding the trade offs of certain
             | data structures, algorithms and more fundamental hardware
             | management strategies.
             | 
             | You don't need to be able to pass a leet code interview,
             | but you should know about big O complexity, you should be
             | able to work out if a linked list is better than an array,
             | you should be able to program a trie, and you should be at
             | least aware of concepts like cache coherence / locality.
             | You don't need to be an expert, but these are realities of
             | the way software and hardware work. They're also not super
             | complex to gain a working knowledge of, and various LLMs
             | are probably a really good way to gain that knowledge.
        
             | dotancohen wrote:
             | Then don't let the AI write the data structures. I don't. I
             | usually don't even let the AI write the class or method
             | names. I give it a skeleton application and let it fill in
             | the code. Works great, and I retain knowledge of how the
             | application works.
        
             | nostrademons wrote:
             | The rule may not hold with AI driven development. The rule
             | exists because it's expensive to rewrite code that depends
             | on a given data structure arrangement, and so programmers
             | usually resort to hacks (eg. writing translation layers or
             | views & traversals of the data) so they can work with a
             | more convenient data structure with functionality that's
             | written later. If writing code becomes free, the AI will
             | just rewrite the whole program to fit the new requirements.
             | 
             | This is what I've observed with using AI on relatively
             | small (~1000 line) programs. When I add a requirement that
             | requires a different data structure, Claude will happily
             | move to the new optimal data structure, and rewrite
             | literally everything accordingly.
             | 
             | I've heard that it gets dicier when you have source files
             | that are 30K-40K lines and programs that are in the
             | million+ line range. My reports have reported that Gemini
             | falls down badly in this case, because the source file
             | blows the context window. But even then, they've also
             | reported that you can make progress by asking Gemini to
             | come up with the new _design_ , and then asking it to come
             | up with a list of modules that depend upon the old
             | structure, and then asking it to write a shim layer module-
             | by-module to have the old code use the new data structure,
             | and then have it replace the old data structure with the
             | new one, and then have it remove the shim layer and rewrite
             | the code of each module to natively use the new data
             | structure. Basically, babysit it through the same
             | refactoring that an experienced programmer would use to do
             | a large-scale refactoring in a million+ line codebase, but
             | have the AI rewrite modules in 5 minutes that would take a
             | programmer 5 weeks.
        
           | mock-possum wrote:
           | I'm really going to need to see both. There's a lot of
           | business logic that simply is not encoded in a data storage
           | model.
        
         | mosura wrote:
         | Perlis is just wrong in that way academics so often are.
         | 
         | Pike is right.
        
           | Intermernet wrote:
           | Hang on, they mostly agree with each other. I've spoken to
           | Rob Pike a few times and I never heard him call out Perlis as
           | being wrong. On this particular point, Perlis and Pike are
           | both extending an existing idea put forward by Fred Brooks.
        
             | mosura wrote:
             | Perlis absolutely is not saying the same thing, and as the
             | commenter notes the functional community interpret it in a
             | particularly extreme way.
             | 
             | I would guess Pike is simply wise enough not to get
             | involved in such arguments.
        
           | jacquesm wrote:
           | Perlis is right in the way that academics so often are and
           | Pike is right in the way that practitioners often are. They
           | also happen to be in rough agreement on this, unsurprisingly
           | so.
        
           | hrmtst93837 wrote:
           | Treating either as gospel is lazy, Perlis was pushing back on
           | dogma and Pike on theory, while legacy code makes both look
           | cleaner on paper.
        
           | AnimalMuppet wrote:
           | Could you be more specific?
        
             | mosura wrote:
             | Promoting the idea of one data structure with many
             | functions contradicts:
             | 
             | "If you've chosen the right data structures and organized
             | things well, the algorithms will almost always be self-
             | evident."
             | 
             | And:
             | 
             | "Use simple algorithms as well as simple data structures."
             | 
             | A data structure general enough to solve enough problems to
             | be meaningful will either be poorly suited to some problems
             | or have complex algorithms for those problems, or both.
             | 
             | There are reasons we don't all use graph databases or
             | triple stores, and rely on abstractions over our byte
             | arrays.
        
               | AnimalMuppet wrote:
               | I think you are badly misinterpreting the statement.
               | 
               | Let's say you're working for the DMV on a program for
               | driver's licenses. The idea is to use one structure for
               | driver's license data, as opposed to using one structure
               | for _new_ driver 's licenses, a different one for
               | renewals, and yet a third for expired ones, and a fourth
               | one for name changes.
               | 
               | It is _not_ saying that you should use byte arrays for
               | driver 's license records, so that you can use the same
               | data structure for driver's license data and missile
               | tracks. Generalize _within_ your program, not across all
               | possible programs running on all computers.
        
               | mosura wrote:
               | Your admittedly exaggerated example is arguing against
               | the entire concept of relational databases, which is not
               | a winning proposition.
               | 
               | You do not write programs with one map of id to thing as
               | you are suggesting here.
        
         | rsav wrote:
         | There's also:
         | 
         | >I will, in fact, claim that the difference between a bad
         | programmer and a good one is whether he considers his code or
         | his data structures more important. Bad programmers worry about
         | the code. Good programmers worry about data structures and
         | their relationships.
         | 
         | -- Linus Torvalds
        
           | mikepurvis wrote:
           | I think this is sometimes a barrier to getting started for
           | me. I know that I need to explore the data structure design
           | in the context of the code that will interact with it and
           | some of that code will be thrown out as the data structure
           | becomes more clear, but still it can be hard to get off the
           | ground when me gut instinct is that the data design isn't
           | right.
           | 
           | This kind of exploration can be a really positive use case
           | for AI I think, like show me a sketch of this design vs that
           | design and let's compare them together.
        
             | ignoramous wrote:
             | > _This kind of exploration can be a really positive use
             | case for AI I think_
             | 
             | Not sure if SoTA codegen models are capable of navigating
             | design space and coming up with optimal solutions. Like for
             | cybersecurity, may be specialized models (like DeepMind's
             | _Sec-Gemini_ ), if there are any, might?
             | 
             | I reckon, a programmer who already has learnt about /
             | explored the design space, will be able to prompt more
             | pointedly and evaluate the output qualitatively.
             | 
             | > _sometimes a barrier to getting started for me_
             | 
             | Plenty _great_ books on the topic (:
             | 
             |  _Algorithms + Data Structures = Programs_ (1976), https://
             | en.wikipedia.org/wiki/Algorithms_%2B_Data_Structures...
        
               | mikepurvis wrote:
               | Yeah key word is exploration. It's not "hey Claude write
               | the design doc for me" but rather, here's two possible
               | directions for how to structure my solution, help me
               | sketch each out a bit further so that I can get a better
               | sense what roadblocks I may hit 50-100 hours into
               | implementation when the cost of changing course is far
               | greater.
        
             | sph wrote:
             | AI is terrible for this.
             | 
             | My recommendation is to truly learn a functional language
             | and apply it to a real world product. Then you'll learn how
             | to think about data, in its pure state, and how it is
             | transformed to get from point A to point B. These lessons
             | will make for much cleaner design that will be applicable
             | to imperative languages as well.
             | 
             | Or learn C where you do not have the luxury of using high-
             | level crutches.
        
           | sph wrote:
           | From what I understand from the vibe coders, they tell a
           | machine what the code should do, but not how it should do it.
           | They leave the important decisions (the shape of data) to an
           | LLM and thus run afoul of this, which is gonna bite them in
           | the ass eventually.
        
           | Zamicol wrote:
           | That is excellent. I'm putting that in my notes.
        
           | aleph_minus_one wrote:
           | > >I will, in fact, claim that the difference between a bad
           | programmer and a good one is whether he considers his code or
           | his data structures more important. Bad programmers worry
           | about the code. Good programmers worry about data structures
           | and their relationships.
           | 
           | > -- Linus Torvalds
           | 
           | What about programmers
           | 
           | - for whom the code _is_ a data structure?
           | 
           | - who formulate their data structures in a way (e.g. in a
           | very powerful type system) such that all the data structures
           | _are_ code?
           | 
           | - who invent a completely novel way of thinking about
           | computer programs such that in this paradigm _both_ code and
           | data structures are just trivial special cases of some mind-
           | blowing concept z of which there exist other special cases
           | that are useful to write powerful programs, but these special
           | cases are completely alien from anything that could be called
           | "code" or "data (structures)", i.e. these programmers don't
           | think/worry about code or data structures, but about z?
        
         | mpalmer wrote:
         | Was the "J" short for "Cassandra"?                   When
         | someone says "I want a programming language in which I need
         | only say what I wish done," give him a lollipop.
        
         | Hendrikto wrote:
         | I feel like these are far more vague and less actionable than
         | the 5 Pike rules.
        
         | DaleBiagio wrote:
         | " 9. It is better to have 100 functions operate on one data
         | structure than 10 functions on 10 data structures."
         | 
         | That's great
        
         | mchaver wrote:
         | I find languages like Haskell, ReScript/OCaml to work really
         | well for CRUD applications because they push you to think about
         | your data and types first. Then you think about the
         | transformations you want to make on the data via functions.
         | When looking at new code I usually look for the types first,
         | specifically what is getting stored and read.
        
           | embedding-shape wrote:
           | Similarly, that approach works really well in Clojure too,
           | albeit with a lot less concern for types, but the "data and
           | data structures first" principle is widespread in the
           | ecosystem.
        
             | mchaver wrote:
             | I've heard good things about Clojure, and it'ss different
             | from what I am used to (bonus points because I like an
             | intellectual challenge), so trying it out is definitely on
             | my todo list.
        
         | linhns wrote:
         | Nice to see Perlis mentioned once in a while. Reading SICP
         | again, still learning new things.
        
           | WillAdams wrote:
           | There is a matching video series for SICP:
           | 
           | https://ocw.mit.edu/courses/6-001-structure-and-
           | interpretati...
           | 
           | which I found very helpful in (finally) managing to get
           | through that entire text (and do all the exercises).
        
         | 0xpgm wrote:
         | Reminded me of this thread between Alan Kay and Rich Hickey
         | where Alan Kay thinks "data" is a bad idea.
         | 
         | My interpretation of his point of view is that what you need is
         | a process/interpreter/live object that 'explains' the data.
         | 
         | https://news.ycombinator.com/item?id=11945722
         | 
         | EDIT: He writes more about it in Quora. In brief, he says it is
         | 'meaning', not 'data' that is central to programming.
         | 
         | https://qr.ae/pCVB9m
        
           | christophilus wrote:
           | I'm with Rich Hickey on this one, though I generally prefer
           | my data be statically typed.
        
             | 0xpgm wrote:
             | Sure, static typing adds some sort of process that provides
             | a coarse interpretation of the data.
        
           | johnmaguire wrote:
           | Hm, not sure. Data on its own (say, a string of numbers)
           | might be meaningless - but structured data? Sure, there may
           | be ambiguity but well-structured data generally ought to have
           | a clear/obvious interpretation. This is the whole idea of
           | nailing your data structures.
        
             | 0xpgm wrote:
             | Yeah, structured data implies some processing on raw data
             | to improve its meaning. Alan Kay seems to want to push this
             | idea to encapsulate data with rich behaviour.
        
           | gregw2 wrote:
           | Thanks for the pointer to this 2016 dialog!
           | 
           | One part of it has interesting new resonance in the era of
           | agentic LLMs:
           | 
           |  _alankay on June 21, 2016 | root | parent | next [-]
           | 
           | This is why "the objects of the future" have to be
           | ambassadors that can negotiate with other objects they've
           | never seen. Think about this as one of the consequences of
           | massive scaling ... _
           | 
           | Nowdays rather than the methods associated with data objects,
           | we are dealing with "context" and "prompts".
        
             | 0xpgm wrote:
             | Quite a nice insight there!
             | 
             | I should probably be thinking more in this direction.
        
         | JanisErdmanis wrote:
         | With 100 functions and one datastructure it is almost as
         | programming with a global variables where new instance is
         | equivalent to a new process. Doesn't seem like a good rule to
         | follow.
        
           | embedding-shape wrote:
           | The scope of where that data structure or functions are
           | available is a different concern though, "100 functions + 1
           | data structure" doesn't require globals or private, it's a
           | separate thing.
        
             | JanisErdmanis wrote:
             | One can always look as global variables equivalent to a
             | context object that's is passed in every function. It's
             | just a syntactic difference whether one constructs such
             | data structure or uses it implicitly via globals.
             | 
             | What I am getting at is that when one has such gigantic
             | data structure there is no separation of concerns.
        
               | CyberDildonics wrote:
               | Does one need one's separation of concerns if one's
               | concerns shouldn't be separated in the in the first
               | place?
               | 
               | Anytime one has access to a database one has access to
               | one large global data structure that one can access from
               | anywhere is a program.
               | 
               | This same concept goes for one's global state in one's
               | game if one is making a game.
        
               | JanisErdmanis wrote:
               | Separation of concerns is still a valid paradigm with a
               | single global datastructure like GUI, Microservice,
               | Database and etc. In such situation one can still
               | seperate concerns via composing the global datastructure
               | from a smaller units and define methods with respect to
               | thoose smaller units. In that way one does not need to
               | wonder whether there are some unattended side effects
               | when calling a function that mutates the state.
        
               | CyberDildonics wrote:
               | Seems like one is backpedaling because one was just
               | talking about one's separation of one's concerns and now
               | one is defending one's separation of concerns with
               | respect to one's global data structure.
        
               | JanisErdmanis wrote:
               | I still firmly believe that one ctx object and hundred
               | functions/methods is as bad as programming with plain
               | variables defined in the global scope. If the ctx is
               | composed from smaller data structures with whom the
               | functions are defined, then all is good. This is the
               | opposite of the rule.
        
               | CyberDildonics wrote:
               | But why?
               | 
               | You keep saying you believe it, but that is literally
               | what a database is, game state manipulation, string
               | manipulation, iterator algorithms, list comprehensions,
               | range algorithms, image manipulations, etc. These are all
               | instances where you use the same data structures over and
               | over with as many algorithms and functions and you need.
        
         | alberto-m wrote:
         | This quote from "Dive into Python" when I was a fresh graduate
         | was one of the most impacting lines I ever read in a
         | programming book.
         | 
         | > Busywork code is not important. Data is important. And data
         | is not difficult. It's only data. If you have too much, filter
         | it. If it's not what you want, map it. Focus on the data; leave
         | the busywork behind.
        
         | bandrami wrote:
         | Also basically everything DHH ever said (I stopped using Rails
         | 15 years ago but just defining data relationships in YAML and
         | typing a single command to get a functioning website and
         | database was in fact pretty cool in the oughts).
        
         | Pxtl wrote:
         | As much as relational DBs have held back enterprise software
         | for a very long time by being so conservative in their
         | development, the fact that they force you to put this
         | relationship absolutely front-of-mind is _excellent_.
        
           | embedding-shape wrote:
           | I'd personally consider "persistence" AKA "how to store shit"
           | to be a very different concern compared to the data
           | structures that you use in the program. Ideally, your design
           | shouldn't care about how things are stores, unless there is a
           | particular concern for how fast things read/writes.
        
             | mosura wrote:
             | Often significant improvements to every aspect of a system
             | that interacts with a database can be made by proper design
             | of the primary keys, instead of the generic id way too many
             | people jump to.
             | 
             | The key difficulty is identifying what these are is far
             | from obvious upfront, and so often an index appears
             | adjacent to a table that represents what the table should
             | have been in the first place.
        
               | embedding-shape wrote:
               | I guess that might be true also, to some extent. I guess
               | most of the times I've seen something "messy" in software
               | design, it's almost always about domain code being made
               | overly complicated compared to what it has to do, and
               | almost never about "how does this domain data gets
               | written/read to/from a database", although it's very
               | common. Although of course storage/persistence isn't non-
               | essential, just less common problem than the typical
               | design/architecture spaghetti I encounter.
        
               | Pxtl wrote:
               | I'm a firm believer in always using an auto-generated
               | surrogate key for the PK because domain PKs always
               | eventually become a pain point. The problem is that doing
               | so does real damage to the ergonomics of the DB.
               | 
               | This is why I fundamentally find SQL too conservative and
               | outdated. There are obvious patterns for cross-cutting
               | concerns that would mitigate things like this but
               | enterprise SQL products like Oracle and MS are _awful_ at
               | providing ways to do these reusable cross-cutting
               | concerns consistently.
        
             | Pxtl wrote:
             | I meant to reply to a different comment originally,
             | specifically the one including this quote from Torvalds:
             | 
             | > Good programmers worry about data structures and their
             | relationships.
             | 
             | > -- Linus Torvalds
             | 
             | I was specifically thinking about the "relationship"
             | issues. The _worst_ messes to fix are the ones where the
             | programmer didn 't consider how to relate the objects
             | together - which relationships need to be direct PK
             | bindings, which can be indirect, which things have to be
             | cached vs calculated live, which things _are_ the cache (vs
             | the master copy), what the cardinality of each relationship
             | is, which relationships are semantically ownerships vs
             | peers, which data is part of the system itself vs
             | configuration data vs live, how you handle changes to the
             | data, (event sourcing vs changelogging vs vs append-only vs
             | yolo update), etc.
             | 
             | Not quite "data structures" I admit but absolutely thinking
             | hard about the relationship between all the data you have.
             | 
             | SQL doesn't frame _all_ of these questions out for you but
             | it 's good getting you to start thinking about them in a
             | way you might not otherwise.
        
         | tangus wrote:
         | Aren't they basically saying opposite things? Perlis is saying
         | "don't choose the right data structure, shoehorn your data into
         | the most popular one". This advice might have made sense before
         | generic programming was widespread; I think it's obsolete.
        
           | Rygian wrote:
           | Pike: strongly typed logic is great!
           | 
           | Perlin: stringly typed logic is great!
        
           | embedding-shape wrote:
           | > Perlis is saying "don't choose the right data structure,
           | shoehorn your data into the most popular one"
           | 
           | I don't take it like that. A map could be the right data
           | structure for something people typically reach for classes to
           | do, and then you get a whole bunch of functions that can
           | already operate on a map-like thing for free.
           | 
           | If you take a look at the standard library and the data
           | structures of Clojure you'd see this approach taken to a
           | somewhat extreme amount.
        
         | TYPE_FASTER wrote:
         | > Rule 5. Data dominates. If you've chosen the right data
         | structures and organized things well, the algorithms will
         | almost always be self-evident. Data structures, not algorithms,
         | are central to programming.
         | 
         | If I have learned one thing in my 30-40 years spent writing
         | code, it is this.
        
           | seanalltogether wrote:
           | I agree. The biggest lesson I try to drive home to newer
           | programmers that join my projects is that its always best to
           | transform the data into the structure you need at the very
           | end of the chain, not at the beginning or middle. Keep the
           | data in it's purest form and then transform it right before
           | displaying it to the user, or right before providing it in
           | the final api for others to consume.
           | 
           | You never know how requirements are going to change over the
           | next 5 years, and pure structures are always the most
           | flexible to work with.
        
             | bluGill wrote:
             | Related: your business logic should work on metric units.
             | It is a UI concern if the user wants to see some other
             | measurement system. Convert to feet, chains, cubits... or
             | whatever obscure measurement system the user wants at
             | display time. (if you do get an embedded device that
             | reports non-metric units convert when it comes in - you
             | will get a different device in the future that reports
             | different units anyway)
             | 
             | You still have to worry about someone using kg when you use
             | g, but you avoid a large class of problems and make your
             | logic easier.
        
         | dcuthbertson wrote:
         | But doesn't No. 2 directly conflict with Pike's 5th rule? It
         | seems to me these are all aphorisms that have to be taken with
         | a grain of salt.
         | 
         | > 2. Functions delay binding; data structures induce binding.
         | Moral: Structure data late in the programming process.
        
         | jerf wrote:
         | As I'm sure more and more people are using AI to document old
         | systems, even just to get a foothold in them personally if they
         | don't intend to share it, here's a hint related to that: By
         | default, if you fire an AI at a programming base, at least in
         | my experience you get the usual documentation you expect from a
         | system: This is the list of "key modules", this module does
         | this, this module does that, this module does the other thing.
         | 
         | This is the worst sort of documentation; technically true but
         | quite unenlightening. It is, in the parlance of the Fred Brooks
         | quote mentioned in a sibling comment, _neither_ the
         | "flowchart" _nor_ the  "tables"; it is simply a brute
         | enumeration of code.
         | 
         | To which the fix is, ask for the right thing. Ask for it to
         | analyze the key data structures (tables) and provide you the
         | flow through the program (the flowchart). It'll do it no
         | problem. Might be inaccurate, as is a hazard with all
         | documentation, but it makes as good a try at this style of
         | documentation as "conventional" documentation.
         | 
         | Honestly one of the biggest problems I have with AI coding and
         | documentation is just that the training set is filled to the
         | brim with mediocrity and the defaults are inferior like this on
         | numerous fronts. Also relevant to this conversation is that AI
         | tends to code the same way it documents and it won't have
         | either clear flow charts or tables unless you carefully prompt
         | for them. It's pretty good at doing it when you ask, but if you
         | don't ask you're gonna get a mess.
         | 
         | (And I find, at least in my contexts, using opus, you can't
         | seem to prompt it to "use good data structures" in advance, it
         | just writes scripting code like it always does and like that
         | part of the prompt wasn't there. You pretty much have to come
         | back in after its first cut and tell it what data structures to
         | create. Then it's really good at the rest. YMMV, as is the way
         | of AI.)
        
       | kleiba wrote:
       | I believe the "premature evil" quote is by Knuth, not Hoare?!
        
         | swiftcoder wrote:
         | Potentially its by either (or even both independently). Knuth
         | originally attributed it to Hoare, but there's no paper trail
         | to demonstrate Hoare actually coined it first
        
           | Intermernet wrote:
           | Turns out that premature attribution is actually the root of
           | all evil...
        
           | Bengalilol wrote:
           | Every empirical programmer will, at some point, end up
           | yelling it out loud (too).
        
       | bsenftner wrote:
       | Obvious. Why the elevation of the obvious?
        
         | bazoom42 wrote:
         | Definitely not obvious to everybody.
        
         | DrScientist wrote:
         | I think for people starting out - rule 5 isn't perhaps that
         | obvious.
         | 
         | > Rule 5. Data dominates. If you've chosen the right data
         | structures and organized things well, the algorithms will
         | almost always be self-evident. Data structures, not algorithms,
         | are central to programming.
         | 
         | If want to solve a problem - it's natural to think about logic
         | flow and the code that implements that first and the data
         | structures are an after thought, whereas Rule 5 is spot on.
         | 
         | Conputers are machines that transform an input to an output.
        
           | mosura wrote:
           | > If want to solve a problem - it's natural to think about
           | logic flow and the code that implements that first and the
           | data structures are an after thought, whereas Rule 5 is spot
           | on.
           | 
           | It is?
           | 
           | How can you conceive of a precise idea of how to solve a
           | problem without a similarly precise idea of how you intend to
           | represent the information fundamental to it? They are
           | inseparable.
        
             | DrScientist wrote:
             | Obviously they are linked - the question is where do you
             | _start_ your thinking.
             | 
             | Do you start with the logical task first and structure the
             | data second, or do you actually think about the data
             | structures first?
             | 
             | Let's say I have a optimisation problem - I have a simple
             | scoring function - and I just want to find the solution
             | with the best score. Starting with the logic.
             | 
             | for all solutions, score, keep if max.
             | 
             | Simple eh? Problem is it's a combinatorial solution space.
             | The key to solving this before the entropic death of the
             | universe is to think about the _structure_ of the solution
             | space.
        
           | TheOtherHobbes wrote:
           | I mean - no. If you're coming to a completely new domain you
           | have to decide what the important entities are, and what
           | transformations you want to apply.
           | 
           |  _Neither_ data structures _nor_ algorithms, but entities and
           | tasks, from the user POV, one level up from any kind of
           | implementation detail.
           | 
           | There's no point trying to do something if you have no idea
           | what you're doing, or why.
           | 
           | When you know the what and why you can start worrying about
           | the how.
           | 
           | Iff this is your 50th CRUD app you can probably skip this
           | stage. But if it's green field development - no.
        
             | DrScientist wrote:
             | Sure context is important - and the important context you
             | appear to have missed is the 5 rules aren't about building
             | websites. It's about solving the kind of problems which are
             | easy to state but hard to do (well) .
             | 
             | eg sort a list.
        
         | praptak wrote:
         | A good chunk of great advice is obvious things _that people
         | still fail to do_.
         | 
         | That's why a collection of "obvious" things formulated in a
         | convincing way by a person with big street cred is still useful
         | and worth elevating.
        
           | pm215 wrote:
           | Also, "why these 5 in particular" is definitely not obvious
           | -- there are a great many possible "obvious in some sense but
           | also true in an important way" epigrams to choose from (the
           | Perlis link from another comment has over a hundred). That
           | Pike picked these 5 to emphasise tells you something about
           | his view of programming, and doubly so given that they are
           | rather overlapping in what they're talking about.
        
         | pjc50 wrote:
         | You've got to elevate some obviously correct things, otherwise
         | social media will fill the void with nonobviously incorrect
         | things.
        
           | mosura wrote:
           | Better to have 100 comments on one topic than 10 comments on
           | 10 topics.
        
         | HunterWare wrote:
         | Can't be but so obvious if the first comment I saw here was
         | that the first two rules didn't seem so important. =)
        
         | knorker wrote:
         | I'd call it more derivative than obvious.
         | 
         | "Why quote someone who's just quoting someone else?" -- Michael
         | Scott -- knorker
        
       | heresie-dabord wrote:
       | See Tony Hoare:
       | 
       | https://news.ycombinator.com/item?id=47325225
        
       | tobwen wrote:
       | Added to AGENTS.md :)
        
         | wwweston wrote:
         | How good is your model at picking good data structures?
         | 
         | There's several orders of magnitude less available _discussion_
         | of selecting data structures for problem domains than there is
         | code.
         | 
         | If the underlying information is implicit in high volume of
         | code available then maybe the models are good at it, especially
         | when driven by devs who can/will prompt in that direction. And
         | that assumption seems likely related to how much code was
         | written by devs who focus on data.
        
           | skydhash wrote:
           | > There's several orders of magnitude less available
           | discussion of selecting data structures for problem domains
           | than there is code.
           | 
           | I believe that's what most algorithms books are about. And
           | most OS book talks more about data than algorithms. And if
           | you watch livestream or read books on practical projects,
           | you'll see that a lot of refactor is first selecting a data
           | structure, then adapt the code around it. DDD is about data
           | structure.
        
         | ozgrakkurt wrote:
         | Would be cool to see the live reaction of Rob Pike to this
         | comment
        
           | andsoitis wrote:
           | > Would be cool to see the live reaction of Rob Pike to this
           | comment
           | 
           | Based on everything public, Pike is deeply hostile to
           | generative AI in general:
           | 
           | - The Christmas 2025 incident
           | (https://simonwillison.net/2025/Dec/26/slop-acts-of-
           | kindness/)
           | 
           | - he's labeled GenAI as nuclear waste
           | (https://www.webpronews.com/rob-pike-labels-generative-ai-
           | nuc...)
           | 
           | - ideologically, he's spent his career chasing complexity
           | reduction, adovcating for code sobriety, resource efficiency,
           | and clarity of thought. Large, opaque, energy-intensive LLMs
           | represent the antithesis.
        
             | clktmr wrote:
             | > - he's labeled GenAI as nuclear waste
             | (https://www.webpronews.com/rob-pike-labels-generative-ai-
             | nuc...)
             | 
             | The whole article is an AI hallucination. It refers to the
             | same "Christmas 2025 incident". The internet is dead for
             | real.
        
         | phh wrote:
         | Unironically. Every time I asked a LLM to make something
         | faster, they always tried blind code optimisations, rather than
         | measure.
        
       | CharlieDigital wrote:
       | I feel like 1 and 2 are only applicable in cases of novelty.
       | 
       | The thing is, if you build enough of the same kinds of systems in
       | the same kinds of domains, you can kinda tell where you should
       | optimize ahead of time.
       | 
       | Most of us tend to build the same kinds of systems and usually
       | spend a career or a good chunk of our careers in a given domain.
       | I feel like you can't really be considered a staff/principal if
       | you can't already tell ahead of time where the perf bottleneck
       | will be just on experience and intuition.
        
         | PaulKeeble wrote:
         | I feel like every time I have expected an area to be the major
         | bottleneck it has been. Sometimes some areas perform worse than
         | I expected, usually something that hasn't been coded well, but
         | generally its pretty easy to spot the computationally heavy or
         | many remote call areas well before you program them.
         | 
         | I have several times done performance tests before starting a
         | project to confirm it can be made fast enough to be viable, the
         | entire approach can often shift depending on how quickly
         | something can be done.
        
           | pydry wrote:
           | The number 1 issue Ive experienced with poor programmers is a
           | belief that theyre special snowflakes who can anticipate the
           | future.
           | 
           | It's the same thing with programmers who believe in BDUF or
           | disbelieve YAGNI - they design architectures for anticipated
           | futures which do not materialize instead of evolving the
           | architecture retrospectively in line with the future which
           | did materialize.
           | 
           | I think it's a natural human foible. Gambling, for instance,
           | probably wouldnt exist if humans' gut instincts about their
           | ability to predict future defaulted to realistic.
           | 
           | This is why no matter how many brilliant programmers scream
           | YAGNI, dont do BDUF and dont prematurely optimize there will
           | always be some comment saying the equivalent of "akshually
           | sometimes you should...", remembering that one time when they
           | metaphorically rolled a double six and anticipated the
           | necessary architecture correctly when it wasnt even necessary
           | to do so.
           | 
           | These programmers are all hopped up on a different kind of
           | roulette these days...
        
             | rcxdude wrote:
             | Aye. The number one way to make software amenable to future
             | requirements is to keep it simple so that it's easy to
             | change in future. Adding complexity for anticipated changes
             | works against being able to support the unanticipated ones.
        
             | tbrownaw wrote:
             | Sure, don't build your system to keep audit trails until
             | after you have questions to answer so that you know what
             | needs to go in those audit trails.
             | 
             | Don't insist on file-based data ingestion being a wrapper
             | around a json-rpc api just because most similar things are
             | moving that direction; what matters is whether someone has
             | specifically asked for that for this particular system yet.
             | 
             | .
             | 
             | Not all decisions can be usefully revisited later.
             | Sometimes you really do need to go "what if..." and make
             | sure none of the possibilities will bite too hard. Leaving
             | the pizza cave occasionally and making sure you (have
             | contacts who) have some idea about the direction of the
             | industry you're writing stuff for can help.
        
               | CharlieDigital wrote:
               | > Sure, don't build your system to keep audit trails
               | until after you have questions to answer so that you know
               | what needs to go in those audit trails...what matters is
               | whether someone has specifically asked for that for this
               | particular system yet.
               | 
               | I spent ~15 years in life sciences.
               | 
               |  _You 're going to build an audit trail, no matter what._
               | There's no validated system in LS that does not have an
               | audit trail.
               | 
               | It's just like e-commerce; you're going to have a cart
               | and a checkout page. There's no point in calling that a
               | premature optimization. Every e-commerce website has more
               | or less the same set of flows with simply different
               | configuration/parameters/providers.
        
               | pydry wrote:
               | Going "what if?" and then validating a customer
               | requirement that exists NOW is NOT the same thing as
               | trying to pre-empt a customer's requirement which _might_
               | exist in the future.
               | 
               | Audit trails are commonly neglected coz somebody didnt
               | ask the right questions, not coz somebody didnt try to
               | anticipate the future.
        
           | projektfu wrote:
           | It really depends on your requirements. C10k requires
           | different design than a web server that sees a few requests
           | per second at most, but the web might never have been
           | invented if the focus was always on that level of
           | optimization.
        
         | relaxing wrote:
         | Rob Pike wrote Unix and Golang, but sure, you're built
         | different.
        
           | andsoitis wrote:
           | > Rob Pike wrote Unix
           | 
           | Unix was created by Ken Thompson and Dennis Ritchie at Bell
           | Labs (AT&T) in 1969. Thompson wrote the initial version, and
           | Ritchie later contributed significantly, including developing
           | the C programming language, which Unix was subsequently
           | rewritten in.
        
             | 9rx wrote:
             | Pike didn't create Unix initially, but was a contributor to
             | it. He, with a team, unquestionably wrote it.
        
               | andsoitis wrote:
               | > but was a contributor to it. He, with a team,
               | unquestionably wrote it.
               | 
               | contribute < wrote.
               | 
               | His credits are huge, but I think saying he wrote Unix is
               | misattribution.
               | 
               | Credits include: Plan 9 (successor to Unix), Unix Window
               | System, UTF-8 (maybe his most universally impactful
               | contribution), Unix Philosophy Articulation,
               | strings/greps/other tools, regular expressions, C
               | successor work that ultimately let him to Go.
        
               | 9rx wrote:
               | Are you under the impression he was, like, a hands-off
               | project manager or something? His involvement was in
               | writing it. Not singlehandedly, but certainly as part of
               | a team. He unquestionably wrote it. He did not envision
               | it like he did the other projects you mention, but the
               | original credit was only in the writing of.
        
               | amw-zero wrote:
               | To say "Rob Pike wrote Unix" is completely inaccurate. He
               | joined after v7, in 1980.
        
               | 9rx wrote:
               | Nobody seems to be questioning that he was involved in
               | Unix. Given that he didn't write it, what _did_ he do for
               | the project? Quality assurance? Support? Marketing? Court
               | jester?
        
           | Intermernet wrote:
           | Rob Pike is responsible for many cool things, but Unix isn't
           | one of them. Go is a wonderful hybrid (with its own faults)
           | of the schools of Thompson and Wirth, with a huge amount of
           | Pike.
           | 
           | If you'd said Plan 9 and UTF-8 I'd agree with you.
        
             | jacquesm wrote:
             | Rob Pike definitely wrote large chunks of Unix while at
             | Bell Labs. It's wrong to say he wrote all of it like the GP
             | did but it is also wrong to diminish his contributions.
             | 
             | Unless you meant to imply that UNIX isn't cool.
        
               | relaxing wrote:
               | I did not say he wrote all of it. "Write" can include co-
               | authorship.
               | 
               | A lot of people are learning some history today,
               | beautiful to see.
        
               | jacquesm wrote:
               | I think that if you meant co-authorship you could have
               | made that clearer. A 'contributed to' would have saved
               | some unique ids.
        
           | my-next-account wrote:
           | Do you think Rob Pike ever decided that maybe what was done
           | before isn't good enough? Stop putting artificial limits on
           | your own competency.
        
         | HunterWare wrote:
         | ROFL, I wish Pike had known what he was talking about. /s ;)
        
           | CharlieDigital wrote:
           | Rob Pike and I (and probably most of us) work(ed) on
           | different kind of things.
           | 
           | Notice my use of the word "Novelty".
           | 
           | I get hired because I'm very good at building specific kinds
           | of systems so I tend to build many variants of the same kinds
           | of systems. They are generally not that different and the
           | ways in which the applications perform are similar.
           | 
           | I do not generally write new algorithms, operating systems,
           | nor programming languages.
           | 
           | I don't think this is so hard to understand the nuance of
           | Pike's advice and what we "mortals" do in or day-to-day to
           | earn a living.
        
         | Bengalilol wrote:
         | > you can kinda tell where you should optimize ahead of time
         | 
         | Rules are "kinda" made to be broken. Be free.
         | 
         | I've been sticking to these rules (and will keep sticking to
         | them) for as long as I can program (I've been doing it for the
         | last 30 years).
         | 
         | IMHO, you can feel that a bottleneck is likely to occur, but
         | you definitely can't tell where, when, or how it will actually
         | happen.
        
       | Mercuriusdream wrote:
       | never expected it to be a single HTML file so kind of surprised,
       | but straight to the point, to be honest.
        
         | andsoitis wrote:
         | KISS
        
           | epolanski wrote:
           | Well, even simpler, could've been plain text, every browser
           | supports them.
        
       | anthk wrote:
       | 9front it's distilled Unix. I corrected Russ Cox' 'xword' to work
       | in 9front and I am just a newbie. No LLM's, that's Idiocratic,
       | like the movie; just '9intro.us.pdf' and man pages.
       | 
       | LLM's work will never be reproducible by design.
        
       | piranha wrote:
       | > Rule 5 is often shortened to "write stupid code that uses smart
       | objects".
       | 
       | This is probably the worst use of the word "shortened" ever, and
       | it should be more like "mutilated"?
        
         | andsoitis wrote:
         | Syntactic sugar is cancer of the semicolon.
        
           | franktankbank wrote:
           | Tide goes in tide goes out, can't explain that.
        
             | paradox460 wrote:
             | Tide goes in, clean laundry comes out
        
       | keyle wrote:
       | Rule 5 is definitely king. Code acts on data, if the data is
       | crap, you're already lost.
       | 
       | edit: s/data/data structure/
        
         | andsoitis wrote:
         | ... if the data structures are crap.
         | 
         | Good software can handle crap data.
        
           | keyle wrote:
           | That is not what I meant. I meant crap data structures. Sorry
           | it's late here.
        
       | DaleBiagio wrote:
       | The attribution to Hoare is a common error -- "Premature
       | optimization is the root of all evil" first appeared in Knuth's
       | 1974 paper "Structured Programming with go to Statements."
       | 
       | Knuth later attributed it to Hoare, but Hoare said he had no
       | recollection of it and suggested it might have been Dijkstra.
       | 
       | Rule 5 aged the best. "Data dominates" is the lesson every senior
       | engineer eventually learns the hard way.
        
         | zabzonk wrote:
         | I've always thought it was Dijkstra - it even sounds Dijkstra-
         | ish.
        
         | YesThatTom2 wrote:
         | If Dijkstra blamed Knuth it would have been the best recursive
         | joke ever.
        
       | elcapitan wrote:
       | Meta: Love the simplicity of the page, no bullshit.
       | 
       | Funny handwritten html artifact though:                   <title>
       | <h1>Rob Pike's 5 Rules of Programming</h1> </title>
        
         | divbzero wrote:
         | Yes, I noticed this too. Timeless wisdom in 2128 bytes of
         | handcrafted HTML.
        
       | doe88 wrote:
       | Great rules, but Rule 3.: WOW, so true, so well enunciated,
       | masterful.
        
         | bell-cot wrote:
         | Yes, and I'd say it's more true now than then. Best case, your
         | fancy algorithms are super-sizing code that runs 1% of the
         | time, always kicking more-often-run code out of the most
         | critical CPU caches. Worst case, your fancy algorithms contain
         | security bugs, and the bad guys cash in.
        
       | Devasta wrote:
       | > "Premature optimization is the root of all evil."
       | 
       | This Axiom has caused far and away more damage to software
       | development than the premature optimization ever will.
        
         | gjadi wrote:
         | Because people only quote it partially.
         | 
         | > We should forget about small efficiencies, say about 97% of
         | the time: premature optimization is the root of all evil. Yet
         | we should not pass up our opportunities in that critical 3%.
        
       | nateb2022 wrote:
       | Previous discussion:
       | https://news.ycombinator.com/item?id=15776124 (8 years ago, 18
       | comments)
        
         | tomhow wrote:
         | Here's the full set:
         | 
         |  _Rob Pike's Rules of Programming (1989)_ -
         | https://news.ycombinator.com/item?id=38097031 - Nov 2023 (259
         | comments)
         | 
         |  _Rob Pike's Rules of Programming (1989)_ -
         | https://news.ycombinator.com/item?id=24135189 - Aug 2020 (323
         | comments)
         | 
         |  _Rob Pike's Rules of Programming (1989)_ -
         | https://news.ycombinator.com/item?id=15776124 - Nov 2017 (18
         | comments)
         | 
         |  _Rob Pike's Rules of Programming (1989)_ -
         | https://news.ycombinator.com/item?id=15265356 - Sept 2017 (112
         | comments)
         | 
         |  _Rob Pike's Rules of Programming (1989)_ -
         | https://news.ycombinator.com/item?id=7994102 - July 2014 (96
         | comments)
        
       | jcmartinezdev wrote:
       | Rule 6: Never disagree with AI slop
        
       | igtztorrero wrote:
       | Rule 4, I have always practiced and demanded of junior
       | programmers, to make algorithms and structures that are simple to
       | understand, for our main user: the one who will modify this code
       | in the future.
       | 
       | I believe that's why Golang is a very simple but powerful
       | language.
        
       | anymouse123456 wrote:
       | There are very few phrases in all of history that have done more
       | damage to the project of software development than:
       | 
       | "Premature optimization is the root of all evil."
       | 
       | First, let's not besmirch the good name of Tony Hoare. The quote
       | is from Donald Knuth, and the missing context is essential.
       | 
       | From his 1974 paper, "Structured Programming with go to
       | Statements":
       | 
       | "Programmers waste enormous amounts of time thinking about, or
       | worrying about, the speed of noncritical parts of their programs,
       | and these attempts at efficiency actually have a strong negative
       | impact when debugging and maintenance are considered. We should
       | forget about small efficiencies, say about 97% of the time:
       | premature optimization is the root of all evil. Yet we should not
       | pass up our opportunities in that critical 3%."
       | 
       | He was talking about using GOTO statements in C. He was talking
       | about making software much harder to reason about in the name of
       | micro-optimizations. He assumed (incorrectly) that we would
       | respect the machines our software runs on.
       | 
       | Multiple generations of programmers have now been raised to
       | believe that brutally inefficient, bloated, and slow software is
       | just fine. There is no limit to the amount of boilerplate and
       | indirection a computer can be forced to execute. There is no
       | ceiling to the crystalline abstractions emerging from these
       | geniuses. There is no amount of time too long for a JVM to spend
       | starting.
       | 
       | I worked at Google many years ago. I have lived the absolute
       | nightmares that evolve from the willful misunderstanding of this
       | quote.
       | 
       | No thank you. Never again.
       | 
       | I have committed these sins more than any other, and I'm mad as
       | hell about it.
        
         | devnullbrain wrote:
         | > and the missing context is essential.
         | 
         | Oh yes, I'd recommend everyone who uses the phrase reads the
         | rest of the paper to see the kinds of optimisations that Knuth
         | considers justified. For example, optimising memory accesses in
         | quicksort.
        
           | anymouse123456 wrote:
           | Exactly!
           | 
           | I wish Knuth would come out and publicly chastise the many
           | decades of abuse this quote has enabled.
        
             | trey-jones wrote:
             | To be fair, I think human nature is probably a bigger
             | culprit here than the quote. Yes, it was one of the first
             | things told to me as a new programmer. No, I don't think it
             | influenced very heavily how I approach my work. It's just
             | another small (probably reasonable) voice in the back of my
             | head.
        
           | kalaksi wrote:
           | This shows how hard it is to create a generalized and simple
           | rule regarding programming. Context is everything and a lot
           | is relative and subjective.
           | 
           | Tips like "don't try to write smart code" are often repeated
           | but useless (not to mention that "smart" here means over-
           | engineered or overly complex, not smart).
        
             | pydry wrote:
             | I dunno, Ive seen people try to violate "dont prematurely
             | optimize" probably a thousand times (no exaggeration) and
             | never ONCE seen this happen:
             | 
             | 1. Somebody verifies with the users that speed is actually
             | one of the most burning problems.
             | 
             | 2. They profile the code and discover a bottleneck.
             | 
             | 3. Somebody says "no, but we shouldnt fix that, that's
             | premature optimization!"
             | 
             | Ive heard all sorts of people like OP moan that "this is
             | why pieces of shit like slack are bloated and slow" (it
             | isnt) when advocating skipping steps 1 and 2 though.
             | 
             | I dont think they misunderstand the rule, either, they just
             | dont agree with it.
             | 
             | Did pike really have to specify explicitly that you have to
             | identify that a problem is a problem before solving it?
        
               | devnullbrain wrote:
               | >1. Somebody verifies with the users that speed is
               | actually one of the most burning problems.
               | 
               | Sometimes this is too late.
               | 
               | C++98 introduce `std::set` and `std::map`. The public
               | interface means that they are effectively constrained to
               | being red-black trees, with poor cache locality and
               | suboptimal lookup. It took until C++11 for
               | `std::unordered_map` and `std::unordered_set`, which
               | brought with them the adage that you should probably use
               | them unless you know you want ordering. Now since C++23
               | we finally have `std::flat_set` and `std::flat_map`, with
               | contiguous memory layouts. 25 years to half-solve an
               | optimisation problem and naive developers will still be
               | using the wrong thing.
               | 
               | As soon as the interface made contact with the public,
               | the opportunity to follow Rob Pike's Rule 5 was lost. If
               | you create something where you're expected to uphold a
               | certain behaviour, you need to consider if the
               | performance of data structures could be a functional
               | constraint.
               | 
               | At this point, the rule becomes cyclical and nonsensical:
               | it's not premature if it's the right time to do it. It's
               | not optimisation if it's functional.
        
               | pydry wrote:
               | You've inadvertently made an argument for deprecation,
               | not ignoring rob's rule.
               | 
               | When building interfaces you are bound to make mistakes
               | which end users will end up depending on (not just
               | regarding optimization).
               | 
               | The correct lesson to learn from this is not "just dont
               | make mistakes" but to try and minimize migration costs to
               | prevent these mistakes from getting tightly locked in and
               | try to detect these mistakes earlier on in the design
               | process with more coordinated experimentation.
               | 
               | C++ seems pretty bad at both. It's not unusual, either -
               | migration and upgrade paths are often the most neglected
               | part of a product.
        
               | devnullbrain wrote:
               | How would you have minimised migration costs for
               | std::map?
        
               | 9rx wrote:
               | _> the opportunity to follow Rob Pike 's Rule 5 was
               | lost._
               | 
               | std::set/std::map got into trouble because they chose the
               | algorithm first and then made the data model match. Rule
               | 5 suggests choosing the right data model first,
               | indicating that it is most important.
        
           | lynndotpy wrote:
           | Yep. If one is implementing quicksort for a library where it
           | will be used and relied on, I'd sure hope they're optimizing
           | it as much as they can.
        
         | frereubu wrote:
         | Totally agree. Out of this context, the word "premature" can
         | mean too many things.
        
         | aljgz wrote:
         | In all honesty, this is one of the less abused quotes, and I
         | have seen more benefit from it than harm.
         | 
         | Like you, I've seen people produce a lot of slow code, but it's
         | mostly been from people who would have a really hard time
         | writing faster code that's less wrong.
         | 
         | I hate slow software, but I'd pick it anytime over bogus
         | software. Also, generally, it's easier to fix performance
         | problems than incorrect behavior, especially so when the error
         | has created data that's stored somewhere we might not have
         | access to. But even more so, when the harm has reached the real
         | world.
        
           | anymouse123456 wrote:
           | I don't believe there is any tension at all between fast and
           | simple software.
           | 
           | We can and should have both.
           | 
           | This is a fraud, made up by midwits to justify their leaning
           | towers of abstraction.
        
             | embedding-shape wrote:
             | User-facing, sure, nothing stopping us from doing "simple
             | and fast" software. But when it comes to the code, design
             | and architecture, "simple" is often at odds with "fast",
             | and also "secure". Once you need something to be fast and
             | secure, it often leads to a less simple design, because now
             | you care about more things, it's kind of hard to avoid.
        
               | ndriscoll wrote:
               | IME doing application servers and firmware my whole
               | career, simple and fast are usually the same thing, and
               | "simple secure" is usually better security posture than
               | "complex secure".
        
               | embedding-shape wrote:
               | Interesting, never done firmware, but plenty of backends
               | and frontends. Besides the whole "do less and things get
               | faster", I can't think of a single case where "simple"
               | and "fast" is the same thing.
               | 
               | And I'd agree that "simple secure" is better than
               | "complex secure" but you're kind of side-stepping what I
               | said, what about "not secure at all", wouldn't that lead
               | to simpler code? Usually does for me, especially if you
               | have to pile it on top of something that is already not
               | so secure, but even when taking it into account when
               | designing from ground up.
        
               | ndriscoll wrote:
               | Not really. `return 0` is the simplest program you could
               | write, but it's not terribly useful. There's an
               | underlying assumption that there's some
               | purpose/requirement for the program to exist. Through
               | that lens "secure" is just assumed as a requirement, and
               | the simplest way to meet your requirements will usually
               | still give you the fastest program too.
               | 
               | "Do less and things get faster" is a very wide class of
               | fixes. e.g. you could do tons of per-packet decision
               | making millions of times per second for routing and
               | security policies, or you could realize the answer
               | changes slowly in time, and move that to upfront work,
               | separating your control vs data processing, and generally
               | making it _easier_ to understand. Or you could build your
               | logic into your addressing /subnets and turn it into a
               | simple mask and small table lookup. So your entire logic
               | gets boiled down to a table (incidentally why I can't
               | understand why people say ipv6 is complex. Try using
               | ipv4! Having more bits for addresses is awesome!).
        
               | MyHonestOpinon wrote:
               | > "simple" is often at odds with "fast"
               | 
               | Sort of. But if you keep the software simple, then it is
               | easier to optimize the bottlenecks. You don't really need
               | to make everything complicated to make it faster, just a
               | few well selected places need to be refactored.
        
           | gspr wrote:
           | > I have seen more benefit from it than harm.
           | 
           | Same. I, too, am sick of bloated code. But I use the quote as
           | a reminder to myself: "look, the fact that you _could_ spend
           | the rest of the workday making this function run in linear
           | instead of quadratic time doesn 't mean you should - you have
           | so many other tasks to tackle that it's better that you leave
           | the suboptimal-but-obviously-correct implementation of this
           | one little piece as-is for now, and return to it later if you
           | need to".
        
         | bko wrote:
         | > Multiple generations of programmers have now been raised to
         | believe that brutally inefficient, bloated, and slow software
         | is just fine. There is no limit to the amount of boilerplate
         | and indirection a computer can be forced to execute. There is
         | no ceiling to the crystalline abstractions emerging from these
         | geniuses. There is no amount of time too long for a JVM to
         | spend starting.
         | 
         | I think that's due to people doing premature optimization! If
         | people took the quote to heart, they would be less inclined to
         | increasing the amount of boilerplate and indirection.
        
           | ummonk wrote:
           | The boilerplate and indirection isn't done for performance
        
         | YesThatTom2 wrote:
         | I hear you, friend!
         | 
         | While you were seeing those problems with Java at Google, I saw
         | seeing it with Python.
         | 
         | So many levels of indirection. Holy cow! So many unneeded
         | superclasses and mixins! You can't reason about code if the
         | indirection is deeper than the human mind can grasp.
         | 
         | There was also a belief that list comprehensions were magically
         | better somehow and would expand to 10-line monstrosities of
         | unreadable code when a nested for loop would have been more
         | readable and just as fast but because list comprehensions were
         | fetishized nobody would stop at their natural readability
         | limits. The result was like reading the run-on sentence you
         | just suffered through.
        
         | twoodfin wrote:
         | Ignoring optimization opportunities until you see the profile
         | only works when you actually profile!
         | 
         | Profiling never achieved its place in most developers' core
         | loop the way that compiling, linting, or unit testing did.
         | 
         | How many real CI/CD pipelines spit out flame graphs alongside
         | test results?
        
           | pydry wrote:
           | I usually defer this until a PM does the research to
           | highlight that speed is a burning issue.
           | 
           | I find 98% of the time that users are clamoring to get
           | something implemented or fixed which isnt speed related so I
           | work on that instead.
           | 
           | When I do drill down what I tend to find in the flame graphs
           | is that your scope for making performance improvements a user
           | will _actually_ notice is bottlenecked primarily by I /O not
           | by code efficiency.
           | 
           | Meanwhile my less experienced coworkers will spot a nested
           | loop that will never take more than a couple of milliseconds
           | and demand it be "optimised".
        
             | lokar wrote:
             | Even at Google, the tendency is (or was when I was there),
             | to only profile things that we know are consuming a lot of
             | resources (or for sure will), or are hurting overall
             | latency.
             | 
             | Also the rule (quote?) says "speed hack", I don't think he
             | is saying ignore runtime complexity totally, just don't go
             | crazy with really complex stuff until you are sure you need
             | it.
        
               | Jensson wrote:
               | That depends on which part of Google. I worked in the hot
               | path of the search queries and there speed was extremely
               | important for everything, they want to do so much there
               | every single query and latency isn't allowed to go up.
        
             | IshKebab wrote:
             | The problem with ignoring performance is that you'll always
             | end up with slow software that is awful to use but ticks
             | all the feature boxes. As soon as someone comes along that
             | is fast and nice people will switch to that.
             | 
             | People don't ask for software to be fast and usable because
             | it obviously should be. Why would they ask? They might
             | _complain_ when it 's unusably slow. But that doesn't mean
             | they don't want it to be fast.
        
         | sph wrote:
         | Another one from my personal experience: apply DRY principles
         | (don't repeat yourself) the _third_ time you need something. Or
         | in other words: you 're allowed to copy-and-paste the same
         | piece of code in two different places.
         | 
         | Far too often we generalise a piece of logic that we need in
         | one or two places, making things more complicated for ourselves
         | whenever they inevitably start to differ. And chances are very
         | slim we will actually need it more than twice.
         | 
         | Premature generalisation is the most common mistake that
         | separates a junior developer from an experienced one.
        
           | busfahrer wrote:
           | Agreed, I think even Carmack advocates this rule
        
           | cjs_ac wrote:
           | DRY follows WET (Write Everything Twice).
        
           | colechristensen wrote:
           | Ehh, people who are really excited about DRY write unreadable
           | convoluted code, where the bulk of the code is abstractions
           | invented to avoid rewriting a small amount of code and unless
           | you're very familiar with the codebase reasoning about what
           | it actually does is a mystery because related pieces of
           | functionality are very far away from each other.
        
             | trey-jones wrote:
             | DRY is not to avoid writing code (of any amount). DRY is a
             | maintainability feature. "Unless you're very familiar with
             | the code" you probably won't remember that you have to make
             | this change in two places instead of one. DRY makes life
             | easier for future you, and anyone else unfortunate to
             | encounter (y)our mess.
        
               | bluGill wrote:
               | You are confusing DRY done as intended vs what DRY looks
               | like in the real world to many people.
        
               | colechristensen wrote:
               | Making maintainable code is a good goal.
               | 
               | DRY is one step removed from that goal and people use it
               | to make very unmaintainable code because they confuse any
               | repeated code with unmaintainability. (or their theory
               | that some day we might want to repeat this code so we
               | might as well pre-DRY it)
               | 
               | The result is often a horrendous complex mess. Imagine a
               | cookbook with a cookie recipe that resided on 47
               | different pages (40 of which were pointers on where to
               | find other pointers on where to find other pointers on
               | where to find a step) in attempts to never write the same
               | step twice in the whole book or your planned sequels in a
               | 20 volume set.
        
               | chuckadams wrote:
               | It's almost like there's a "reasonable person" type of
               | standard that's impossible to nail down in a general
               | rule...
        
               | colechristensen wrote:
               | If you can describe a rule in one sentence it'll probably
               | lead to as much trouble as it fixes.
               | 
               | The problem is zealots. Zealotry doesn't work for
               | indeterminate things that require judgement like "code
               | quality" or "maintainability", but a simple rule like
               | "don't repeat yourself" is easy for a zeal. They take a
               | rule and shut down any argument with "because the rule!"
               | 
               | If you're arguing about code quality and maintainability
               | without one sentence rules then you actually have to make
               | arguments. If the rule is your argument there's no
               | discussion only dogma.
               | 
               | As a result? Easy to distill rules spread fast, breed
               | zealots, and result in bad code.
        
           | matthewkayin wrote:
           | I think we should not even generalize it down to a rule of
           | three, because then you're outsourcing your critical thinking
           | to a rule rather than doing the thinking yourself.
           | 
           | Instead, I tend to ask: if I change this code here, will I
           | always also need to change it over there?
           | 
           | Copy-paste is good as long as I'm just repeating patterns. A
           | for loop is a pattern. I use for loops in many places. That
           | doesn't mean I need to somehow abstract out for loops because
           | I'm repeating myself.
           | 
           | But if I have logic that says that button_b.x = button_a.x +
           | button_a.w + padding, then I should make sure that I only
           | write that information down once, so that it stays consistent
           | throughout the program.
        
             | nostrademons wrote:
             | The reason for the rule of thumb is because you don't
             | _know_ whether you will need to change this code here when
             | you change it there until you 've written several instances
             | of the pattern. Oftentimes different generalizations become
             | appropriate for N=1, N=2, N>=3 && N <= 10, N>=10 && N<=100,
             | and N>=100.
             | 
             | Your example is a pretty good one. In most practical
             | applications, _you do not want to be setting button x
             | coordinates manually_. You want to use a layout manager,
             | like CSS Flexbox or Jetpack Compose 's Row or Java Swing's
             | FlowLayout, which takes in a padding and a direction for a
             | collection of elements and automatically figures out where
             | they should be placed. But if you only have one button,
             | this is overkill. If you only have two buttons, this is
             | overkill. If you have 3 buttons, you should start to
             | realize this is the pattern and reach for the right
             | abstraction. If you get to 10 buttons, you'll realize that
             | you need to arrange them in 2D as well and handle how they
             | grow & shrink as you resize the window, and there's a good
             | chance you need a more powerful abstraction.
        
             | rkomorn wrote:
             | > Instead, I tend to ask: if I change this code here, will
             | I always also need to change it over there?
             | 
             | IMO, this is the exact (and arguably only) question to ask.
        
             | 9rx wrote:
             | Critical thinkers understand that rules aren't written for
             | critical thinkers; that they are written for beginners who
             | don't yet have the necessary experience to be able to think
             | critically.
        
           | TeMPOraL wrote:
           | I really like Casey Muratori's "[Semantic] Compression-
           | oriented programming" - which is the philosophical backing of
           | "WET" (Write Everything Twice) counterpart to DRY.
           | 
           | https://caseymuratori.com/blog_0015
        
           | trey-jones wrote:
           | I think this is a reasonable rule of thumb, but there are
           | also times that the code you are about to write a second time
           | is extremely portable and can easily be made reusable (say
           | less than 5 minutes of extra time to make the abstraction).
           | In these cases I think it's worth it to go ahead and do it.
           | 
           | Having identical logic in multiple places (even only 2) is a
           | _big_ contributor to technical debt, since if you 're
           | searching for something and you find it and fix it /once/ we
           | often thing of the job as done. Then the "there is still a
           | bug and _I already fixed that_ " confusion is avoided by
           | staying DRY.
        
           | andrewmutz wrote:
           | You say that, but I've created plenty of production bugs
           | because two different implementations diverge. Easier to
           | avoid such bugs if we just share the implementation.
        
             | bluGill wrote:
             | I've also seen a lot of production bugs because two things
             | that appeared to be a copy/paste where actually
             | conceptually different and making them common made the
             | whole much more complex trying to get common code to handle
             | things that diverged even though they started from the same
             | place.
        
           | hackemmy wrote:
           | This is so true. I have been burned by this more times than I
           | can count. You see two functions that look similar, you
           | extract a shared utility, and then six months later one of
           | them needs a slightly different behavior and now you are
           | fighting your own abstraction instead of just changing one
           | line in a copy. The rule of three is a good default. Let the
           | pattern prove itself before you try to generalize it.
        
           | UncleMeat wrote:
           | More critical in my mind is investigating the "inevitably
           | start to differ" option.
           | 
           | If two pieces of code use the same functionality by
           | coincidence but could possibly evolve differently then don't
           | refactor. Don't even refactor if this happens three, four, or
           | five times. Because even if the code may be identical today
           | the features are not actually identical.
           | 
           | But if you have two uses of code that actually semantically
           | identical and will assuredly evolve together then go ahead
           | and refactor to remove duplication.
        
           | Kye wrote:
           | As always, xkcd:
           | 
           | https://xkcd.com/1205/
           | 
           | https://xkcd.com/974/
        
           | tikhonj wrote:
           | The rule of 3 is awful because it focuses on the wrong thing.
           | If two instances of the same logic represent the same
           | concept, they should be shared. If 10 instances of the same
           | logic represent unrelated concepts, they should be
           | duplicated.
           | 
           | The goal is to have code that corresponds to a coherent
           | conceptual model for whatever you are doing, and the
           | resulting codebase should clearly reflect the design of the
           | system. Once I started thinking about code in these terms, I
           | realized that questions like "DRY vs YAGNI" were not
           | meaningful.
        
             | taneq wrote:
             | > If two instances of the same logic represent the same
             | concept, they should be shared. If 10 instances of the same
             | logic represent unrelated concepts, they should be
             | duplicated.
             | 
             | Exactly.
        
             | sph wrote:
             | The devil's in the details, as usual. No rule should be
             | followed to the letter, which is what the top comment was
             | initially complaining about.
             | 
             | Yet again, understanding when to follow a rule of thumb or
             | not is another thing that separates the junior from the
             | senior.
        
             | miloignis wrote:
             | Of course, the rule of 3 is saying that you often _can't
             | tell_ what the shared concept between different instances
             | is until you have at least 3 examples.
             | 
             | It's not about copying _identical_ code twice, it 's about
             | refactoring similar code into a shared function once you
             | have enough examples to be able to see what the shared core
             | is.
        
               | imajoredinecon wrote:
               | 3 just seems arbitrary in practice though. In my job we
               | share code when it makes sense and don't when it doesn't,
               | and that serves us just fine
        
               | datsci_est_2015 wrote:
               | But don't let the rule of 3 be an excuse for you to not
               | critically assess the abstract concepts that your program
               | is operating upon and within.
               | 
               | I too often see junior engineers (and senior data
               | scientists...) write code procedurally, with giant
               | functions and many, many if statements, presumably
               | because in their brain they're thinking about "1st I do
               | this if this, 2nd I do that if that, etc".
        
             | eyelidlessness wrote:
             | I agree. And I think this also distills down to Rob Pike's
             | rule 5, or something quite like it. If your design
             | prioritizes modeling the domain's data, shaping algorithms
             | around that model, it's usually trivial to determine how
             | likely some "duplication" is operating on shared concepts,
             | versus merely following a similar pattern. It may even help
             | you refine the data model itself when confronted with the
             | question.
        
             | fauigerzigerk wrote:
             | Agreed. DRY is a compression algorithm. The rule of 3 is a
             | bad compression algorithm. Good abstraction is not
             | compression at all.
        
           | taneq wrote:
           | "Once, twice, automate/abstract" is a good general rule but
           | you have to understand that the thing you're counting isn't
           | appearances in the source code, it's repetitions of the same
           | logic _in the same context_. It's gotta _mean_ the same, not
           | just look the same.
        
           | krilcebre wrote:
           | The instances should be based on the context. For example we
           | had a few different API providers for the same thing, and
           | someone refactored the separate classes into a single one
           | that treats all of the APIs the same.
           | 
           | Well, turns out that 3 of the APIs changed the way they
           | return the data, so instead of separating the logic, someone
           | kept adding a bunch of if statements into a single function
           | in order to avoid repeating the code in multiple places. It
           | was a nightmare to maintain and I ended up completely
           | refactoring it, and even tho some of the code was repeated,
           | it was much easier to maintain and accommodate to the API
           | changes.
        
           | Pxtl wrote:
           | Depends on length and complexity, imho. If it's more than a
           | line or two of procedure? Or involves anything
           | counterintuitive? DRY at 2.
           | 
           | Extract a method or object if it's something that feels
           | conceptually a "thing" even if it has only one use. Most
           | tools to DRY your code also help by providing a bit of
           | encapsulation that do a great job of tidying things up to
           | force you to think about "should I be letting this out of
           | domain stuff leak in here?"
        
           | mock-possum wrote:
           | My rule of thumb is "when I have to make changes to this
           | later, how annoying is it going to be to make the same change
           | in multiple places?"
           | 
           | Sometimes four or five doesn't seem too bad, sometimes two is
           | too many
        
           | moogly wrote:
           | The D stands for "dependency", the R stands for "regret" and
           | I'm not sure what the Y stands for yet.
        
             | zer00eyz wrote:
             | Yelling... it stands for yelling...
             | 
             | Mostly at the massive switch statements and 1000 line's of
             | flow control logic that end up embedded someplace where
             | they really dont belong in the worst cases.
        
           | mort96 wrote:
           | IMO, the right way to think about DRY is to consider why a
           | given piece of code would ever change.
           | 
           | If you have two copies of some piece of code, and you can
           | reasonably say that if you ever want to update one copy then
           | you will almost certainly want to update the other copy as
           | well, then it's probably a good idea to try to merge them and
           | keep that logic in some centralized place.
           | 
           | On the other hand, if you have three copies of the same piece
           | of code, but they kind of just "happen to" be identical and
           | it's completely plausible that any one of the copies will be
           | modified in the future for reasons which won't affect the
           | other copies, maybe keeping them separate is a good idea.
           | 
           | And of course, it's sometimes worth it to keep two or more
           | different copies which _do_ share the same  "reason to
           | change". This is especially clear when you have the copies in
           | different repositories, where making the code "DRY" would
           | mean introducing dependencies between repositories which has
           | its own costs.
        
           | bsza wrote:
           | It's not how many times, it's what you do about it. DRY
           | doesn't mean you have to make abstractions for everything. It
           | means you don't repeat yourself. That is, if two pieces of
           | code are identical, chances are one of them shouldn't exist.
           | There are a lot of simple ways you might be able to address
           | that, starting from the most obvious one, which is to just
           | literally delete one of them. Abstraction should be about the
           | last tool you reach for, but for most people it's
           | unfortunately the first.
        
           | noufalibrahim wrote:
           | I had a situation where we need to implement a protocol. The
           | spec was fairly decent but the public implementations of the
           | other end were slightly non compliant which necessitated
           | special casing. Plus multiple versions etc.
           | 
           | An expensive consultant suggested creating pristine
           | implementation and then writing a rule layer that would
           | modify things as needed and deploying the whole thing as a
           | pile of lamdba functions.
           | 
           | I copy pasted the protocol consumer file per producer and
           | made all the necessary changes with proper documentation and
           | mocks. Got it working quickly and we could add new ones
           | without affecting.
           | 
           | If I'd try to keep it DRY, i think it would be a leaky mess.
        
         | dwb wrote:
         | Totally agree. I've see that quote used to justify wilfully
         | ignoring basic performance techniques. Then people are
         | surprised when the app is creaking exactly due to the lack of
         | care taken earlier. I would tend to argue the other way most of
         | the time: a little performance consideration goes a long way!
         | 
         | Maybe I've had an unrepresentative career, but I've never
         | worked anywhere where there's much time to fiddle with
         | performance optimisations, let alone those that make the
         | code/system significantly harder to understand. I expect that's
         | true of most people working in mainstream tech companies of the
         | last twenty years or so. And so that quote is basically never
         | applicable.
        
         | pjc50 wrote:
         | Slow code is more of a project management problem. Features are
         | important and visible on the roadmap. Performance usually isn't
         | until it hits "unacceptable", which may take a while to feed
         | back. That's all it is.
         | 
         | (AI will probably make this worse as well, having a bloat
         | tendency all of its own)
        
         | lowmagnet wrote:
         | I always point out the operational word is "premature".
        
         | dominotw wrote:
         | > I have lived the absolute nightmares that evolve from the
         | willful misunderstanding of this quote.
         | 
         | how do you know which code was written using this quote in
         | mind.
        
           | BoneShard wrote:
           | He doesn't know, but that quote makes for a cool talking
           | point. Software is slow or bloated because of budget,
           | deadlines, and skill levels - not because of a quote.
        
         | globular-toast wrote:
         | So you're saying people have misunderstood "premature
         | optimisation is the root of all evil" as "optimisation is the
         | root of all evil"?
         | 
         | I don't think you can blame this phrase if people are going to
         | drop an entire word out of an eight word sentence. The very
         | first word, no less.
        
         | bluGill wrote:
         | Don't confuse premature pessimization for the warnings against
         | premature optimization.
         | 
         | I can write bubble sort, it is simple and I have confidence it
         | will work. I wrote quicksort for class once - I turned in
         | something that mostly worked but there were bugs I couldn't fix
         | in time (but I could if I spent more time - I think...)
         | 
         | However writing bubble sort is wrong because any good language
         | has a sort in the standard library (likely timsort or something
         | else than quicksort in the real world)
        
         | taneq wrote:
         | > I have lived the absolute nightmares that evolve from the
         | willful misunderstanding of this quote.
         | 
         | Then the quote wasn't the problem. The wilful misunderstanding
         | was the problem.
        
         | koliber wrote:
         | Picking the starting point is very important. "optimization" is
         | the process of going from that starting point to a more
         | performant point.
         | 
         | If you don't know enough to pick good starting points you
         | probably won't know enough to optimize well. So don't optimize
         | prematurely.
         | 
         | If you are experienced enough to pick good starting points,
         | still don't optimize prematurely.
         | 
         | If you see a bad starting point picked by someone else, by all
         | means, point it out if it will be problematic now or in the
         | foreseeable future, because that's a bug.
        
         | JTbane wrote:
         | Anyone else feel like bloat is usually not an algorithmic
         | problem, but rather a library or environment issue most of the
         | time?
        
         | wavemode wrote:
         | I don't think the quote itself is responsible for any of that.
         | 
         | It's true that premature optimization (that is, optimization
         | before you've measured the software and determined whether the
         | optimization is going to make any real-world difference) is
         | bad.
         | 
         | The reality, though, is that most programmers aren't grappling
         | with whether their optimizations are premature, they're
         | grappling with whether to optimize at all. At most companies,
         | once the code works, it ships. There's little, if any, time
         | given for an extra "optimization" pass.
         | 
         | It's only after customers start complaining about performance
         | (or higher-ups start complaining about compute costs) that
         | programmers are given any time to go through and optimize
         | things. By which point refactoring the code is now much harder
         | than it wouldn've been originally.
        
         | Megranium wrote:
         | Huh, I've always understood that quote very differently, with
         | emphasis on "premature" ... not as in, "don't optimize" but
         | more as in "don't optimize before you've understood the
         | problem" ... or, as a CS professor of mine said "Make it work
         | first, THEN make it work fast" ...
        
           | DarkCrusader2 wrote:
           | well you see, in corporate (atleast in big tech), this is
           | usually used as a justification to merge inefficient code (we
           | will optimize it later). That later never comes, either the
           | developers/management moves on or the work item never gets
           | prioritized. That is until the bad software either causes
           | outages or customer churn. Then it is fixed and shown as high
           | impact in your next promo packet.
        
           | lokar wrote:
           | And if you know in advance that a function will be in the
           | critical path, and it needs to perform some operation on N
           | items, and N will be large, it's not premature to consider
           | the speed of that loop.
        
             | lokar wrote:
             | Another thought: many (most?) of these "rules" were before
             | widespread distributed computing. I don't think Knuth had
             | in mind a loop that is reading from a database at 100ms
             | each time.
             | 
             | I've seen people write some really head shaking code that
             | makes remote calls in a loop that don't actually depend on
             | each other. I wonder to what extend they are thinking
             | "don't bother with optimization / speed for now"
        
               | rob74 wrote:
               | If you really have a loop that is reading from a database
               | at 100ms each time, that's not because of not having
               | optimized it prematurely, that's just stupid.
        
               | lokar wrote:
               | And yet... :)
               | 
               | I think there is just a current (I've seen it mostly in
               | Jr engineers) that you should just ignore any aspect of
               | performance until "later"
        
               | lokar wrote:
               | and, I guess, context does matter. If you need to make 10
               | calls to gather up some info to generate something, but
               | you only need to do this once a day, or hour, and if the
               | whole process takes a few seconds that's fine, I could
               | see the argument that just doing the calls one at a time
               | linearly is simpler write/read/maintain.
        
               | heliumtera wrote:
               | Got it. What about initiating a 800mb image on a CPU
               | limited virtual machine that THEN hits a database, before
               | responding to a user request on a 300ms roundtrip? I
               | think we need a new word to describe the average
               | experience, stupidity doesn't fit.
        
               | patrickthebold wrote:
               | Reminds me of this quote which I recently found and like:
               | 
               | > look, I'm sorry, but the rule is simple: if you made
               | something 2x faster, you might have done something smart
               | if you made something 100x faster, you definitely just
               | stopped doing something stupid
               | 
               | https://x.com/rygorous/status/1271296834439282690
        
               | kstrauser wrote:
               | First, I agree with what you're saying.
               | 
               | But second, I'd remove "optimization" from considering
               | here. The code you're describing isn't _slow_ , it's
               | _bad_ code that also happens to be slow. Don 't write bad
               | code, ever, if you can knowingly avoid it.
               | 
               | It's OK to write good, clear, slow code when correctness
               | and understandability is more important that optimizing
               | that particular bit. It's not OK to write boneheaded
               | code.
               | 
               | (Exception: After you've written the working program, it
               | turns out that you have all the information to make the
               | query once in one part of the broader program, but don't
               | have all the information to make it a second time until
               | flow reaches another, decoupled part of the program. It
               | may be the lesser evil to do that than rearrange the
               | entire thing to pass all the necessary state around,
               | although you're making a deal with the devil and pinky
               | swearing never to add a 3rd call, then a 4th, then a 5th,
               | then...)
        
             | redbar0n wrote:
             | Just remember Rob Pike's 1st rule: don't assume where
             | bottlenecks will occur, but verify it.
        
               | ummonk wrote:
               | I've worked on optimizing modern slow code. Once you
               | optimize a few bottlenecks it turns out it's very hard to
               | optimize because the rest of the time is spread out over
               | the whole code without any small bottlenecks and it's all
               | written in a slow language with no thought for
               | performance.
        
             | senfiaj wrote:
             | From my understanding you still need to care care about the
             | algorithms and architecture. If N is sufficiently large,
             | you should pick O(N) algorithm over O(N^2). But usually
             | there is a tradeoff, simple code (or hiding something
             | behind some abstraction) might be easier to understand and
             | maintain, but it might work slower with large input data
             | and vice versa. I would rather write code that will be
             | easier to optimize if there is some bottleneck than to
             | optimize it overagressivelly. Also, different code needs
             | different kind of optimization. Sometimes the code might be
             | more IO heavy (disk / DB or network), for this type of
             | code, the IO operation planning and caching is more
             | critical than the optimization of the raw CPU time.
             | Sometimes the input is too small to have any significant
             | performance effects, and, what's paradoxical, choosing
             | smarter algorithms might even hurt performance (alongside
             | the maintanability). For example, for 10 - 100 items a
             | simple linear scan in an array might be faster than using a
             | O(log n) binary search tree. It's also well known that
             | faster executable code (regardless of being hand written,
             | machine generated, high level or machine code) usually has
             | larger size (mostly because it's more "unrolled",
             | duplicated and more complex when advanced algorithms are
             | used). If you optimize the speed everywhere, the binary
             | size tends to increase, causing more cache misses, which
             | might hurt the performance more than improve. This is why
             | some profiling is often needed for large software than
             | simply passing O3.
        
           | vbezhenar wrote:
           | We will optimize it later, we don't have time for that right
           | now, it seems it works fast enough for our needs right now.
           | 
           | "Later" never comes and all critical performance issues are
           | either ignored, hot-patched externally with caches of various
           | quality or just with more expensive hardware.
        
             | Nemi wrote:
             | While what you say is often true, it is a different problem
             | and does not change the fact of the prior posters.
        
             | zygentoma wrote:
             | My favourite quote for that is:
             | 
             | Broken gets fixed, but crappy stays forever
        
           | mort96 wrote:
           | Plenty of people seem to understand it as, "don't even
           | _think_ about performance until someone has made a strong
           | enough business case that the performance is sufficiently bad
           | as to impact profits ".
        
           | ekropotin wrote:
           | IDK if it can be applied in all situations.
           | 
           | Sometimes, especially when it comes to distributed systems,
           | going from working solution to fast working solution requires
           | full blown up redesign from scratch.
        
           | bdangubic wrote:
           | > Make it work first, THEN make it work fast
           | 
           | 1. I have seen too many "make it work first" that ended up
           | absolute shitshow that was notoriously difficult to do
           | anything with. You _can_ build the software right the first
           | time
           | 
           | 2. The "fast" part is what I think too many people are
           | focusing on and in my experience the "THEN" part is always
           | missing resources utilization and other types of inefficiency
           | that are not necessarily related to speed. I have seen
           | absolute messes of software that work _really_ fast
        
           | rco8786 wrote:
           | Ditto here
        
           | artyom wrote:
           | I agree with you. "Premature" is the keyword. Bloated
           | software is the result of not having the intention to
           | optimize it at all.
        
         | divan wrote:
         | > generations of programmers have now been raised to believe
         | that brutally inefficient, bloated, and slow software is just
         | fine.
         | 
         | I believe people don't think about Knuth when they choose to
         | write app in Electron. Some other forces might be at play here.
        
         | imjonse wrote:
         | I was a bit worried you are paraphrasing Rob Pike, but no, he
         | actually agrees with that Knuth quote.
         | 
         | I am almost certain that people building bloated software are
         | not willfully misunderstanding this quote; it's likely they
         | never heard about it. Let's not ignore the relevance of this
         | half a century old advice just because many programmers do not
         | care about efficiency or do not understand how computers work.
         | Premature optimization is exactly that, the fact that is
         | premature makes it wrong, regardless if it's about GOTO
         | statements in the 70s or a some modern equivalent where in the
         | name of craft or fun people make their apps a lot more complex
         | than they should be. I wouldn't be surprised if some of the
         | brutally inefficient code you mention was so because people
         | optimized prematurely for web-scale and their app never ever
         | needed those abstractions and extra components. The advice
         | applies both to hackers doing micro-optimizations and
         | architecture astronauts dreaming too big IMHO.
        
           | IshKebab wrote:
           | No I've definitely heard plenty of people use this as some
           | kind of inarguable excuse to not care about performance.
           | Especially if they're writing something in Python that should
           | really be not super slow. "It's fine! Premature optimisation
           | and all that. We'll optimise it later."
           | 
           | And then of course later is too late; you can't optimise most
           | Python.
        
         | lynndotpy wrote:
         | I think the bigger problem is that "Premature optimization is
         | the root of all evil" is a statement made by software engineers
         | to feel more comfortable in their shortcomings.
         | 
         | That's not to bemoan the engineer with shortcomings. Even the
         | most experienced and educated engineer might find themself
         | outside their comfort zone, implementing code without the
         | ability to anticipate the performance characteristics under the
         | hood. A mental model of computation can only go so far.
         | 
         | Articulated more succinctly, one might say "Use the profiler,
         | and use it often."
        
         | trgn wrote:
         | > Multiple generations of programmers have now been raised to
         | believe that brutally inefficient, bloated, and slow software
         | is just fine
         | 
         | 100%
        
         | trgn wrote:
         | A lot of developers get enamored by fetishes. Just one example,
         | because it's one i always struggle to vanquish in any of my
         | teams.
         | 
         | Devs are obsessed with introducing functional-style constructs
         | everywhere, just for the sake of it. FP is great for some
         | classes of software, but baseline crufty for anything that
         | requires responsiveness (front-ends basically), let alone
         | anything at real interactive speeds (games, geo-software, ...)
         | 
         | The "premature optimization" quote is then always used as a way
         | to ignore that entire code paths will be spamming the heap with
         | hundreds of thousands of temporary junk, useless lexical
         | scopes, and so forth. Writing it lean the first time is never
         | considered, because of adherence to these fetishes (mutability
         | is bad, oo is bad, loops lead to off-by-one errors, ...). It's
         | absolutely exhausting to have these conversations, it's always
         | starting from the ground up and these quotes like "premature
         | optimization is the root of all evil" are only used as
         | invocations to ward of criticism.
        
         | 01100011 wrote:
         | This is the sort of pontifical statement that old guys like me
         | tend to make which is strictly wrong but also contains a lot of
         | wisdom.
         | 
         | Yes, software is bloated, full of useless abstractions and bad
         | design. You kids(well, anyone programming post 1980, so myself
         | included) should be ashamed. Also let's not forget that those
         | abstractions helped us solve problems and our friends in
         | silicon valley(ok that no longer makes sense but imagine if
         | SillyValley still just made HW) covered our mistakes. But yeah,
         | we write crap a lot of the time.
         | 
         | But as other folks have said, it doesn't mean "don't optimize."
         | 
         | I've always used my own version of the phrase, which is: "Don't
         | be stupid." As in, don't do dumb, expensive things unless you
         | need to for a prototype. Don't start with a design that is far
         | from optimal and slow. After profiling, fix the slow things.
         | I'm pretty sure that's what most folks do on some level.
        
         | whatever1 wrote:
         | At least before the LLM world you would have to trade money
         | (aka more compute) for time to market. What is the point of
         | spending a single second optimizing a query when your database
         | has 10 users?
         | 
         | Of course today this has changed. You can have multiple agents
         | working on micro optimizing everything and have the pie and eat
         | it too.
        
         | pphysch wrote:
         | It has less to do with a quote and more to do with CS education
         | (and the market) rewarding minimal functionality over
         | performance, security, fault-tolerance, etc.
         | 
         | The average university CS student in USA (and India I presume)
         | is taught to "hack it" at any cost, and we see the results.
        
         | dblohm7 wrote:
         | I too learned this the hard way, via a supposedly concurrent
         | priority queue that did quadratic-time work while holding a
         | lock over the entire thing. I was told that "premature
         | optimization is the root of all evil."
         | 
         | Sorry, folks, but that's just an excuse to make dumb choices.
         | Premature _micro_optimization is the root of all evil.
         | 
         | EDIT: It was great training for when I started working on
         | browser performance, though!
        
           | dblohm7 wrote:
           | And if I may add a corollary: Measurement doesn't need to be
           | held off until the end of the project! Start doing it as soon
           | as you can!
        
         | jayd16 wrote:
         | This discussion kind of irks me. I just read these posts as:
         | "The quote saying A is bad. Actually it said A all along!"
         | 
         | It's just complaining about others making a different value
         | judgement for what is a worthwhile optimization. Hiding behind
         | the 'true meaning of the quote' is pointless.
        
         | andoando wrote:
         | As someone currently writing 16-18 tables all with common
         | definition, and crud, Id like some abstraction
        
         | didgetmaster wrote:
         | I agree. Faster hardware or horizontal scaling on distributed
         | cloud environments can mask the problem; but it certainly
         | doesn't solve the problem of bloated, inefficient software.
         | 
         | While it might not be necessary to spend hours fine-tuning
         | every function; code optimization should be the mindset of
         | every programmer no matter what they are coding.
         | 
         | How many fewer data centers would we need if all that software
         | running in them was more efficient?
         | 
         | https://didgets.substack.com/p/finding-and-fixing-a-billion-...
        
         | rixed wrote:
         | I wish we lived in a world where quotes could be that powerful.
         | But I'm afraid in reality this quote, like any other, is just
         | used as a justification after the fact.
         | 
         | Actually, I do not believe devs are to blame, or that CS
         | education is to blame; I believe that's an unfortunate law of
         | society that complexity piles up faster than we can manage it.
         | Of course the economic system rewards shiping today at the
         | expense of tomorrow's maintenance, and also rewards splitting
         | systems in seemingly independent subsystems that are simpler in
         | isolation but results in a more complex machinery (cloud,
         | microservices...)
         | 
         | I'm even wondering if it's not a more fundamental law than
         | that, because adding complexity is always simpler than removing
         | it, right? Kind of a second law of termodynamic for code.
        
         | Someone wrote:
         | > From his 1974 paper, "Structured Programming with go to
         | Statements":
         | 
         | > He was talking about using GOTO statements in C.
         | 
         | I don't think he was talking about C. That paper is from
         | December 1974, and (early) C is from 1972, and "The UNIX Time-
         | Sharing System" (https://dsf.berkeley.edu/cs262/unix.pdf) is
         | from July 1974, so time wise, he could have known C, but AFAICT
         | that paper doesn't mention C, and the examples are PL/I or
         | (what to me looks like) pseudocode, using ':=' for assignment,
         | 'if...fi' and 'while...repeat' for block, 'go to' and not C's
         | 'goto', etc.
        
       | Shawn19s83 wrote:
       | surprised this isn't talked about more
        
       | tasuki wrote:
       | The first four are kind of related. For me the fifth is the
       | important - and oft overlooked - one:
       | 
       | > Data dominates. If you've chosen the right data structures and
       | organized things well, the algorithms will almost always be self-
       | evident. Data structures, not algorithms, are central to
       | programming.
        
       | ta20211004_1 wrote:
       | Can't agree more on 5. I've repeatedly found that any really
       | tricky programming problem is (eventually) solved by iterative
       | refinement of the data structures (and the APIs they expose / are
       | associated with). When you get it right the control flow of a
       | program becomes straightforward to reason about.
       | 
       | To address our favorite topic: while I use LLMs to assist on
       | coding tasks a lot, I think they're very weak at this. Claude is
       | much more likely to suggest or expand complex control flow logic
       | on small data types than it is to recognize and implement an
       | opportunity to encapsulate ideas in composable chunks. And I
       | don't buy the idea that this doesn't matter since most code will
       | be produced and consumed by LLMs. The LLMs of today are much more
       | effective on code bases that have already been thoughtfully
       | designed. So are humans. Why would that change?
        
         | zer00eyz wrote:
         | > refinement of the data structures (and the APIs they expose /
         | are associated with)
         | 
         | I think rule 5 is often ignored by a lot of distributed
         | services. Where you have to make several calls, each with their
         | own http, db and "security" overhead, when one would do. Then
         | these each end up with caching layers because they are "slow"
         | (in aggregate).
        
           | nostrademons wrote:
           | If you're doing it right, you start with a centralized
           | service; get the product, software architecture, and data
           | flows right while it's all in one process; and then
           | distribute along architectural boundaries when you need to
           | scale.
           | 
           | Very few software services built today are doing it right.
           | Most assume they need to scale from day one, pick a
           | technology stack to enable that, and then alter the product
           | to reflect the limitations of the tech stack they picked.
           | Then they wonder why they need to spend millions on sales and
           | marketing to convince people to use the product they've
           | built, and millions on AWS bills to scale it. But then, the
           | core problem was really that their company did not need to
           | exist in the first place and only does because investors
           | insist on cargo-culting the latest hot thing.
           | 
           | This is why software sucks so much today.
        
             | skeeter2020 wrote:
             | >> If you're doing it right, you start with a centralized
             | service; get the product, software architecture, and data
             | flows right while it's all in one process; and then
             | distribute along architectural boundaries when you need to
             | scale.
             | 
             | I'll add one more modification if you're like me (and
             | apparently many others): go too far with your distribution
             | and pull it back to a sane (i.e. small handful) number of
             | distributed services, hopefully before you get too far down
             | the implementation...
        
         | alain94040 wrote:
         | Agreed, in my experience, rule 5 should be rule 1. I think I
         | also heard it said (paraphrased) as "show we your code and I'll
         | be forever confused, show me your database schema and
         | everything will become obvious".
         | 
         | Having implemented my shared of highly complex high-performance
         | algorithms in the past, the key was always to figure out how to
         | massage the raw data into structures that allow the algorithm
         | to fly. It requires both a decent knowledge of the various
         | algorithm options you have, as well as being flexible to see
         | that the data could be presented a different way to get to the
         | same result orders of magnitude faster.
        
           | skeeter2020 wrote:
           | I have seen a huge decline in data first over the past
           | decade-plus; maybe related to a lot more pragmatic training
           | where code-first and abstraction helped you go faster,
           | earlier but I definitely came of age starting with the schema
           | and there are an awful lot of problems & systems that
           | essentially are UI and functions on top of the schema.
        
             | danielmarkbruce wrote:
             | UI + functions on top of schema if you've designed the
             | schema well. Otherwise, it's a whole other thing.
        
           | beachy wrote:
           | I think you are referring to:
           | 
           | "Show me your flowchart and conceal your tables, and I shall
           | continue to be mystified. Show me your tables, and I won't
           | usually need your flowchart; it'll be obvious." -- Fred
           | Brooks, The Mythical Man Month (1975)
        
           | eikenberry wrote:
           | I don't think they were ever meant to be in order of
           | importance.
        
       | dasil003 wrote:
       | These rules aged well overall. The only change I would make these
       | days is to invert the order.
       | 
       | Number 5 is timeless and relevant at all scales, especially as
       | code iterations have gotten faster and faster, data is all the
       | more relevant. Numbers 4 and 3 have shifted a bit since data
       | sizes and performance have ballooned, algorithm overhead isn't
       | quite as big a concern, but the simplicity argument is relevant
       | as ever. Numbers 2 and 1 while still true (Amdahl's law is a
       | mathematical truth after all), are also clearly a product of
       | their time and the hard constraints programmers had to deal with
       | at the time as well as the shallowness of the stack. Still good
       | wisdom, though I think on the whole the majority of programmers
       | are less concerned about performance than they should be,
       | especially compared to 50 years ago.
        
       | treetalker wrote:
       | I'm not a skilled programmer (but would like to be someday).
       | Would someone kindly resolve what appears to me to be a
       | contradiction between the following?
       | 
       | 1(a) Torvalds: "Bad programmers worry about the code. Good
       | programmers worry about data structures and their relationships."
       | 
       | 1(b) Pike Rule 5: "Data dominates. If you've chosen the right
       | data structures and organized things well, the algorithms will
       | almost always be self-evident. Data structures, not algorithms,
       | are central to programming."
       | 
       | -- versus --
       | 
       | 2. Perlis 2: "Functions delay binding; data structures induce
       | binding. Moral: Structure data late in the programming process."
       | 
       | ---
       | 
       | Ignorant as I am, I read these to advise that I ought to put data
       | structures centrally, first, foremost -- but not until the end of
       | the programming process.
        
         | colechristensen wrote:
         | That is indeed contradictory and what those things say.
         | 
         | Good structure comes from exploring until you understand the
         | problem well AND THEN letting data structure dominate.
        
         | foltik wrote:
         | Afaict Perlis is more saying not to expose data layout in the
         | boundaries between abstractions, rather to keep them pure and
         | functional.
         | 
         | So not really a contradiction, just Perlis talking about the
         | functional shell and Torvalds/Pike talking about the imperative
         | core.
        
         | zweifuss wrote:
         | When you explore a problem, use Python and
         | lists/sets/dictionaries/JSON. Wait with types and specific data
         | structures till you have understanding. Speed of development
         | over speed of execution.
         | 
         | When you know what and how to build commit to good data
         | structures. Do the types, structs, classes, Trie, CRDTs, XML,
         | Protobuf, Parquet and whatnot where apropriate. Instrument your
         | program. The efficiency of the final product counts.
        
       | dkarl wrote:
       | I think it's fine and generous that he credited these rules to
       | the better-known aphorisms that inspired them, but I think his
       | versions are better, they deserve to be presented by themselves,
       | instead of alongside the mental clickbait of the classic
       | aphorisms. They preserve important context that was lost when the
       | better-known versions were ripped out of their original texts.
       | 
       | For example, I've often heard "premature optimization is the root
       | of all evil" invoked to support opposite sides of the same
       | argument. Pike's rules are much clearer and harder to interpret
       | creatively.
       | 
       | Also, it's amusing that you don't hear this anymore:
       | 
       | > Rule 5 is often shortened to "write stupid code that uses smart
       | objects".
       | 
       | In context, this clearly means that if you invest enough mental
       | work in designing your data structures, it's easy to write simple
       | code to solve your problem. But interpreted through an OO
       | mindset, this could be seen as encouraging one of the classic
       | noob mistakes of the heyday of OO: believing that your code could
       | be as complex as you wanted, without cost, as long as you hid the
       | complicated bits inside member methods on your objects. I'm
       | guessing that "write stupid code that uses smart objects" was a
       | snappy bit of wisdom in the pre-OO days and was discarded as
       | dangerous when the context of OO created a new and harmful way of
       | interpreting it.
        
         | zemo wrote:
         | > but I think his versions are better, they deserve to be
         | presented by themselves, instead of alongside the mental
         | clickbait of the classic aphorisms
         | 
         | keeping the historical chain of thinking alive is good,
         | actually
        
         | Matthyze wrote:
         | "mental clickbait of the classic aphorisms" is one way to
         | phrase 'attribution"
        
       | mcdonje wrote:
       | Very performance focused. Could more accurately be 5 rules of
       | perf. Good list, though.
        
       | _philipalan wrote:
       | CS Unc remains un-chopped.
        
       | ajpaulson wrote:
       | I think I'm going to copy and paste this directly into my
       | AGENTS.md file!
        
       | d_burfoot wrote:
       | I don't disagree with these principles, but if I wanted to
       | compress all my programming wisdom into 5 rules, I wouldn't spend
       | 3 out of the 5 slots on performance. Performance is just a
       | component of correctness : if you have a good methodology to
       | achieve correctness, you will get performance along the way.
       | 
       | My #1 programming principle would be phrased using a concept from
       | John Boyd: make your OODA loops fast. In software this can often
       | mean simple things like "make compile time fast" or "make sure
       | you can detect errors quickly".
        
       | patwolf wrote:
       | These rules apply equally well to system architecture. I've been
       | trying to talk our team out of premature optimization (redis
       | cluster) and fancy algorithms (bloom filters) to compensate for
       | poor data structures (database schema) before we know if
       | performance is going to be a problem.
       | 
       | Even knowing with 100% certainty that performance will be subpar,
       | requirements change often enough that it's often not worth the
       | cost of adding architectural complexity too early.
        
         | bob1029 wrote:
         | > Even knowing with 100% certainty that performance will be
         | subpar
         | 
         | I think there is value in attempting to do something the "wrong
         | way" on purpose to some extent. I have walked into many
         | situations where I was beyond convinced that the performance of
         | something would suck only to be corrected harshly by the
         | realities of modern computer systems.
         | 
         | Framing things as "yes, I know the performance is definitely
         | not ideal in this iteration" puts that monkey in a proper cage
         | until the next time around. If you don't frame it this way up
         | front, you might be constantly baited into chasing the
         | performance monkey around. Its taunts can be really difficult
         | to ignore.
        
       | sayYayToLife wrote:
       | I suppose this makes me feel a little bit better about a multi-
       | month process that ended up requiring the eight Queens problem.
       | 
       | That said management did not quite understand. They thought that
       | I should have known about the bottleneck (Actually I did but I
       | was told not to prematurely optimize)
       | 
       | I end up writing the program three times, the final solution was
       | honestly beautiful.
       | 
       | Management was not happy. The customer was happy.
        
       | ekjhgkejhgk wrote:
       | Uuuh doesn't look good that you claim something is important
       | enough to be in your top 5, but then misattribute it.
        
       | thecodemonkey wrote:
       | Running the same codebase for 10+ years with a small team is what
       | finally made me fully internalize these rules.
       | 
       | I've always been a KISS/DRY person but over a decade there are
       | plenty of moments where you're tempted to reach for a fancier
       | database or rewrite something in a trendier stack. What's
       | actually kept things running well at scale is boring, known
       | technologies and only optimizing in the places where it actually
       | matters.
       | 
       | We wrote our principles down recently and it basically just reads
       | like Pike's rules in different words: https://www.geocod.io/code-
       | and-coordinates/2025-09-30-develo...
        
       | andxor wrote:
       | Great gonna add these to my CLAUDE.md /s
        
       | HardCodedBias wrote:
       | Heretical opinion:
       | 
       | I think that Rob Pike was far more of a wordcel than a shape
       | rotator for a famous computer scientist (which historically were
       | very much on the shape rotator side).
        
       | pdpi wrote:
       | There's an important property that emerges from rules 3 and 4 --
       | because the simple algorithm is easier to implement correctly,
       | you can test the fancy algorithm for correctness by comparing its
       | output to the simple one.
        
       | publicdebates wrote:
       | "Rule 6: Don't waste time on syntax highlighting unless you're
       | incompetent."
        
       | OpenDQV wrote:
       | Golden rules for sure!
        
       | yandrypozo wrote:
       | does _a speed hack_ mean adding time.Sleep() for testing? or it's
       | something else?
        
       | possiblydrunk wrote:
       | Optimization usually trades complexity for speed. Complexity
       | hinders debugging and maintenance. Don't optimize unless you have
       | to and not before you know where the bottleneck is.
       | Straightforward common sense advice as long as hardware is not
       | persistently constraining.
        
       | TimLeland wrote:
       | Take a look at the page title. I guess he didn't follow his own
       | rules for this 100-line HTML file
       | 
       | <title> <h1>Rob Pike's 5 Rules of Programming</h1> </title>
        
       | BTAQA wrote:
       | Rule 5 is the one that took me longest to internalize. Coming
       | from frontend development into building a full product with a
       | real database, I kept reaching for complex query logic when the
       | real fix was just restructuring the data. Once the schema was
       | right the queries became obvious. Brooks was right 50 years ago
       | and it's still true.
        
       | netbioserror wrote:
       | This resonates as true, as long as the fundamentals of your tools
       | are there. Picking interpreted languages or browsers as targets
       | shoots you in the foot and sets you magnitudes behind when
       | performance starts to matter. But if you're using a native-
       | compiled language with value- and move-semantics, immutable data,
       | and a composable type system, it's shocking how easy it can be to
       | write obvious, maintainable, fast programs that perform under
       | pressure, even when you're not being clever.
       | 
       | Thankfully newer languages like Nim, Odin, and Swift lean hard
       | into value semantics. They drastically reduce the cost of
       | focusing on data structures and writing obvious algorithms. Then,
       | when bottlenecks appear, you can choose to opt into fine-tuning.
        
       | fogzen wrote:
       | Rule 5 should be rule 1.
        
       | SomaticPirate wrote:
       | How quaint. I hope Claude/Codex reads this since from what I've
       | heard here I'm not likely to need this rules anymore /s I am
       | curious if anyone has attempted to use codex/claude with
       | something like this in the prompt
        
       | sneedenheimer wrote:
       | Given that Rob Pike seems to think having a shell script that
       | uses tar is better than having a `-r` flag for cp [1], I wouldn't
       | give much weight to his philosophy of programming :P.
       | 
       | [1]: https://wiki.c2.com/?WhatIsNotInPlanNine
        
       | 01100011 wrote:
       | Rule 3 gets me into trouble with CS majors a lot. I'm an EE by
       | education and entered into SW via the bottom floor(embedded
       | C/ASM) so it was late in my career before I knew the formal
       | definition of big-O and complexity.
       | 
       | For most of my career, sticking to rule 3 made the most sense.
       | When the CS major would be annoying and talk about big-O they
       | usually forgot n was tiny. But then my job changed. I started
       | working on different things. Suddenly my job started sounding
       | more like a leetcode interview people complain about. Now n
       | really is big and now it really does matter.
       | 
       | Keep in mind that Rob Pike comes from a different era when
       | programming for 'big iron' looked a lot more like programming for
       | an embedded microcontroller now.
        
         | SoftTalker wrote:
         | My father did some programming in Fortran and Assembly of
         | various flavors. He was always partial to lookup tables where
         | they could replace complicated conditionals or computations.
         | Memory was precious in his day but it could still be worth it
         | if your program did something repeatedly (which most do).
        
         | kevincox wrote:
         | I actually disagree with Rule 3! While numbers are usually
         | small being fast on small cases generally isn't as important as
         | performing acceptably on large cases. So I prefer to take the
         | better big-O so that it doesn't slow down unacceptably on real-
         | world edge-case stresses. (The type of workloads that the devs
         | often don't experience but your big customers will.)
         | 
         | Of course there is a balance to this, the engineering time to
         | implement both options is an important consideration. But given
         | both algorithms are relatively easy to implement I will default
         | to the one that is faster at large sizes even if it is slower
         | at common sizes. I do suspect that there is an implicit
         | assumption that "fancy" algorithms take longer and are harder
         | to implement. But in many cases both algorithms are in the
         | standard library and just need to be selected. If this post
         | focused on "fancy" in terms of actual time to implement rather
         | than speed for common sizes I would be more inclined to agree
         | with it.
         | 
         | I wrote an article about this a while back:
         | https://kevincox.ca/2023/05/09/less-than-quadratic/
        
           | Jensson wrote:
           | Rule 3 was true 1989, back then computers were so slow and
           | had barely any ram so most things you did only was reasonable
           | for small number of inputs. Today we almost always have large
           | amounts of inputs so its different.
        
             | danielmarkbruce wrote:
             | This very much depends on where you work... and basically
             | isn't true for most people. It's extremely true for some
             | people.
        
               | cjwoodall wrote:
               | Rule 3 is still very much real. Fancy fast algorithms
               | often have other trade-offs. The best algorithm for the
               | job is the one that meets all requirements well... Big-O
               | is one aspect, data is another, determinism of the
               | underlying things that are needed (dynamic memory
               | allocation, etc) can be another.
               | 
               | It is important to remember that the art of sw
               | engineering (like all engineering) lives in a balance
               | between all these different requirements; not just in
               | OPTIMIZE BIG-O.
        
               | danielmarkbruce wrote:
               | Sure but the default (and usually correct) assumption
               | when working at google (as an example) is basically "all
               | numbers are big", so you you have to cluey about
               | algorithms and data structures and not default to brute
               | forcing something.
               | 
               | At 99% of shops it should be the other way around .
        
               | jltsiren wrote:
               | Even when you are working with large numbers, most
               | numbers are usually small. Most of the code is probably
               | not dealing with the large things, and a large thing may
               | consist of a large number of instances that are
               | individually small.
               | 
               | I've personally found it useful to always have concrete
               | numbers in mind. An algorithm or data structure designed
               | for N will probably be fine for N/10 and 10N, but it will
               | often be inefficient for N/1000 or 1000N.
        
         | grogers wrote:
         | Well it is hedged with the word "fancy". I think a charitable
         | reading is to understand the problem domain. If N is always
         | small then trying to minimize the big-O is just showing off and
         | likely counterproductive in many ways. If N is large, it might
         | be a requirement.
         | 
         | Most people don't need FFT algorithm for multiplying large
         | numbers, Karatsuba's algorithm is fine. But in some domains the
         | difference does matter.
         | 
         | Personally I usually see the opposite effect - people first
         | reach for a too-naive approach and implement some O(n^2)
         | algorithm where it wouldn't have even been more complex to
         | implement something O(n) or O(n log n). And n is almost always
         | small so it works fine, until it blows up spectacularly.
        
           | bartread wrote:
           | > Personally I usually see the opposite effect - people first
           | reach for a too-naive approach and implement some O(n^2)
           | algorithm where it wouldn't have even been more complex to
           | implement something O(n) or O(n log n). And n is almost
           | always small so it works fine, until it blows up
           | spectacularly.
           | 
           | Same. People solve in ways that are very obviously going to
           | cause serious problems in only a few short weeks or months
           | and it's endlessly frustrating. If you're building a
           | prototype, fine, but if you're building for production, very
           | far from fine.
           | 
           | Most frustrating because often there's next to no cost in
           | selecting and implementing the correct architecture, domain
           | model, data structure, or algorithm up front.
        
       | big-chungus4 wrote:
       | Idk about rule 1, in my experience it's usually pretty clear
       | which part of code is slow. Maybe it depends on projects,
       | programming language, etc
        
       | wsesamemr81 wrote:
       | this matches my experience exactly
        
       | justacatbot wrote:
       | Rule 2 is the one that keeps biting me. You can spend days micro-
       | optimizing functions only to realize the real bottleneck was
       | storing data in a map when you needed a sorted list. The
       | structure of the data almost always determines the structure of
       | the code.
        
         | ummonk wrote:
         | That's Rule 5 no?
        
       | antirez wrote:
       | In programming, the only rule to follow is that there are no
       | rules: only taste and design efforts. There are too many
       | different conditions and tradeoffs: sometimes what is going to be
       | the bottleneck is actually very clear and one could decide to
       | design with that already in mind, for instance.
        
       | GuB-42 wrote:
       | The opposite conclusion can be taken from the premise of rule #1
       | "You can't tell where a program is going to spend its time"
       | 
       | If you can't tell in advance what is performance critical, then
       | consider everything to be performance critical.
       | 
       | I would then go against rule #3 "Fancy algorithms are slow when n
       | is small, and n is usually small". n is usually small, except
       | when it isn't, and as per rule #1, you may not know that ahead of
       | time. Assuming n is going to be small is how you get accidentally
       | quadratic behavior, such as the infamous GTA bug. So, assume n is
       | going to be big unless you are sure it won't be. Understand that
       | your users may use your software in ways you don't expect.
       | 
       | Note that if you really want high performance, you should
       | properly characterize your "n" so that you can use the
       | appropriate technique, it is hard because you need to know all
       | your use cases and their implications in advance. Assuming n will
       | be big is the easy way!
       | 
       | About rule #4, fancy algorithms are often not harder to
       | implement, most of the times, it means using the right library.
       | 
       | About rule #2 (measure), yes, you absolutely should, but it
       | doesn't mean you shouldn't consider performance before you
       | measure. It would be like saying that you shouldn't worry about
       | introducing bugs before testing. You should do your best to make
       | your code fast and correct before you start measuring and
       | testing.
       | 
       | What I agree with is that you shouldn't introduce speed hacks
       | unless you know what you are doing. Most of performance come from
       | giving it consideration on every step. Avoiding a copy here,
       | using a hash map instead of a linear search there, etc... If you
       | have to resort to a hack, it may be because you didn't consider
       | performance early enough. For example, if took care of making a
       | function fast enough, you may not have to cache results later on.
       | 
       | As for #5, I agree completely. Data is the most important. It
       | applies to performance too, especially on modern hardware. To
       | give you an very simplified idea, RAM access is about 100x slower
       | than running a CPU instruction, it means you can get massive
       | speed improvement by making your memory footprint smaller and
       | using cache-friendly data structures.
        
         | epolanski wrote:
         | > If you can't tell in advance what is performance critical,
         | then consider everything to be performance critical.
         | 
         | As for rule 2: first you measure.
        
       | fl0ki wrote:
       | > Fancy algorithms are slow when n is small, and n is usually
       | small. Fancy algorithms have big constants.
       | 
       | I get where he's coming from, but I've seen people get this very
       | wrong in practice. They use an algorithm that's indeed faster for
       | small n, which doesn't matter because anything was going to be
       | fast enough for small n, meanwhile their algorithm is so slow for
       | large n that it ends up becoming a production crisis just a year
       | later. They prematurely optimized after all, but for an n that
       | did not need optimization, while prematurely pessimizing for an n
       | that ultimately did need optimization.
        
       | R0m41nJosh wrote:
       | When I was young I took time to "optimize" my code where it
       | obviously had no impact, like on simple python scripts. It was
       | just by ego, to look smart. I guess the "early optimization"
       | takes are aimed at young developers who want to show their skills
       | on completely irrelecant places.
       | 
       | Of course with experience, you start to feel when the straight
       | forward suboptimal code will cause massive performance issued. In
       | this case it's critical to take action up front to avoid the
       | mess. Its called software architecture, I guess.
        
       | shashank-100 wrote:
       | rules are there until you break them
        
       | vishnugupta wrote:
       | I can't emphasize the importance of rule-5 enough.
       | 
       | I learnt about rule-5 through experience before I had heard it
       | was a rule.
       | 
       | I used to do tech due diligence for acquisition of companies. I
       | had a very short time, about a day. I hit upon a great time saver
       | idea of asking them to show their DB schema and explain it. It
       | turned out to be surprisingly effective. Once I understood the
       | scheme most of the architecture explained itself.
       | 
       | Now I apply the same principle while designing a system.
        
         | SoftTalker wrote:
         | Yes, fully agree. Rule 5 has been the center of my approach to
         | designing and writing software for over 30 years now. Fad
         | methodologies and platforms come and go but Rule 5 works as
         | well for me today as it did in 1995.
        
           | artyom wrote:
           | I can't agree more. I live and breath by rule #5.
           | 
           |  _Getting competent_ at it, however, is no joke and takes
           | time.
        
       | nlawalker wrote:
       | This reminds me of a portion of a talk Jonathan Blow gave[1],
       | where he justifies this from a productivity angle. He explains
       | how his initial implementation for virtually everything in Braid
       | used arrays of records, and only after finding bottlenecks did he
       | make changes, because if he had approached every technical
       | challenge by trying to find the optimal data structure and
       | algorithm he would never have shipped.
       | 
       | "There's a third thing [beyond speed and memory] that you might
       | want to optimize for which is much more important than either of
       | these, which is years of your life required per program
       | implementation." This is of course from the perspective of a solo
       | indie game developer, but it's a good and interesting perspective
       | to consider.
       | 
       | [1] https://www.youtube.com/watch?v=JjDsP5n2kSM
        
         | Insanity wrote:
         | It's easy to see this outside of the perspective of a solo game
         | developer. We all have deadlines to manage even in the regular
         | 'corporate world'. And engineering time spent on a problem also
         | translates to an actual cost.
         | 
         | It's a good consideration tbh.
        
         | dgb23 wrote:
         | It's also notable that video games are programs that run for
         | hours and iterate over large sets of very similar entities at
         | 60 frames or more per second repeatedly and often do very
         | similar operations on each of the entities.
         | 
         | That also means that "just do an array of flat records" is a
         | very sane default even if it seems brutish at first.
        
           | quietbritishjim wrote:
           | I think when he said "just do an array of flat records" he
           | meant as opposed to record of arrays (i.e. row oriented vs
           | column oriented), as opposed to fancy data structures which I
           | think you're assuming he was implying. Separate arrays for
           | each data member are common in game engines exactly because
           | they're good for iterating over, which as you said is common.
        
             | O3marchnative wrote:
             | That's also great for letting the compiler unlock auto-
             | vectorization opportunities without delving into the world
             | of manual SIMD.
             | 
             | Even storing something simple such as an array of complex
             | numbers as a structure of arrays (SoA) rather than an array
             | of structures (AoS) can unlock a lot of optimizations. For
             | example, less permutes/shuffles and more arithmetic
             | instructions.
             | 
             | Depending on how many fields you actually need when you
             | iterate over the data, you prevent cache pollution as well.
        
             | mabster wrote:
             | I haven't watched his videos on his language for ages, but
             | this was a big thing he wanted in his language: being able
             | to swap between array-of-structs and struct-of-array
             | quickly and easily.
        
             | MaxBarraclough wrote:
             | Jonathan Blow's own unreleased _Jai_ programming language
             | has a feature to make it trivial to switch between array-
             | of-structs and struct-of-arrays.
             | 
             | From a quick search, it seems HackerNews's own _jcelerier_
             | has put together a C++ library for doing this.
             | https://github.com/celtera/ahsohtoa
        
         | skeeter2020 wrote:
         | I'd be careful extending learnings from games (solo or team
         | efforts) to general programming as the needs and intent seem to
         | be so different. We rarely see much code re-use in games
         | outside of core, special-purpose buy largely isolated
         | components and assets. Outside of games there's a much bigger
         | emphasis on the data IME, and performance is often a nice-to-
         | have.
        
           | awesome_dude wrote:
           | Yeah - A game is (generally) a one and done enterprise. Like
           | a start up it's all about getting it out the door, there's
           | little to no expectation of having to maintain it for any
           | real length of time.
        
             | fidotron wrote:
             | HN has some hot takes but that one is particularly
             | impressive.
             | 
             | Fortnite, Roblox, League of Legends, Counter Strike . . .
             | all very short term projects.
        
               | wat10000 wrote:
               | For every game like that, there are a thousand games that
               | shipped, maybe got a few updates, and then they were
               | done.
        
               | awesome_dude wrote:
               | We can probably add to that the fact that the nominated
               | titles almost certainly started out with spaghetti code
               | that had to be refactored, reworked, and gave maintainers
               | nightmares in their sleep
        
           | mabster wrote:
           | It's been mixed moving to normal code: I haven't had to low-
           | level optimise for ages now (man I miss that). But
           | performance in the O() sense has been the same.
           | 
           | Game engine development is very much about processing of
           | data. The pipeline is long and the tree is wide. Being able
           | to reason about complicated data processing topologies mapped
           | very easily across.
        
         | suzzer99 wrote:
         | > how his initial implementation for virtually everything in
         | Braid used arrays of records
         | 
         | This is me with hash maps.
        
         | Fraterkes wrote:
         | This is slightly surprising to me, since Braid is kinda
         | infamous for being in development for a pretty long time for a
         | puzzle platformer
        
           | SatvikBeri wrote:
           | Was 3 years a long time for an indie platformer in the early
           | 2000s? Looking at some similar examples:
           | 
           | * Braid was 3 years
           | 
           | * Cave Story was 5 years
           | 
           | * World of Goo was 2 years
           | 
           | * Limbo was about 3 years (but with 8-16 people)
           | 
           | So Braid seems pretty average.
        
             | Fraterkes wrote:
             | Yeah, you're right. I must've misremembered.
        
         | IshKebab wrote:
         | I feel like a game is a bit different though because you
         | control the input. You can't profile input you've never seen.
        
         | gowld wrote:
         | Jonathan blow has spent the past 10 years and almost all of his
         | money trying to build the perfect programming language for his
         | 3rd game.
         | 
         | Also, Rule 5 contradicts the idea you quoted from Blow.
        
         | parasense wrote:
         | The funny thing is even data structure is really an array of
         | memory depending how low down deep one looks. All the people
         | who took an intro computer science course knows, those who had
         | to implement a heap allocator, it's all really just arrays
         | underneath...
        
       | cestith wrote:
       | Any software developer who hasn't read _The Practice of
       | Programming_ by Kernighan and Pike should. It's not that long and
       | much of it is timeless.
        
         | Insanity wrote:
         | Yeah, but I doubt many of the newer generation are going to
         | read this. I manage a team of engineers, and one of the recent-
         | ish graduates asked me in our 1-on-1 if it's still worth
         | learning Python given that he can just write prompts. (Python
         | is the language all our tools use).
         | 
         | If the next generation doesn't even want to learn a programming
         | language, they're definitely not going to learn how to write
         | _clean_ code.
         | 
         | Maybe I'm just overly pessimistic about junior engineers at the
         | moment because of that conversation lol.
        
           | calepayson wrote:
           | Junior here. There are still a few of us who value books and
           | documentation. It's a weird time though. Hard to feel
           | confident that you're learning in the correct way.
           | 
           | Anyway, I've found that if you want to get a coworker into
           | reading technical books, the best way is with a novel or
           | three. I've had good success with The Martian. The Phoenix
           | Project might work too. Slip them fun books until they've
           | built a habit and then drop The Mythical Man Month on them.
           | :)
        
           | LVB wrote:
           | Here's my optimistic take: the fundamental things that spark
           | joy about learning a novel algorithm, pattern, technique,
           | etc. haven't gone anywhere, and there's no reason to think
           | those things won't continue to be interesting. Furthermore,
           | it seems like _reading_ code isn 't going anywhere too soon,
           | and that definitely benefits from clean code. It follows that
           | someone who can actually recognize clean from spaghetti, and
           | tell the LLM to refactor it into XYZ style, is going to be
           | relatively more valuable.
           | 
           | Random side note: my teen son has grown up with iPhone-level
           | tech, yet likes and finds my old Casio F91 watch very
           | interesting. I still have faith :)
        
           | wduquette wrote:
           | In almost forty years of experience, the fraction of
           | developers I've known who read in the field beyond what's
           | strictly needed for their task is _very_ small. I 'm always
           | delighted when I find one.
        
           | fwip wrote:
           | I obviously wasn't there, but it sounds like maybe they were
           | asking for reassurance. There's a lot of people out there
           | saying that LLMs are going to totally replace regular
           | programming, and for a new grad who doesn't know much about
           | the world, they value your expertise.
        
             | Insanity wrote:
             | That's a positive interpretation. You might be right,
             | either way that's what I pointed them to. I don't think the
             | LLMs will really replace engineers in the foreseeable
             | future, and so learning the languages and the fundamentals
             | is still needed.
        
               | cestith wrote:
               | I have a laptop and a phone right here, right now. I have
               | actual calculators around here somewhere. I've been out
               | of schools for decades. I still can do arithmetic and
               | basic algebra in my head or on paper and often do.
               | 
               | I'm hoping the situation with LLMs will be the same.
               | Teach the basics and allow people to fall back on them
               | for at least the simpler tasks for their lifetimes. I
               | know people, by the way, who can still use an abacus and
               | a slide rule. I can too, but with a refresher beforehand
               | because I seldom use those.
        
           | kshacker wrote:
           | IMO it is a valid question. Our AI has not yet reached that
           | level, our prompts have not yet reached that level of
           | sophistication. But I do not code in assembly any more, I do
           | not do pointer arithmetic any more, so maybe some day we get
           | to a state where we do not write python also. It is not going
           | to be soon despite the AI bandwagon saying so, there are too
           | many legacy pieces that are not documented well and not easy
           | decipherable due to context window limits. But in 10 years
           | ...maybe prompts is all we need.
           | 
           | PS: Not that we do not have people working at all levels of
           | stack today, just that each level of stack, like a discussion
           | going on today about python's JIT compiler will be a few
           | (dozen or hundred) specialists. Everyone else can work with
           | prompts.
        
       | ryguz wrote:
       | The interesting thing about Rule 1 is that it makes Rules 3-5
       | follow almost mechanically. If you genuinely accept that you
       | cannot predict where the bottleneck is, then writing
       | straightforward code and measuring becomes the only rational
       | strategy. The problem is most people treat these rules as
       | independent guidelines rather than as consequences of a single
       | premise.
       | 
       | In practice what I see fail most often is not premature
       | optimization but premature abstraction. People build elaborate
       | indirection layers for flexibility they never need, and those
       | layers impose real costs on every future reader of the code. The
       | irony is that abstraction is supposed to manage complexity but
       | prematurely applied it just creates a different kind.
        
         | eru wrote:
         | > In practice what I see fail most often is not premature
         | optimization but premature abstraction.
         | 
         | Compare and contrast https://people.mpi-
         | sws.org/~dreyer/tor/papers/wadler.pdf
        
           | tasuki wrote:
           | Philip Wadler gave us a sound type system. Rob Pike gave us a
           | programming language for stupid people. Each contributed in
           | their own way, towards different goals.
        
         | rob wrote:
         | Really need that [flag bot] button added to HN.
        
           | tech_hutch wrote:
           | Are you saying the parent comment seems like a bot?
        
             | macintux wrote:
             | Comment history is suspect.
        
           | rd wrote:
           | It would be easier if we could just block comments from green
           | users. I get that it loses ~.1% of authors who might have
           | made an account to comment on a blogpost of theirs that was
           | posted here. I'd rather have that loss than have to deal with
           | the 99.9% of spam.
        
             | suzzer99 wrote:
             | TIL green means new. I thought it was special for some
             | reason.
        
         | tracker1 wrote:
         | You tend to see it a lot in "Enterprise" software (.Net and
         | Java shops in particular). A lot of Enterprise Software
         | Architects will reach for their favored abstractions out of
         | practice as opposed to if they fit. Custom solution providers
         | will build a bunch of the same out of practice.
         | 
         | This is something I tend to consider far, far worse than "AI
         | Slop" in practice. I always hated Microsoft Enterprise
         | Library's Data Access Application Block (DAAB) in practice.
         | I've literally only ever seen one product that supported
         | multiple database backends that necessitated that level of
         | abstraction... but I've seen that library well over a dozen
         | times in practice. Just as a specific example.
         | 
         | IMO, abstractions should generally serve to make the rest of
         | the codebase reasonable more often than not... abstractions
         | that hide complexity are useful... abstractions that add
         | complexity much less so.
        
         | silisili wrote:
         | > In practice what I see fail most often is not premature
         | optimization but premature abstraction
         | 
         | This matches my experience as well.
         | 
         | Someone here commented once that abstractions should be
         | emergent, not speculative, and I loved that line so much I use
         | it with my team all the time now when I see the craziness
         | starting.
        
           | hugey010 wrote:
           | I completely agree with you, and that is an amazing quote.
        
           | senderista wrote:
           | "Abstractions should be written in blood"
        
         | fl0ki wrote:
         | I only agree if you have a bounded dataset size that you know
         | will never grow. If it can grow in future (and if you're not
         | sure, you should assume it can), not only will many data
         | structures and algorithms scale poorly along the way, but they
         | will grow to dominate the bottleneck as well. By the time it no
         | longer meets requirements and you get a trouble ticket, you're
         | now under time pressure to develop, qualify, and deploy a new
         | solution. You're much more likely to encounter regressions when
         | doing this under time pressure.
         | 
         | If you've been monitoring properly, you buy yourself time
         | before it becomes a problem as such, but in my experience most
         | developers who don't anticipate load scaling also don't monitor
         | properly.
         | 
         | I've seen a "senior software engineer with 20 years of industry
         | experience" put code into production that ended up needing 30
         | minute timeouts for a HTTP response only 2 years after initial
         | deployment. That is not a typo, 30 minutes. I had to take over
         | and rewrite their "simple" code to stop the VP-level
         | escalations our org received because of this engineering
         | philosophy.
        
           | 9rx wrote:
           | _> You 're much more likely to encounter regressions when
           | doing this under time pressure._
           | 
           | There is nothing to suggest you should wait to optimize under
           | pressure, only that you should optimize only after you have
           | measured. Benchmark tests are still best written during the
           | development cycle, not while running hot in production.
           | 
           | Starting with the naive solution helps quickly ensure that
           | your API is sensible and that your testing/benchmarking is in
           | good shape before you start poking at the hard bits where you
           | are much more likely to screw things up, all while offering a
           | baseline score to prove that your optimizations are actually
           | necessary and an improvement.
        
         | munk-a wrote:
         | As someone who believes strongly in type based programming and
         | the importance of good data structure choice I'm not seeing how
         | Rule 5 follows Rule 1. I think it's important to reinforce how
         | impactful good data structure choice is compared to trying to
         | solve everything through procedural logic since a well
         | structured coordination of data interactions can end up greatly
         | simplifying the amount of standalone logic.
        
           | astrobe_ wrote:
           | Data cache issues is one case of something being surprising
           | slow because of how data is organized. That said, Structure
           | of Arrays vs Array of structures is an example where rule 4
           | and 5 somewhat contradict each other, if one confuses
           | "simple" and "easy" - Structure of Array style is "harder"
           | because we don't see it often; but then if it's harder, it is
           | is likely more bug-prone.
        
           | akkad33 wrote:
           | But good data structure is not always evident from the get
           | go. And if your types are too specific it would make future
           | development hard if the specs change. This is what I struggle
           | with
        
             | munk-a wrote:
             | Professionally I'm a data architect. Modeling data in a way
             | that is functional, performant and forward facing is not an
             | easy problem so it's perfectly fine to struggle with it. We
             | do our best job with what we've got within reasonable
             | constraints - we can't do anything more than that.
             | 
             | I found that over time my senses have been honed to more
             | quickly identify things that are important to deeply study
             | and plan right now and areas where I can skimp more and fix
             | it later if problems develop. I don't know if there was a
             | short cut to honing those senses that didn't involve a lot
             | of pain as I needed to pick apart and rework oversights.
        
         | mkehrt wrote:
         | This comment is fascinating to me, as it indicates an entirely
         | different mindset than mine. I'm much more interested in code
         | readability and maintainabilty (and simplicty and elegance)
         | than performance, unless it's necessary. So I would start by
         | saying everything flows from rule 4 or maybe 5. Rule 1 is a
         | consequence of rule 4 for me.
        
           | Eiriksmal wrote:
           | Maybe it's because the comment you are replying to is from a
           | new account posting paragraphs of LLMese in multiple comments
           | in the same minute. It's unsurprising that soulless LLM
           | output doesn't match your mindset!
        
             | gowld wrote:
             | That account has posted 3 comments in 3 hours.
             | 
             | https://news.ycombinator.com/threads?id=ryguz
        
         | pc86 wrote:
         | I was just dealing with this is some home-grown configuration
         | nightmare where every line of the file was pulled from some
         | other namespace to the point where you end up with two dozen
         | folders, each with half a dozen partial configuration files in
         | them, and it takes half a hour to figure out where a single
         | value is coming from.
         | 
         | I'm sure it's super flexible but the exactly same thing could
         | have been achieved with 8 YAML files and 60% of the content
         | between them would be identical.
        
         | hugey010 wrote:
         | Premature abstraction is one of the worst pitfalls when writing
         | software. It's paid for up front, it costs developer time to
         | understand and work with, it adds complexity (tech debt),
         | increases likeliness of bugs, and increases refactor time. All
         | for someone to say "if we ever want to do X". If we wanted to
         | do it, we'd do it now.
         | 
         | I truly believe this comes from devs who want to feel smart by
         | "architecting" solutions to future problems before those
         | problems have become well defined.
        
       | tracker1 wrote:
       | Pretty much live by these in practice... I've had a lot of
       | arguments over #3 though... yes nested loops can cause
       | problems... but when you're dealing with < 100 or so items in
       | each nested loop and outer loop, it's not a big deal in practice.
       | It's simpler and easier to reason with... don't optimize unless
       | you really need to for practical reasons.
       | 
       | On #5, I think most people tend to just lean on RDBMS databases
       | for a lot of data access patterns. I think it helps to have some
       | fundamental understandings in terms of where/how/why you can
       | optimize databases as well as where it make sense to consider
       | non-relational (no-sql) databases too. A poorly structured
       | database can crawl under a relatively small number of users.
        
       | jkaptur wrote:
       | It's interesting to contrast "Measure. Don't tune for speed until
       | you've measured" with Jeff Dean's "Latency Numbers Every
       | Programmer Should Know" [0].
       | 
       | Dean is saying (implicitly) that you _can_ estimate performance,
       | and therefore you can design for speed a priori - without
       | measuring, and, indeed, before there is anything to measure.
       | 
       | I suspect that both authors would agree that there's a happy
       | medium: you absolutely can and should use your knowledge to
       | design for speed, but given an implementation of a reasonable
       | design, you need measurement to "tune" or improve incrementally.
       | 
       | 0: https://gist.github.com/jboner/2841832
        
         | eschneider wrote:
         | I mean...you should always design with speed in mind (In that
         | Jeff Dean sense :) but what 'premature optimization' is
         | referring to, is more like localized speed optimizations/hacks.
         | Don't do those until a) you know you'll need it and b) you know
         | where it will help.
        
         | sifar wrote:
         | Yeah, the latency numbers provide a ceiling for your algorithm.
         | The actual performance depends on the implementation, code
         | generation, runtime hazards, small dependencies one may have
         | overlooked etc.
        
         | SatvikBeri wrote:
         | I've had the pleasure of working with some truly fast pieces of
         | code written by experts. It's always both. You have to have a
         | good sense of what's generally fast and what's not in order to
         | design a system that doesn't contain intractable bottlenecks.
         | And once you have a good design you can profile and optimize
         | the remaining constraints.
         | 
         | But e.g. if you want to do fast math, you really need to design
         | your pipeline around cache efficiency from the beginning - it's
         | very hard to retrofit. Whereas reducing memory allocations in
         | order to make parallel algorithms faster is something you can
         | usually do after profiling.
        
       | PaulHoule wrote:
       | The "bottleneck" model of performance has limitations.
       | 
       | There are a lot of systems where useless work and other
       | inefficiencies are spread all over the place. Even though I think
       | garbage collection is underrated (e.g. Rustifarians will agree
       | with me in 15 years) it's a good example because of the
       | nonlocality that profilers miss or misunderstand.
       | 
       | You can make great prop bets around "I'll rewrite your Array-of-
       | Structures code to Structure-of-Arrays code and it will get much
       | faster"
       | 
       | https://en.wikipedia.org/wiki/AoS_and_SoA
       | 
       | because SoA usually is much more cache friendly and AoS makes the
       | memory hierarchy perform poorly in a way profilers can't see. The
       | more time somebody spends looking at profilers and more they
       | quote Rule 1 the more they get blindsided by it.
        
       | okamiueru wrote:
       | Rule 1 seems similar to Donald Knuths "premature optimization"
       | from 1974.
       | 
       | > Programmers waste enormous amounts of time thinking about, or
       | worrying about, the speed of noncritical parts of their programs,
       | and these attempts at efficiency actually have a strong negative
       | impact when debugging and maintenance are considered. We should
       | forget about small efficiencies, say about 97% of the time:
       | premature optimization is the root of all evil. Yet we should not
       | pass up our opportunities in that critical 3%.
       | 
       | Rule 2 follows rule 1.
       | 
       | Rule 3 & 4 is a variation of Keep it Simple, Stupid (KISS) from
       | the 1960s.
       | 
       | ... and... now I feel stupid, because I read the last part, which
       | is summarizing it in the same way.
        
       | dreko wrote:
       | Later never comes" is true, but the fix isn't to optimize early,
       | it's to write code simple enough that optimization is easy when
       | later finally does come. That's what Rule 5 is really about. Get
       | the data structures right and the rest is tractable.
        
       | munro wrote:
       | > Rule 5. Data dominates. If you've chosen the right data
       | structures and organized things well, the algorithms will almost
       | always be self-evident. Data structures, not algorithms, are
       | central to programming.
       | 
       | It's so true, when specing things I always try to focused on DDL
       | because even the UI will fall into place as well, and a place I
       | see claude opus fail as well when building things.
        
         | cleaver wrote:
         | I recall a similar statement from Ed Yourdon in one of his
         | books (90's?)
        
           | EvanAnderson wrote:
           | The article makes reference to Fred Brooks and "The Mythical
           | Man Month", but doesn't make a direct quote. The quote I'd
           | have referenced is:
           | 
           | "Show me your flowchart and conceal your tables, and I shall
           | continue to be mystified. Show me your tables, and I won't
           | usually need your flowchart; it'll be obvious." -- Fred
           | Brooks, The Mythical Man Month (1975)
        
       | oxag3n wrote:
       | > Rule 5. Data dominates. If you've chosen the right data
       | structures and organized things well, the algorithms will almost
       | always be self-evident. Data structures, not algorithms, are
       | central to programming.
       | 
       | I'm a big fan of Data Oriented Design. Once you conceptualize how
       | data is stored and transformed in your program, it just has to be
       | reflected in data structures that make it possible.
       | 
       | Modern design approaches tend to focus on choosing a right
       | abstraction like columnar/row layout, caching etc. They mostly
       | fail to optimally work with the data. Optimal in this case
       | meaning getting most of all underlying hardware capabilities, for
       | example reading large and preferably continuous blocks of data
       | from magnetic storage, parallel data processing, keeping
       | intermediate results in CPU caches, utilizing all physical SSD
       | queues.
        
         | aaronblohowiak wrote:
         | The fundamental tension between nouns and verbs and the
         | attempts to unify them like events have made programming a long
         | art form to study.
         | 
         | It's all use-case and priority-specific, and I think the more
         | varied your experience and more tools you have in the tool
         | belt, the better off you can be to bring the right solution to
         | bear. Of course, then you think you have the right solution in
         | mind (lets say using partitions in postgres for something) but
         | you find the ORM your service is using doesn't support it, then
         | what is "best" becomes not only problem-specific but also tool-
         | specific. Finally, even if you have the best solution and your
         | existing ecosystem supports it but the rest of the engineering
         | staff you have is unfamiliar with it, it may again no longer be
         | "best".
         | 
         | this ladder of problem-fit, ecosystem-fit, staffing-fit is
         | something I have grappled with in my career.
         | 
         | LLMs are only so-so at any of the above (even when including
         | the agent as "staff".)
        
       | ryguz wrote:
       | Rule 5 about data dominating resonates most in modern systems.
       | The trend of just throwing more code at it when most performance
       | and correctness issues come down to how data flows through the
       | system. Most junior engineers optimize the wrong layer because
       | they start with the code instead of the data model.
        
       | makeitrain wrote:
       | Here's the modern version: https://grugbrain.dev/
        
       | sunnyos wrote:
       | Seem logical
        
       | awesome_dude wrote:
       | I received some 'interesting' feedback when I spoke about
       | commenting that I was using an O(n) search instead of an O(log n)
       | algorithm because of the normally small size of n [0]
       | 
       | What I should have done was point to Rob's third rule (either in
       | my comment or in the resulting threads)
       | 
       | [0]
       | https://news.ycombinator.com/threads?id=awesome_dude&next=47...
        
       | IvyMike wrote:
       | Once upon a time in the 90's I was at work at 2am and I needed to
       | implement a search over a data set. This function was going to be
       | eventually called for every item, thus if I implemented it as a
       | linear search, it would be n^2 behavior. Since it was so late and
       | I was so tired, I marked it as something to fix later, and just
       | did linear search.
       | 
       | Later that week, now that things were working, I profiled the n^2
       | search. The software controlled a piece of industrial test
       | equipment, and the actual test process would take something
       | around 4 hours to complete. Using the very worst case, far-
       | beyond-reasonable data set, if I left the n^2 behavior in, would
       | have added something like 6 seconds to that 4 hour runtime.
       | 
       | (Ultimately I fixed it anyways, but because it was easy, not
       | because it mattered.)
        
         | senderista wrote:
         | For small enough n, linear search might have been faster.
        
         | bsder wrote:
         | The problem with O(n^2) algorithms is that they are fast enough
         | to get into production and slow enough to explode in
         | production.
        
       | jancsika wrote:
       | Can you actually follow rule #1 for things like realtime audio
       | programming?
        
       | eichin wrote:
       | Heh, in the early days of C++ (1990ish) I had a notable
       | application of 3+4 involving a doubly linked list with cache
       | pointers (time-sequence data browser so references were likely
       | "nearby" as the user zoomed in; spec was to handle streaming data
       | eventually.) Had problems with it crashing in pointer-related
       | ways (in 1990, _nobody_ had a lot of C++ experience) so I cooked
       | up a really dumb  "just realloc an array" version so I could
       | figure out if the problem was above or below data structure...
       | and not only didn't the "dumb" version crash, it was also much
       | faster (and of faster order!) due to amortized realloc - doing a
       | more expensive operation much less often turns out to be a really
       | good trick :-)
        
       | rsc wrote:
       | Worth noting these were not written as rules of programming
       | generally but rules specifically targeted at complexity. They are
       | lifted from the "Complexity" section of Rob's "Notes on
       | Programming in C".
       | 
       | https://www.lysator.liu.se/c/pikestyle.html
       | http://www.literateprogramming.com/pikestyle.pdf
        
       | up2isomorphism wrote:
       | Even agree with most of the stuff he said, however in real life,
       | you won't be able to win a fight using these arguments. You can
       | only create a environment to execute these strategies first to
       | get a good product and them use them as a propaganda afterwards.
        
       | nelsonfigueroa wrote:
       | > Data structures, not algorithms, are central to programming
       | 
       | I'm a big time leetcode interview hater and reading that felt
       | validating. Why the f*ck am I always asked about algorithms.
        
       ___________________________________________________________________
       (page generated 2026-03-18 23:00 UTC)