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
    M

    Mat Ryer

    medium.com/@matryer · Personal blog · on HN since 2015

    Mat Ryer, a Go developer and author, writes about Go code style, HTTP services, open source projects and APIs.

    Visit blogHN submissions
    ProgrammingLanguages & CompilersWeb Development
    What HN says

    HN commenters cite his talk and posts on writing Go HTTP services and his code style, which they debate on mutation and branching.

    Stats for nerds
    23HN people shared it
    27linked in comments
    188story points
    Sep 2023last shared
    2015people per year2023

    Top posts on HN

    1. 1
      Vice: Go channels across many machines
      1 person · 82 points · first shared 2017 · 14 comments on HN
    2. 2
      How I write Go HTTP services after seven years
      3 people · 27 points · first shared 2018 · 2 comments on HN
    3. 3
      Show HN: Silk – Markdown driven API tests
      4 people · 14 points · first shared 2016 · Discussion on HN
    4. 4
      Go code: Line of sight principle
      9 people · 12 points · first shared 2016 · 1 comments on HN
    5. 5
      When your old open-source project unexpectedly gets to the top of Hacker News
      3 people · 9 points · first shared 2016 · 1 comments on HN
    6. 6
      Machine learning APIs are too expensive
      1 person · 9 points · first shared 2018 · Discussion on HN
    7. 7
      Show HN: Cloud storage abstraction package for Go
      1 person · 9 points · first shared 2016 · 1 comments on HN
    8. 8
      I was offered $1M for my Go package – and I said No
      2 people · 7 points · first shared 2016 · 1 comments on HN
    9. 9
      The http.HandlerFunc wrapper technique in #golang
      2 people · 6 points · first shared 2015 · Discussion on HN
    10. 10
      Context has arrived: Per-request state in Go 1.7
      1 person · 3 points · first shared 2016 · Discussion on HN

    What HN people wrote when they linked it

    • jonahxSep 2023

      Some important context re: my style...

      > Any code anywhere in the function can mutate any of the variables

      Regardless of the language I'm using, I never mutate values. Counters in loops or some other hyper-local variables (for performance) might be the inconsequential exceptions to this rule.

      > More functions help scopes stay small, and data flow is more explicit.

      Just write your big function with local scope sections, if needed (another local exception to the rule above). Eg, in JS:

      let sectionReturnVal

      {
      // stuff that sets sectionReturnVal
      }

      or even use IIFE to return the value and then you can use a const. "A function, you're cheating!" you might say, but my goal is not to avoid a particular language construct, but to maintain locality, and avoid unnecessary names and jumping around.

      > A side benefit is that "more functions" helps keep indentation down.

      This is important and I maintain it.

      See "Align the happy path to the left" (https://medium.com/@matryer/line-of-sight-in-code-186dd7cdea88)

      It is also worth noting that solving this problem with function extraction can often be a merely aesthetic improvement. That is, you will still need to keep hold the surrounding context (if not the state) in your head when reading the function to understand the whole picture, and the extraction makes that harder.

      Using early returns correctly, by contrast, can actually alleviate working memory issues, since you can dismiss everything above as "handling…

    • kminehartSep 2017

      I worry that a lot of developers who have been using languages like Java or C# see Go and immediately feel the need to point out that Go doesn't support language features that they've come to rely on, and so they see that as a weakness or a flaw.

      With Go, you're getting a lot of high-level language features like anonymous functions, while also gaining the control that you're not able to get in higher level languages like Python or Ruby or Java.

      I think this works out great for cloud computing, where performance is a major requirement, but the technology is expanding rapidly enough that a step up from C or C++ is very necessary.

      A lot of the complaints I hear are related to abstractions, too, and I understand those to an extent. I also think that if you're complaining about the lack of generics, maybe you're not thinking about interfaces correctly. A perfect example is the beautiful simplicity that is the [`io.Reader`](https://medium.com/@matryer/golang-advent-calendar-day-seventeen-io-reader-in-depth-6f744bb4320b).

      So, whenever someone says something like the OP:

      > As a simple language to wire pieces together, Golang is fine, but it really doesn't give you the tools (imo) to be productive for anything more complex than simple apps.

      I take that as meaning, "I've never seriously used Go beyond writing a hello world app. It doesn't have the features I rely on to be productive, therefore I don't think it's a capable language for larger projects."

      I will say though,…

    • unscaledOct 2021

      The section that you're linking to in Effective Go does not state anywhere that "branches are clunky, they are so intentionally to make the points where your code branches much more obvious".

      It only promotes the concept that of using guard-clause style ifs that return an error and have no else clause, gradually eliminating each possible error condition.
      This style of programming was later termed in the Go community "Aligning the happy path to the left"[1][2]

      [1] https://medium.com/@matryer/line-of-sight-in-code-186dd7cdea88
      [2] https://maelvls.dev/go-happy-line-of-sight/

      I wholeheartedly agree that this style makes code more readable and I have adopted it - and encouraged others to adopt it - in other languages besides Go. This style would stil be followed with the try or check/handle proposals. For instance, let's take the example:

      f, err := os.Open(name)
      if err != nil {
      return err
      }
      d, err := f.Stat()
      if err != nil {
      f.Close()
      return err
      }
      codeUsing(f, d)
      f.Close()
      return nil

      With the simple try proposal that would be:

      f := try(os.Open(name))
      defer f.Close()
      d := try(f.Stat())
      codeUsing(f, d)

      With OP's variant of the try proposal, using a question mark this is arguably even more readable (less noisy):

      f := os.Open(name)?
      defer f.Close()
      d := f.Stat()?
      codeUsing(f, d)

      As you can see, these proposal reduce - not increase - nesting, so they are completely in line with what Effective Go is saying.

    • Cthulhu_Jul 2019

      > error check has == instead of !=

      And you return the error as-is if its nil; seems fine to me?

      Your second example is also a bit... far-fetched because it tries to be smart by putting the error checking in the same line. There's also the "line of sight" guideline which states that the happy path should be left-aligned, while edge cases - like errors - should be in indentation [0]. See also the law of least astonishment [1], which your final example does not conform to.

      Yes it will compile and yes it is an issue but that's not because of the language. It's because of an attempt at cleverness by writing more compact, of having the happy path in an if, and (arguably) by reusing variable names - but this seems pretty common, and longer variable names like idk, `osOpenError` and `fileStatError` seem to be discouraged in favor of reuse.

      So I'm not sure if you're getting your point across like this.

      [0] https://medium.com/@matryer/line-of-sight-in-code-186dd7cdea88
      [1] https://en.wikipedia.org/wiki/Principle_of_least_astonishment

    • kaizendadFeb 2019

      This is exactly correct. The cost of holding the entire object in memory, for any significantly complex statement, is going to add up quick if you're dealing with large numbers of users/pageviews/etc. The cost of pre-calculating everything in the object for any complex math similarly gets large when you're dealing with something large-scale. Early returns matter a lot with scale, and make [code line of sight](https://medium.com/@matryer/line-of-sight-in-code-186dd7cdea88) much clearer -- which matters a lot of if your team scale is larger, as in many companies that might have multiple teams working on one shared codebase.

    • DonHopkinsFeb 2020

      Good linters correctly highlight all missing semicolons as a symptom of sloppy, negligent, careless programming (or pointless syntactic showboating). It's also technically syntactically valid to omit braces around single statements after if, else, for, and while statements, but idiotic and dangerous to do that, too.

      https://wiki.c2.com/?FixBrokenWindows

      https://www.rtuin.nl/2012/08/software-development-and-the-broken-windows-theory/

      https://blog.codinghorror.com/the-broken-window-theory/

      https://medium.com/@matryer/broken-windows-theory-why-code-quality-and-simplistic-design-are-non-negotiable-e37f8ce23dab

    Related

    Dave Cheneydave.cheney.net271 people

    Why Slack is inappropriate for open source communications

    Dave Cheney
    Personal · last shared 2026
    JT Oldsjtolio.com22 people

    Problems with Go channels (2016)

    JT Olds
    Personal · last shared 2026
    Code Adventuresmedium.com/code-adventures31 people

    Farewell Node.js

    Code Adventures
    Publication · last shared 2021
    Jeremy Bowersjerf.org78 people

    Functors and Monads for People Who Have Read Too Many “Tutorials”

    Jeremy Bowers
    Personal · last shared 2026
    Russ Coxresearch.swtch.com554 people

    Timeline of the xz open source attack

    Russ Cox
    Personal · last shared 2026
    Coder Blogcoder.com66 people

    We improved the performance of a userspace TCP stack in Go

    Coder Blog
    Company · last shared 2026
    One Big Flukeonebigfluke.com36 people

    Go's power is in emergent behavior

    One Big Fluke
    Personal · last shared 2024
    fasterthanli.mefasterthanli.me236 people

    A half-hour to learn Rust

    fasterthanli.me
    Personal · last shared 2026