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
    L

    Laurence Tratt

    tratt.net · Personal blog · on HN since 2008

    Laurence Tratt, a computer science researcher, writes about programming language implementation, VMs, parsing, and benchmarking methodology.

    Visit blogRSSHN submissions
    Languages & CompilersSystems & PerformanceProgramming
    What HN says

    HN links his posts on parsing being an unsolved problem and on why minimum times mislead in benchmarking, both cited as clear explanations.

    Stats for nerds
    130HN people shared it
    229linked in comments
    6.6Kstory points
    Jan 2026last shared
    2011people per year2026

    Top posts on HN

    1. 1
      Using a "proper" camera as a webcam
      1 person · 575 points · first shared 2022 · 487 comments on HN
    2. 2
      How can C Programs be so Reliable?
      4 people · 367 points · first shared 2008 · 152 comments on HN
    3. 3
      How I clean my glasses
      1 person · 314 points · first shared 2022 · 328 comments on HN
    4. 4
      Better Shell History Search
      2 people · 278 points · first shared 2025 · 93 comments on HN
    5. 5
      Why Aren’t More Users More Happy With Our VMs? Part 1 (2018)
      5 people · 267 points · first shared 2018 · 88 comments on HN
    6. 6
      How can C Programs be so Reliable? (2008)
      1 person · 251 points · first shared 2013 · 221 comments on HN
    7. 7
      Practising Programming
      4 people · 236 points · first shared 2022 · 41 comments on HN
    8. 8
      UML: My Part in Its Downfall
      1 person · 233 points · first shared 2022 · 241 comments on HN
    9. 9
      Fast enough VMs in fast enough time
      8 people · 229 points · first shared 2012 · 33 comments on HN
    10. 10
      Parsing: the solved problem that isn't
      3 people · 200 points · first shared 2011 · 47 comments on HN

    What HN people wrote when they linked it

    • ZababaJun 2022

      > new books should use more modern popular languages to age well and to attract younger audience

      That doesn't make sense. Java is one of the most popular programming language, more popular than a lot of other "modern popular languages". The only languages more popular are either as old as Java (JavaScript, Python) or older (C, C++). C# might be one option, but it's close to Java, and I don't know if the support for Linux/MacOS was here at the time this book was started. Same thing for JavaScript and Python's popularity, which are relatively recent trends. On the other hand, Java has stayed and endured. It's still here and will still probably be here in 20 years.

      > on the JVM there are languages better suited for the topic (e.g. Scala by a large margin)

      Scala is less popular than Java, and harder to master. Once you consider Scala, you get into endless arguments about whether to use Scala, SML, OCaml, Haskell, etc.

      > There's already the "Language Implementation Patterns" book

      There is also "Writing an interpreter in Go" and "Writing a compiler in Go" that seem to cover the same ground. But I'm certain than more people know about interpreters and compilers thanks to these three books than thanks to any one of them.

      > but also gives you real life skills (e.g. ANTLR is used in most big data query engines)

      The majority of programming languages don't use a generated parser but a handmade recursive descent parser, because it's the best at error reporting. There's a good post…

    • feznyngJan 2026

      LSPs rely on a parser to generate an AST for a given language. This parser needs to be error-tolerant because it needs to return usable ASTs despite often parsing incomplete, incorrect code and fast enough to run on every keystroke so it can provide realtime feedback.

      Most of the time they rely on their own hand-rolled recursive descent parser. Writing these isn't necessarily hard but time-consuming and tedious especially if you're parsing a large language like C++.

      Parser generators like yacc, bison, chumsky, ANTLR etc. can generate a parser for you given a grammar. However these parsers usually don't have the best performance or error reporting characteristics because they are auto-generated. A recursive descent parser is usually faster and because you can customize syntax error messages, easier for an LSP to use to provide good diagnostics.

      Tree-sitter is also a parser generator but has better error tolerance properties (not quite as good as hand-written but generally better than prior implementations). Additionally, its incremental meaning it can reuse prior parses to more efficiently create a new AST. Most hand-written parsers are not incremental but are usually still fast enough to be usable in LSPs.

      To use tree-sitter you define a grammar in JavaScript that tree-sitter will use to generate a parser in C which you can then use a dynamic or static library in your application.

      In your case, this is useful because you can compile down those C libraries to WASM which…

    • kragenMar 2011

      PEGs are one class of cleanly composable grammars. OMeta uses that attribute of theirs to great advantage. And PEGs are, formally speaking, parsable in worst-case linear time, although whether that linear time is fast enough to be practical is still unknown, and it also potentially uses large linear space. I hope it's not vulgar to post yet another link to my minimal PEG parser generator in one page of code: https://github.com/kragen/peg-bootstrap/blob/master/peg.md

      In particular, the example here of embedding SQL in C would be pretty trivial to do as a PEG.

      PEGs can parse some languages that are not context-free — the example from Bryan Ford's thesis is aₓbₓcₓ, where xᵢ means "i repetitions of x". I think there are also context-free languages they can't parse, but I'm not sure.

      (Operator precedence parsing is particularly ugly in PEGs, since by default, they don't support left recursion. The OMeta folks figured out how to cleanly support left recursion in PEGs, but you lose the linear-time guarantee.)

      One very appealing attribute of PEGs is that you can conveniently extend PEGs to support parameterized productions, which could be crucial in building up a library of general-purpose parsing productions that could reasonably be used to shorten the time to define new languages.

      k4st claims in http://news.ycombinator.com/item?id=2330672 that Pratt top-down operator-precedence parsers are also cleanly composable. I didn't know that, and it seems like a surprising claim,…

    • juliangambleAug 2014

      Robert Harper argues that dynamically typed languages are languages of a single Type:

      And this is precisely what is wrong with dynamically typed languages: rather than affording the freedom to ignore types, they instead impose the bondage of restricting attention to a single type! Every single value has to be a value of that type, you have no choice!
      http://existentialtype.wordpress.com/2011/03/19/dynamic-languages-are-static-languages/

      Bob in this same article also wrote the now oft quoted:

      To borrow an apt description from Dana Scott, the so-called untyped (that is “dynamically typed”) languages are, in fact, unityped.

      Now the author of the linked article wrote another piece in 2012 that rebuts this:

      It therefore makes no sense to say that a language is unityped without qualifying whether that relates to its static or dynamic type system. Python, for example, is statically unityped and dynamically multityped; C is statically multityped and dynamically unityped; and Haskell is statically and dynamically multityped. Although it's a somewhat minor point, one can argue (with a little hand waving) that many assembly languages are both statically and dynamically unityped.

      http://tratt.net/laurie/blog/entries/another_non_argument_in_type_systems

      It is worth noting:

      Sam Tobin-Hochstadt argues the uni-typed classification is not very informative in practice.

      The uni-typed theory reveals little about the nature of programming in a dynamically typed language; it's mainly…

    • ltrattApr 2017

      My gut feeling is that one can minimally maintain systems in "forgotten" languages indefinitely if they're basically stable and feature complete. But it seems that people come unstuck for systems that still need to evolve -- even if that evolution is slow and/or sporadic. The obvious alternative is to rewrite systems in new languages, but that is generally prohibitively expensive. Even for those that can afford the expense, the new system tends to not to take considerable time to bed in, so flipping the switch from the old to the new is only for the brave or those with excellent PR departments.

      Although we didn't have this in mind when we started on this work, I've come to think that language composition might offer a way out of this mess (I immodestly offer [1] as an early example). If one composes an old and a new language, one can migrate a system from an old to a new language bit-by-bit. As well as amortising the translation cost, it also means that one can minimise the "switch flipping" problem: disasters seem much less likely if the composed system can be introduced gradually.

      [1] http://tratt.net/laurie/blog/entries/fine_grained_language_composition.html

    • matheusmoreiraJan 2024

      I envy these small and steady improvements!!

      I spent about one week implementing PyPy's storage strategies in my language's collection types. When I finished the vector type modifications, I benchmarked it and saw the ~10% speed up claimed in the paper¹. The catch is performance increased only for unusually large vectors, like thousands of elements. Small vectors were actually slowed down by about the same amount. For some reason I decided to press on and implement it on my hash table type too which is used everywhere. That slowed the entire interpreter down by nearly 20%. The branch is still sitting there, unmerged.

      I can't imagine how difficult it must have been for these guys to write a compiler and succeed at speeding up the Python interpreter.

      ¹ https://tratt.net/laurie/research/pubs/html/bolz_diekmann_tratt__storage_strategies_for_collections_in_dynamically_typed_languages/

    Related

    Software Development Team (King's College London)soft-dev.org20 people

    Garbage collection for Rust: The finalizer frontier

    Software Development Team (King's College London)
    Publication · last shared 2026
    GraalVM Blogmedium.com/graalvm58 people

    Writing memory safe JIT compilers

    GraalVM Blog
    Company · last shared 2026
    Cliff Bifflecliffle.com81 people

    Rewriting m4vgalib in Rust

    Cliff Biffle
    Personal · last shared 2026
    ThePhDthephd.dev112 people

    Embed is in C23

    ThePhD
    Personal · last shared 2026
    Decompositiondecomposition.al20 people

    A CAP tradeoff in the wild

    Decomposition
    Personal · last shared 2026
    Hillel Waynehillelwayne.com294 people

    1/0 = 0

    Hillel Wayne
    Personal · last shared 2026
    Useless Factoruseless-factor.blogspot.com16 people

    Why not mmap?

    Useless Factor
    Personal · last shared 2015
    Chris Wellonsnullprogram.com295 people

    Why Aren't There C Conferences?

    Chris Wellons
    Personal · last shared 2026