Skip to content
HomeVideosBooks
AllTopicsTrends
BlogsPodcasts
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
    Cover of The design and evolution of C[plus plus]

    The design and evolution of C[plus plus]

    Bjarne Stroustrup · 1994

    This book focuses on the principles, process, and decisions made during the development of the C++ programming language. As the "inventor" of the language, Stroustrup presents his unique insight into the decisions which resulted in the features of C++--the universally praised, the controversial, and even some of the rejected ones. The book provides a solid introduction to OOP and C++ for beginners.

    Programming
    Open LibraryAmazon
    Stats for nerds
    38recommend
    120mentions
    68people
    2008–2026years
    51% recommend48% neutral2% critical

    Mentions per year

    2008201020122014201620182020202220242026

    What Hacker News says

    1. seertaakFeb 2026
      Sure! First, here are references, in case you want to deep dive:

      1. http://lucacardelli.name/Papers/Binary.pdf

      2. https://www.researchgate.net/publication/221321423_Parasitic...

      Second, asymmetric multimethods give something up: symmetry is a desirable property -- it's more faithful to mathematics, for instance. There's a priori no reason to preference the first argument over the second.

      So why do I think they are promising?

      1. You're not giving up that much. These are still real multimethods. The papers above show how these can still easily express things like multiplication of a band diagonal matrix with a sparse matrix. The first paper (which focuses purely on binary operators) points out it can handle set membership for arbitrary elements and sets.

      2. Fidelity to mathematics is a fine thing, but it behooves us to remember we are designing a programming language. Programmers are already familiar with the notion that the receiver is special -- we even have a nice notation, UFCS, which makes this idea clear. (My language will certainly have UFCS.) So you're not asking the programmer to make a big conceptual leap to understand the mechanics of asymmetric multimethods.

      3. The type checking of asymmetric multimethods is vastly simpler than symmetric multimethods. Your algorithm is essentially a sort among the various candidate multimethod instances. For symmetric multimethods, choosing which candidate multimethod "wins" requires PhD level techniques, and the algorithms can explode exponentially with the arity of the function. Not so with asymmetric multimethods: a "winner" can be determined argument by argument, from left to right. It's literally a lexicographical sort, with each step being totally trivial -- which multimethod has a more specific argument at that position (having eliminated all the candidates given the prior argument position). So type checking now has two desirable properties. First, it design principle espoused by Bjarne Stroustroup (my personal language designer "hero"): the compiler implementation should use well-known, straightforward techniques. (This is listed as a reason for choosing a nominal type system in Design And Evolution of C++ -- an excellent and depressing book to read. [Because anything you thought of, Bjarne already thought of in the 80s and 90s.]) Second, this algorithm has no polynomial or exponential explosion: it's fast as hell.

      4. Aside from being faster and easier to implement, the asymmetry also "settles" ambiguities which would exist if you adopted symmetric multimethods. This is a real problem in languages, like Julia, with symmetric multimethods. The implementers of that language resort to heuristics, both to avoid undesired ambiguities, and explosions in compile times. I anticipate that library implementers will be able to leverage this facility for disambiguation, in a manner similar to (but not quite the same) as C++ distinguishes between forward and random access iterators using empty marker types as the last argument. So while technically being a disadvantage, I think it will actually be a useful device -- precisely because the type checking mechanism is so predictable.

      5. This predictability also makes the job of the programmer easier: they can form an intuition of which candidate method will be selected much more readily in the case of asymmetric multimethods than symmetric ones. You already know the trick the compiler is using: it's just double-dispatch, the trick used for "hit tests" of shapes against each other. Only here, it can be extended to more than two arguments, and of course, the compiler writes the overloads for you. (And it won't actually write overloads, it will do what I said above: form a lexicographical sort over the set of multimethods, and lower this into a set of tables which can be traversed dynamically, or when the types are concrete, the compiler can leverage monomorphize -- the series of "if arg1 extends Tk" etc. is done in the compiler instead of at runtime. (But it's the same data structure.)

      6. It's basically impossible to do separate compilation using symmetric multimethods. With asymmetric multimethods, it's trivial. To form an intuition, simply remember that double-dispatch can easily be done using separate compilation. Separate compilation is mentioned as a feature in both the cited papers. This is, in my view, a huge advantage. I admit, this I haven't quite figured out generics will fit into this -- at least if you follow C++'s approach, you'll have to give up some aspects of separate compilation. My bet is that this won't matter so much; the type checking ought to be so much faster that even when a template needs to be instantiated at a callsite, the faster and simpler algorithm will mean the user experience will still be very good -- certainly faster than C++ (which uses a symmetric algorithm for type checking of function overloads).

      To go a bit more into my "vision" -- the papers were written during a time when object-orientation was the dominant paradigm. I'd like to relax this somewhat: instead of classes, there will only be structs. And there won't be instance methods, everything will be a multimethods. So instead of the multimethods being "encapsulated" in their classes, they'll be encapsulated in the module in which they're defined. I'll adopt the Python approach where everything is public, so you need to worry about accessibility. Together with UFCS, this means there is no "privileging" of the writer of a library. It's not like in C++ or Java, where only the writer of the library can leverage the succinct dot notation to access frequently used methods. An extension can import a library, write a multimethod providing new functionality, and that can be used -- using the exact same notation as the methods of the library itself. (I always sigh when I read languages, having made the mistake of distinguishing between free functions and instance methods, "fix" the problem that you can only extend a library from the outside using free functions -- which have a less convenient syntax -- by adding yet another type of function, an "extension function. In my language, there are only structs and functions -- it has the same simplicity as Zig and C in this sense, only my functions are multimethods.)

      Together with my ideas for how the parser will work, I think this language will offer -- much like Julia -- attractive opportunities to extend libraries -- and compose libraries that weren't designed to work "together".

      And yeah, Claude Code and Gemini are going to implement it. Probably in Python first, just for initial testing, and then they'll port it to C++ (or possibly self-host).

      thread
    2. dkarlNov 2025
      The Design and Evolution of C++ by Stroustrup is a fascinating book. It only covers the early years of C++, but that's perhaps what you're most interested in.
      thread
    3. AnonCFeb 2025
      Thank you. It would be interesting to read the history, including the design decisions, the influences (and distractions), the trade offs, etc.

      When I read “The Design and Evolution of C++”, it gave me a better understanding of the language.

      thread
    4. layer8Feb 2025
      Hindsight is 20/20. It wasn’t perceived that way back then. Every C++ feature had a well-reasoned rationale of solving an important problem. (I found the book “The Design and Evolution of C++” worth reading, although that was some time ago.) The only handicap requiring compromises was backwards compatibility with C, but that was also a major reason why it became so successful.

      I’m sure that Rust will continue to become more complex, and in 20–30 years another systems language will likely come along that is at least as safe while being easier to work with again.

      thread
    5. pjmlpJun 2024
      Many of the original C++ decisions come back to how it was supposed to be Typescript for C, which was a reason why it became widely used, and why some warts are the way they are.

      Like having C structs magically turn into C++ ones, thus implicit rules like these.

      Anyone that cares about C++ evolution should read "Design and Evolution of C++", not only for how it came to be, also for safety approaches over plain C, that Bjarne is stil arguing for to this day on WG21 meetings.

      thread
    6. qalmakkaMay 2024
      This. The obsession for object oriented in the '00s has made immense, irreparable damage to an entire generation of developers. I have to fight every day to keep our codebase sane against new entries that are still following that cargo cult that "everything must have an interface".

      I literally had an argument a few days ago with a junior that was dead set on saying that writing single-purpose functions in a C++ namespace was bad. In his own opinion "that should be a class or at least a static member function"...

      It's basically as if most developers have a natural tendency to writing all code as if it was Java - because they have learnt so many "patterns" that only make sense in a Java world. The irony is that often they do not realise that Java is not, in fact, a "proper" object-oriented programming language (like Smalltalk for instance), but rather a formalisation of all those quirky hacks C++ implemented [1].

      [1]: I recommend "Design and Evolution of C++" by Stroustrup - it's a great insight on how lots of things we now give for granted in "modern OOP" were actually hacks he had to introduce in order to merge Simula's model with C.

      thread

    Related

    Cover of The C++ programming language
    2008–2026

    The C++ programming language

    Bjarne Stroustrup
    19 recommend · 49
    Cover of A Tour of C++
    2013–2026

    A Tour of C++

    Bjarne Stroustrup
    65 recommend · 150
    Cover of Beautiful C++
    2022–2025

    Beautiful C++

    John Davidson
    1 recommend · 3
    Cover of API design for C++
    2011–2022

    API design for C++

    Martin Reddy
    6 recommend · 8
    Cover of Inside the C⁺⁺ object model
    2010–2026

    Inside the C⁺⁺ object model

    Stanley B. Lippman
    7 recommend · 14
    Large-Scale C++ Volume IIJohn Lakos
    2020–2026

    Large-Scale C++ Volume II

    John Lakos
    1 recommend · 2
    Cover of The New C Standard
    2018–2022

    The New C Standard

    Derek M. Jones
    2 recommend · 2
    Cover of The annotated C++ reference manual
    2013–2026

    The annotated C++ reference manual

    Margaret A. Ellis
    2 recommend · 13