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

    Jeremy Bowers

    jerf.org · Personal blog · on HN since 2008

    Jeremy Bowers writes about Go, functional programming, Haskell, and software design, including a monad tutorial and a Go supervisor-tree library.

    Visit blogRSSHN submissions
    ProgrammingLanguages & Compilers
    What HN says

    Commenters recommend his monad tutorial for people tired of tutorials, his functional programming lessons for imperative code, and a post on analyzing failures instead of blaming people.

    Stats for nerds
    78HN people shared it
    66linked in comments
    1.9Kstory points
    Jun 2026last shared
    2009people per year2026

    Top posts on HN

    1. 1
      Functors and Monads for People Who Have Read Too Many “Tutorials”
      9 people · 364 points · first shared 2021 · 248 comments on HN
    2. 2
      Some programming language ideas
      3 people · 253 points · first shared 2025 · 237 comments on HN
    3. 3
      Suture – Supervisor Trees for Go
      8 people · 247 points · first shared 2014 · 38 comments on HN
    4. 4
      Layered Design in Go
      1 person · 141 points · first shared 2025 · 39 comments on HN
    5. 5
      Avoiding Reflection (And Such) in Go
      3 people · 121 points · first shared 2015 · 36 comments on HN
    6. 6
      The Uselessness of "Fast" and "Slow" in Programming
      1 person · 117 points · first shared 2025 · 69 comments on HN
    7. 7
      Review: Learn You a Haskell for Great Good
      2 people · 115 points · first shared 2011 · 18 comments on HN
    8. 8
      Why do we still write insecure software?
      3 people · 70 points · first shared 2015 · 35 comments on HN
    9. 9
      Sum Types in Go
      6 people · 66 points · first shared 2013 · 36 comments on HN
    10. 10
      Goto Is Not a Horror
      4 people · 61 points · first shared 2024 · 50 comments on HN

    What HN people wrote when they linked it

    • lmmAug 2014

      > HN and the internet being what it is, I'm sure someone can pop up here with some horror story about when it happened to them, but I would contend that it's still something so unusual as to not be worth planning for. Maybe just a twinge in the gut if you really did declare an interface with just a Shoot of no parameters and no return value, but... if nothing else, in the Go world, the odds of you having a Camera.Shoot() and a Gun.Shoot() method are low anyhow, and the odds of them conflicting even lower. First you have to declare an interface that both of them fully implement. If you have a .Reload method on your gun, but not your camera, you can't accidentally cross them. If you have a .Reload method on both, but the Gun takes an Ammunition argument and the Camera takes a Film argument, they can't cross. And from a pure software-engineering perspective, you have to a have a program in which you are using the same exact word for two completely different concepts, which can happen, but is bad practice and still takes some work.

      Depends how you're using your types. E.g. one pattern I often use is wrapping up a String as a type so that I don't confuse two different domain-specific Strings - so I'll have something like:

      public class PhoneNumber {
      final String value;
      }
      public class EmailAddress {
      final String value;
      }

      (In Scala this is even easier, with @@)

      This is a really useful distinction to draw (in many ways it's more important than when…

    • brightballDec 2016

      I was getting ready to post the exact same thing. The built in event loop is major. Go did a lot of modelling from Erlang, but made tradeoffs that kept it closer to a C-style programming model.

      It's a great language and the limits of its concurrency model aren't something that will really be apparent to you if you haven't learned Erlang/Elixir. For most people, it provides a concurrency model that's a cut above everything else out there.

      The main differences in Go and BEAM languages (Erlang/Elixir) are cooperative vs prescheduling, shared memory vs immutable message passing, general garbage collection vs heap per process, and lastly general runtime vs isolation.

      Cooperative scheduling means that the scheduler has to have control relinquished back to it (such as with I/O events), while prescheduling will take back control. Cooperative means that you can get better end-to-end performance for a benchmark but you run the risk of a code taking over the processor. Prescheduling will allow consistent performance for all operations in the run time without allowing anything to overtake it. That's one of the ways that it's possible to reliably run a database within the runtime alongside the rest of your code on BEAM.

      Shared memory with pointers is pretty standard and definitely provides some performance perks, especially when dealing with large data structures. The flip side means that native clustering doesn't work. With BEAM languages that lack shared memory and rely on message…

    • TainnorApr 2025

      You started out by saying 99% of web code is IO, then casually dropped down to 70-80%, as if that was the same thing. 20-30% of a huge codebase is still a significant amount.

      I've never said IO is irrelevant to web applications. But that in my experience, those 20-30% or whatever can be important, complex and time intensive (the Word generation was actually one od the most time consuming parts of the last application I worked on) enough that fencing them off from the side effecting code in some way can pay off (one way to do this without going fully PFP is outlined here: https://www.jerf.org/iri/post/2025/fp_lessons_purity/#fp-pure-core---imperative-purifiable-core).

      > First one looks like meta programming. IO. You are programming something else.

      I don't understand what you're saying. I was working on a document management system whose contents were stored in tree structures. These structures routinely had to be transformed into other structures. That's a very algorithmic task where the IO can be fenced off very easily (and should be fenced off if only for the sake of easier unit testing). This was literally one of the most common things happening in the codebase.

      > Chatbots are high IO.

      in the sense that every useful program has IO. Otherwise, there's a whole bunch of transformations and intent recognition and skill dispatch and what not that happens between the request and the response, and that can happen entirely in memory on one machine (it can also be offloaded…

    • louthyJan 2026

      In C# you can implement SelectMany for a type and that gives this:

      from id in ParseId(inputId)
      from user in FindUser(id)
      from posts in FindPostsByUserId(id)
      from res in DeactivateDecision(user, posts)
      select res;

      It is the equivalent to do-notation (was directly inspired by it). Here's an example from the language-ext Samples [1], it's a game of 21/pontoon.

      > I wrote what you might call an acid test for monad implementations a while back: https://jerf.org/iri/post/2928/ It's phrased in terms of tutorials but it works for implementations as well; you should be able to transliterate the example into your monad implementation, and it ought to look at least halfway decent if it's going to be usable.

      If I try to implement the test from your blog with Seq type in language-ext (using C#), then I get:

      Seq<(int, string)> minimal(bool b) =>
      from x in b ? Seq(1, 2) : Seq(3, 4)
      from r in x % 2 == 0
      ? from y in Seq("a", "b")
      select (x, y)
      : from y in Seq("y", "z")
      select (x, y)
      select r;

      It yields:

      [(1, y), (1, z), (2, a), (2, b)]
      [(3, y), (3, z), (4, a), (4, b)]

      Which I think passes your test.

      [1] https://github.com/louthy/language-ext/blob/main/Samples/CardGame/Game.cs

    • dematzMar 2026

      Idk, while system architecture diagrams look cool and feel informative, I generally don't feel like they actually help you get started working somewhere on a project. Mistake #3 in this article, putting too much in, is part of this.

      So https://www.jerf.org/iri/post/2025/on_layers_and_boxes_and_lines/#diagrams-huh-what-are-they-good-for is an interesting take: put links in your diagram, so it functions as a table of contents. This seems most useful for someone who needs to start working on a project.

      Similarly https://haskellforall.com/2026/02/browse-code-by-meaning asks how to show what's in a repo, but maybe file tree is not best and a diagram with links as table of contents is the answer.

      That said practically speaking, I'm not sure what tooling easily creates working links in a diagram that looks good in any context, for instance mermaid might render on github but not a text editor.

      Of course for other purposes maybe just go crazy with the diagram. I once had a coworker draw this super detailed master diagram, maybe 50-100 things on it, which I was told impressed senior government officials (after my manager recolored all the red to avoid connoting errors). But for the purpose of orienting developers a table of contents with links sounds better.

    • warmfuzzykittenApr 2011

      Having just now taken delivery of a new technical book - Learn You a Haskell for Great Good! - I'm guessing that rumors of their death, as Mark Twain said about his own, are greatly exaggerated. I bought it on the basis of an online review that would inform this discussion. http://www.jerf.org/iri/post/2910

      In the review, Jeremy Bowers discusses his own experience trying to learn Haskell over the past few years from the random bits and pieces that float about the web and how the careful development of ideas in this book "blew what turned out to be my rickety assemblage of concepts apart and replaced them with a solid understanding of what is going on with them, and why."

      We tend to forget that learning is not the same as carrying around a giant reference book. It's a painstakingly linear process where leaps of understanding happen only when a solid foundation is in place. Books and the linear style of books will always be with us, but to compete with instant search writers must learn to teach.

    Related

    Eli Benderskyeli.thegreenplace.net428 people

    Common Pitfalls in Go Benchmarking

    Eli Bendersky
    Personal · last shared 2026
    Dave Cheneydave.cheney.net271 people

    Why Slack is inappropriate for open source communications

    Dave Cheney
    Personal · last shared 2026
    Matthias Felleisenfelleisen.org43 people

    Apology

    Matthias Felleisen
    Personal · last shared 2026
    Philip Nilssonphilipnilsson.github.io19 people

    Escaping Hell with Monads (2017)

    Philip Nilsson
    Personal · last shared 2026
    Haskell for Allhaskellforall.com190 people

    The category design pattern

    Haskell for All
    Personal · last shared 2026
    FP Complete Blogfpcomplete.com201 people

    Monads and GATs in Nightly Rust

    FP Complete Blog
    Company · last shared 2025
    Applied Goappliedgo.net25 people

    Perceptrons – the most basic form of a neural network

    Applied Go
    Personal · last shared 2026
    Apfelmusapfelmus.nfshost.com22 people

    How Does Lazy Evaluation Work in Haskell? (2014)

    Apfelmus
    Personal · last shared 2023