Skip to content
HomeVideosBooksBlogs
AllTop postsTopics
Podcasts
HistoryListsWatch laterLiked videosFollowing

The videos, books, blogs and podcasts Hacker News keeps recommending, all in one place.

VideosBooksBlogsPodcastsAboutPrivacySettings

Data from Hacker News, HackerTube, HackerBooks, HackerBlogs and Open Library. Credits · Not affiliated with Y Combinator.

HomeVideosBooksBlogsPodcasts
Ctrl K

    Sandi Metz

    sandimetz.com · Personal blog · on HN since 2014

    Sandi Metz, author on object-oriented design, writes about abstraction, code evolution and Ruby, and is known for her books on code design.

    Visit blogHN submissions
    ProgrammingWriting & Thinking
    What HN says

    HN commenters repeatedly cite "The Wrong Abstraction" as a classic and recommend her books on code design.

    Stats for nerds
    95HN people shared it
    32linked in comments
    2.5Kstory points
    Jul 2026last shared
    2016people per year2026

    Top posts on HN

    1. 1
      The Wrong Abstraction (2016)
      62 people · 1.7K points · first shared 2016 · 240 comments on HN
    2. 2
      99 Bottles of OOP now available in Python
      13 people · 422 points · first shared 2016 · 86 comments on HN
    3. 3
      Prefer duplication over the wrong abstraction
      1 person · 204 points · first shared 2016 · 96 comments on HN
    4. 4
      The Half-Life of Code (2017)
      4 people · 66 points · first shared 2017 · 5 comments on HN
    5. 5
      What Does OO Afford?
      4 people · 9 points · first shared 2018 · Discussion on HN
    6. 6
      How Shall We Define Design?
      1 person · 9 points · first shared 2020 · Discussion on HN
    7. 7
      Why we argue style
      2 people · 4 points · first shared 2017 · Discussion on HN
    8. 8
      The Wrong Abstraction
      1 person · 3 points · first shared 2017 · Discussion on HN
    9. 9
      Ruby – Suspicions of nil
      1 person · 3 points · first shared 2015 · Discussion on HN
    10. 10
      Breaking Up the Behemoth – How Applications Evolve
      3 people · 2 points · first shared 2017 · Discussion on HN

    What HN people wrote when they linked it

    • MawrJul 2023

      > I'm not sure why you think that quoting random HN users proves anything except personal opinions of specific people? These are fine, but other people have other opinions.

      They support my argument so I included them. I don't see a practical difference between a "random HN user" and a random blog post or anything else. A good idea is a good idea, regardless of the medium.

      > I don't oppose the "principles" you've quoted, but they would just as easily apply to e.g. Haskell

      Possibly, I threw it together pretty quickly, so it's not very thought-out.

      > (maybe except for the "there's only one way to do it" which however has never been true of any language, including Python).

      It's not binary, but a spectrum. No language has just literally one way to express each concept. However, Python is definitely further towards the "one way to do it" end of the scale. Perhaps not as much these days as it used to, but still far more than for example Ruby or Perl.

      > I feel like you missed my larger point. It's not terribly difficult to write code that you can understand line by line. It's incredibly hard to write a huge code base in a way that you can reason about many code paths simultaneously, however. That's where the abstractions start to make sense.

      I thought I adressed that; everything I mentioned - explicit error returns, pure functions, no global state, and no metaprogramming - all show their true worth in large and/or unfamiliar codebases.

      > I don't understand why people think…

    • TainnorJul 2023

      > I thought I adressed that; everything I mentioned - explicit error returns, pure functions, no global state, and no metaprogramming - all show their true worth in large and/or unfamiliar codebases.

      I agree with all of those. I try to avoid these things whenever I write code (in rare cases, there are valid reasons for using them, but I agree they are overused).

      But that still leaves tons of room for different ways of writing code, and it's very hard to say which one of these is "obvious". Obvious to whom? Some people want to have large methods, so they can see everything at a glance, others prefer to have more smaller function so they can see the high-level picture before they see the details. Which one of them is right? I can't say - it depends on the person, on the problem, and on many other factors.

      What is missing from your list is "don't use advanced language features". You can do all the things you mentioned and still use "advanced" language features. And the debate about Go is often about how (presumably) the absence of "complex" features (something which is IMHO a bit subjective) makes code more "obvious".

      But you can have generics (or, more broadly, polymorphism), interfaces, higher order functions, proper algebraic data types, etc. and still uphold all the features you've quoted. That's what I meant with the Haskell comment (but supposedly the same would be true for e.g. Lisp).

      Since you shared a talk with me (which I intend to watch, but I haven't had time…

    • svieiraJul 2022

      This is discussed in detail in "The Wrong Abstraction" by Sandi Metz

      https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction

      Quote follows:

      ----

      The strength of the reaction made me realize just how widespread and intractable the "wrong abstraction" problem is. I started asking questions and came to see the following pattern:

      1. Programmer A sees duplication.

      2. Programmer A extracts duplication and gives it a name.
      This creates a new abstraction. It could be a new method, or perhaps even a new class.

      3. Programmer A replaces the duplication with the new abstraction.
      Ah, the code is perfect. Programmer A trots happily away.

      4. Time passes.

      5. A new requirement appears for which the current abstraction is almost perfect.

      6. Programmer B gets tasked to implement this requirement.
      Programmer B feels honor-bound to retain the existing abstraction, but since isn't exactly the same for every case, they alter the code to take a parameter, and then add logic to conditionally do the right thing based on the value of that parameter. What was once a universal abstraction now behaves differently for different cases.

      7. Another new requirement arrives.
      Programmer X.
      Another additional parameter.
      Another new conditional.
      Loop until code becomes incomprehensible.

      8. You appear in the story about here, and your life takes a dramatic turn for the worse.

      Existing code exerts a powerful influence. Its very presence argues that it is both correct and necessary. We know that…

    • a4ismsFeb 2023

      I feel there are two separate things going on:

      First, the question of deduplication a/k/a normalization. Deduplication is cheap, and it's "a two-way door, not a one-way turnstile:" It's cheap to re-duplicate when you find that one of the users of your de-duplicated function or whatever needs new behaviour.

      Second, there is the question of the right versus wrong abstraction: If two different things use the same thing, that doesn't necessarily mean that they share the same abstraction conceptually. But of course, sometimes the duplication is a hint that there is some semantic commonality, and when you get this right, it's glorious, but if instead of de-duplicating we actually build the wrong abstraction, it can be extremely expensive to fix. That's more of a "one-way turnstile" problem.

      To me, when I see code that could be "DRY'd up," I have to ask myself whether it represents an opportunity to write a better abstraction, but I treat that decision conservatively, because of the cost of getting it wrong. In many cases, I choose to de-duplicate the code without creating what might be "the wrong abstraction," and it is often less expensive and lower risk to start there and only later consider abstractioneering.

      p.s. The tension between de-duplication and abstractioneering resembles the tension between is-a and has-a, often expressed by classical OO programmers as "inheritance" In those terms, I'm really describing my inclination as "Prefer composition to inheritance by…

    • pure-awesomeJan 2020

      I used to think that if something is done twice, it should be abstracted.

      Now, I'm a bit more careful. There's a pretty famous quote by Sandi Mentz: "Duplication is far cheaper than the wrong abstraction."

      https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction

      Make sure that you're picking the write way to think about the task at hand, rather than blindly following DRY.

      There are times when even a single instance of a code call would be made clearer with abstraction, and there are times where having the same piece of code duplicated multiple times (or duplicated with one piece changed) is far clearer than trying to abstract it.

      This Reddit Comment also has an interesting take:
      https://www.reddit.com/r/programming/comments/5txp5t/duplication_is_far_cheaper_than_the_wrong/ddq5ykf

      > The main purpose of abstractions is not to remove or reduce duplication, and not even to make code "reusable"; it is to make semantic patterns and assumptions explicit and, if possible, first-class.

      The further comments provide more discussion.

      ---

      I agree with the rest of your comment that refactoring and code-cleanup should be done in pieces and that, as with everything, striking the right balance is key.

    • donwJun 2020

      The short answer is: don't design for future use-cases.

      Period.

      Instead, only build what you need to solve the problems you have in-hand, but do so in such a way that your software and your systems are as easy to change as possible in the future.

      Because you very, very rarely know what your future use-cases really are. Markets change over time, and your understanding of the market will also shift, both because some of your assumptions were wrong, and because you can never really have a total understanding of such a complex phenomenon.

      Your business needs will change as well; your top priority from 2019 is likely very different than it is today.

      That is why you build to embrace change, rather than barricade against it.

      As to how, I'd start with Sandi Metz's 99 Bottles of OOP: https://www.sandimetz.com/99bottles

      Learning to write readable code is also pretty important; Clean Code is a good starting point (https://amzn.to/3168z3A), but I'd be keen to know of any shorter books that cover the same materials.

      Growing Object-Oriented Software Guided By Tests (GOOSGT) is a good read as well: https://amzn.to/3du1sEL

    Related

    Nathaniel J. Smithvorpus.org123 people

    Why does calloc exist?

    Nathaniel J. Smith
    Personal · last shared 2026
    Sicperssicpers.info50 people

    Inheritance Often Doesn't Make Sense

    Sicpers
    Personal · last shared 2026
    Wingologwingolog.org237 people

    FFS SSL

    Wingolog
    Personal · last shared 2026
    Tomas Petricektomasp.net152 people

    Write your own Excel in F# (2018)

    Tomas Petricek
    Personal · last shared 2026
    Arthur O'Dwyerquuxplusone.github.io64 people

    Slack’s new WYSIWYG input box is terrible

    Arthur O'Dwyer
    Personal · last shared 2026
    cor3ntincor3ntin.github.io32 people

    The Problem with C (2020)

    cor3ntin
    Personal · last shared 2026
    One Useful Thingoneusefulthing.org104 people

    No elephants: Breakthroughs in image generation

    One Useful Thing
    Personal · last shared 2026
    Bertrand Meyerbertrandmeyer.com47 people

    Introduction to the Theory of Programming Languages (1991)

    Bertrand Meyer
    Personal · last shared 2026