Live data from Hacker News

Reusable and type-safe options for Go APIs

derekchiang.com

31–36 of 36 posts

Re: Reusable and type-safe options for Go APIs

#31
post #8
post #3

Once you accept that the golang type system can't enforce everything your life will be easier. Use rust or Haskell if you want a powerful type system that can do fancy things. golang is great, but you have to accept that some things are runtime errors, and that's fine, it keeps things simple. How often are options given conditionally anyways? Simple tests will cover this in most cases.

No languages are perfect. Yes Go type system can't enforce everything, but it enforce many things. And Go is still language in evolving.

My point was that complex type systems also have down sides. Even if you strongly favor algebratic type systems, you have to admit they are harder to learn (at-least initially).

The upside with golang is that it's simple and easy to adopt; tiny learning curve, and code + APIs are intended to be simple.

If you are messing around with complex patterns in golang to get more compile-time correctness checks, you are most likely not keeping it simple. And thus, have missed the most important upside to golang.

Re: Reusable and type-safe options for Go APIs

#32

I find I don't care for implementing the Options paradigm. More often then not, the things I've implemented have required parameters, and sometimes many of them. Mixing required and options often feels kludgy. I feel the Options method requires lots of documentation referencing, as opposed to more discoverable (via your editor) constructors. I tend to use explicit parameters or a struct with validators where every fi…

I personally prefer something like:

> type Options struct { ... }

> func myMethod(arg1 string, options Options) {...}

Then have people pass in "Options{}" and let the zero-values imply default.

But most of the time, if you are making things complex, you're missing the whole point of golang. The innovation in golang is it's simplicity, if you miss that, then you might as well code C++ (which have more features for these kinds of things).

Re: Reusable and type-safe options for Go APIs

#33

How is it not cleaner and simpler to just use something of a builder pattern? srv = NewServer(addr).WithTLS(crt,key).WithRateLimit(30).WithPool(10).Start() if srv.Err() { // Handle }

Or

  NewServer(Options{Addr: addr, RateLimit 30, Pool: 10})
IMO, keep it simple and remove the optional features if possible is also a good choice. If my golang API is complex, then I might aswell have done it in C++ :)

Re: Reusable and type-safe options for Go APIs

#34

How is it not cleaner and simpler to just use something of a builder pattern? srv = NewServer(addr).WithTLS(crt,key).WithRateLimit(30).WithPool(10).Start() if srv.Err() { // Handle }

How is it cleaner and simpler? It reads about the same to me.

It's cleaner because you can't pass invalid options, they won't compile.

Re: Reusable and type-safe options for Go APIs

#35
post #25

The downside to this solution is that the concrete option types are exported. I believe it's possible to return unexported types from exported functions, which would solve this, but that golint complains about that pattern. Have you suggested this to the etcd maintainers?

That's a good point, and I've since updated the blog post and the code to use anonymous interfaces instead.

Re: Reusable and type-safe options for Go APIs

#36
post #15

Earlier quoted context omitted.

That's right. I've been using Go since pre 1.0 times. I'm however not by and large a programmer by profession.

> I'm however not by and large a programmer by profession. That explains it. Different risk tolerances when you're not reliant on it for a living. Apologies for whatever I was flagged for, if I came across as rude in text that was not my intention. Legitimate curiosity.

No worries. I didn't flag you actually :-)
Post reply on HN