1. 36
  1.  

  2. 5

    The thing about defer being function scoped has bit me in the past, I’m glad it’s not just me.

    1. 5

      What’s with the weird subdomains https://https.www.google.com.tedunangst.com ?

        1. 2

          Search lobsters for past posts for past discussions

        2. 4

          The bit about how it’s hard to tell what will close a Reader/WriterCloser underneath you is super valid. I’m not sure how you’d manage that without some kind of “reference count” or similar (i.e. only actually close until the count hits zero).

          Another awkward use case is how to write http middleware that hash-sums a post body (i.e. for slack webhook validation) and then also lets inner actions read from the request post body.

          1. 6

            It’s simple. If you pass a *Closer to something, you should assume that something is going to close it. Otherwise you’d just pass it a Reader or a Writer.

            1. 2

              Not everyone gets the memo that this is the way it’s supposed to work. Very often, folks will create large interfaces and pass them around, with no intent on using everything defined.

              1. 2

                Sure, but at a certain point, what can you do about people ignoring the docs and even the sort of high level guidance of the language? I mean, deep reading docs is hard, reading the go proverbs isn’t https://go-proverbs.github.io/ – and you only have to get to the 4th one to get to “The bigger the interface, the weaker the abstraction.”

                1. 5

                  “The bigger the interface, the weaker the abstraction.” says very little to someone not engaged in deeply understanding it.

                  Obviously, we can’t throw our hands up and say, “what can you do? People will be people!!!” What we can do is ensure that code we write and review takes these principles to heart, and shows the value of it.

                  1. 2

                    Absolutely, and after doing all that – people are still going to write terrible code that directly goes against all the norms and recommendations. I am all for doing our level best to try to guide people – but leading a horse to water and all that.

              2. 1

                I think this is true, but it basically means you should never pass a *Closer unless you really really have to. The callee should manage the IO lifecycle.

                I would even go so far as to say one of the heavily opinionated Go linters should warn (maybe they do, I have never checked because I don’t think highly opinionated linters are a good idea for anything but beginners).

                1. 1

                  This makes sense, but two difficulties.

                  1. Still requires careful analysis of docs. It’s very easy to pass a closereader off to a function taking a reader.

                  2. You can’t just pass something like a gzip.reader to another layer. Even if that layer closes, it doesn’t close the bottom.

                  1. 1

                    When I read stuff like this I change my mind about go being a language that can be learned in a weekend.

                    1. 1

                      You can certainly pick it up and use it effectively in a weekend, but surely you couldn’t learn the ins and outs of anything substantial in just a weekend.

                  2. 4

                    Between io.TeeReader and io.Pipe I think you can probably wire something up. There’s a decent amount of “plumbing” included, although it took me a few passes through the docs to find it all.

                    1. 4

                      Yeah, its quite worth it to read through the whole std library docs, I seem to find a new thing each time I skim it again.

                    2. 1

                      how to write http middleware that hash-sums a post body (i.e. for slack webhook validation) and then also lets inner actions read from the request post body.

                      I’ve had to do something like that and I ended up writing a small TeeReadCloser struct that wraps TeeReader but also has a Close method that closes both the reader and the writer. You can probably get by with a version that takes a WriteCloser like mine and one that just takes a Writer and combine them as needed, though I wonder why they couldn’t just put these in the standard library.

                    3. 2

                      Good article, after working with go for a few years I have reached the same conclusion.