Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Libraries and library-like code. Any code that fetches data from generic storage/protocols.

Prime examples:

- http requests. For an API it's almost always a generic request parametrized by some type.

For example, you API always returns `{result: ...some data..., nextPageToken: ...}`. Well, that's a `PagedResponse<...the type of data...>`

- cache

Caches store objects. In go any `.get` from a cache will return an `interface{}` that you have to type-assert because you can't do a `Cache<T>`.

and so on.



Re: HTTP requests, you mean the exact HTTP response, which in your case is a JSON object that can be parsed via a different package; the two should not be conflated, and the HTTP package should not be polluted with assumptions about what (if any) data is being passed.

Re: caches, what kinda caches do you mean? For the most simple use case you have maps, which in Go are already generic. Of course, anything more advanced would be greatly helped with generics, since at the moment they (I presume) store `interface{}` types and the consumer has to cast them back to the real types. Or they use code generators, which is also pointed out in the article.

To add some potential goodness coming from generics: Option types to avoid nil, Either types to replace the value/error tuples (which the article points out is a weird outlier, because you don't have tuples elsewhere in the language).

Those make me wonder if parts of the language and codebases written therein would actually improve compared to the weirdness of multiple return values and the like.


> and the HTTP package should not be polluted with assumptions about what (if any) data is being passed.

I'm not talking about the HTTP package itself. In Java and C# you do something along the lines of

  // Java
  CompletableFuture<PagedResult<Contract>> getContracts(...);
  CompletableFuture<PagedResult<Client>> getClients...(...);
  CompletableFuture<PagedResult<Book>> getBooks...(...);

  // C#

  JsonSerializer.Deserialize<PagedResult<Contract>>(responseBody);
  JsonSerializer.Deserialize<PagedResult<Client>>(responseBody);
  JsonSerializer.Deserialize<PagedResult<Book>>(responseBody);
And that's basically it. With Go you end up having fifteen identical PagedResult types for every single type that can be returned from the API because you can't parametrize anything:

  // Go
  
  type ContractsResult struct {
 Result        []*entities.Contract
 NextPageToken string
  }
  type ClientsResult struct {
 Result        []*entities.Client
 NextPageToken string
  }
  type BooksResult struct {
 Result        []*entities.Book
 NextPageToken string
  }
> Or they use code generators, which is also pointed out in the article.

Code generators are just bandaid for glaring holes in the language. Worse still, I don't know if you can even specify code generating tools in your go.mod. For example, wire's installation instructions say "you need to install wire globally and have it on your $GOPATH" [1] So your go build will just fail mysteriously until you have all the necessary tools installed.

> Of course, anything more advanced would be greatly helped with generics

That... that is exactly what I'm talking about.

> Option types to avoid nil, Either types to replace the value/error tuples

Indeed. I forgot about those :) Yup, that would be a great use case for generics.

[1] https://github.com/google/wire




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: