Live data from Hacker News

My real life use-case for generics in Go: API for client-side pagination

vladimir.varank.in

21–30 of 30 posts

Re: My real life use-case for generics in Go: API for client-side pagination

#21
post #12

Earlier quoted context omitted.

>Built-in map and vector types are generic. I understand what people mean by this, but it's not true for any reasonable notion of 'generic'. Pre-generics Go no more has generic maps than C has generic arrays. Yes, you can declare a map or a slice of values of any given type, but you can't write a generic function that abstracts over these types. That's what is usually meant by 'generics'.

Sure but it's worth emphasizing that Go language designers gave these built-in collections the exorbitant privilege of being parameterized by a type and declaring that any new type created by a mere programmer has to be monomorphic.

> the exorbitant privilege of being parameterized by a type

This is how built in collection types work in pretty much all statically typed languages. For example, here is an array of ints in C:

    int foo[] = { 1, 2, 3 };
We wouldn't usually say that C has 'generic arrays'.

> any new type created by a mere programmer has to be monomorphic.

Collections in (pre-Generics) Go are monomorphic. []foo and []bar are as different as foo and bar. That is why, for example, the first argument of sort.Slice has type 'any' (https://cs.opensource.google/go/go/+/go1.18.2:src/sort/slice...)

Re: My real life use-case for generics in Go: API for client-side pagination

#22
post #17

I am surpsised by the fact that in 2022 go developers are rediscovering and being fascinated by generics when any general introductory programming education with a type safe language should have exposed them to it. It feels like a massive step back in what you should expect the average developer to know about programming.

I majored in computer engineering and only touched embedded C and assembly (and MATLAB). I later picked up Go when I wanted to write code to run on regular computers. I never actually touched generics until they were being introduced to Go and I genuinely didn't realize what they could be used for.

Computer engineering and computer science are different fields. A computer science degree generally requires a semester of programming language theory, which likely includes talking about generics (along with a bunch of more obscure ideas).

Having said that, when presented in a PL class, the main conclusion you will come to is that generics in OOP languages are somewhere between completly broken and very confusing. In practice this doesn't come up that often, because most developers instinctivly avoid thd theoretical pitfalls.

Re: My real life use-case for generics in Go: API for client-side pagination

#23

Earlier quoted context omitted.

Anyone can learn how to write generic code, the trick is knowing the price of the particular implementation of generics and when to pay it. https://planetscale.com/blog/generics-can-make-your-go-code-...

I guarantee you that less than 1% of users of generic languages have the knowledge to argue about this. Java devs are in a special position since all had to find out the hard way you can't acquire generic parameters at runtime due to type erasure. In Java generics are just syntactic sugar, but this gives them the lowest (none?) runtime overhead.

Type erasure definitely does not give the lowest runtime overhead most of the time, although (a) you can always find special cases and (b) it's great for code size, which sometimes is performance-determining at the system level due to caches. The huge thing that type erasure gives up compared to per-type instantiation is the ability to do per-type inlining and the further optimizations that enables.

Re: My real life use-case for generics in Go: API for client-side pagination

#24
post #12
post #10

Earlier quoted context omitted.

Built-in map and vector types are generic. E.g. map[int]*MyType Using interface{} is quite common in the absence of sum types (or inheritance with base class). I guess interface{} is like Object in Java. It's not worse than Python or other dynamic languages that many people are fine with. The run-time panics when asserting that a type is something it's not. E.g. https://go.dev/play/p/c4hx8HSiB8I That said, no, it's n…

>Built-in map and vector types are generic. I understand what people mean by this, but it's not true for any reasonable notion of 'generic'. Pre-generics Go no more has generic maps than C has generic arrays. Yes, you can declare a map or a slice of values of any given type, but you can't write a generic function that abstracts over these types. That's what is usually meant by 'generics'.

Yes, you are correct. I had not thought about it deeply. There are restrictions for what can be used as a map keys according to some built-in equality rules. And of course the types used as map keys and values are concrete types so you can't pass a map to generic functions pre generics.

But was the built-in append function generic pre generics? I think it is?

Re: My real life use-case for generics in Go: API for client-side pagination

#25

I am surpsised by the fact that in 2022 go developers are rediscovering and being fascinated by generics when any general introductory programming education with a type safe language should have exposed them to it. It feels like a massive step back in what you should expect the average developer to know about programming.

The thing that people who are agog about people actually liking Go should understand is "any general introductory programming education with a type safe language should have exposed them to it" is completely correct.

To the best of my knowledge, nobody is learning Go as their first and only language at school. Very few people are learning it as their only language, certainly not enough to account for its growth by any means.

Therefore: You have a model of the world. Your model of the world is making the busted prediction that Go shouldn't be useful for anything and nobody should like it. Instead of cutting to the assumption that "Oh, all the people who like Go must just be stupid and ignorant" to fix it up, maybe you should consider updating your model with something else. I doubt there's more than 5% of Go users who have literally never used a language with generics and are somehow unaware of them. It certainly doesn't cover me, I've used Haskell quite a bit and can easily find the generics of other languages quite lacking without trying too hard.

(One thing I can tell you is all y'all agog folk really underestimate just how many of the use cases for "generics" was covered by "interfaces". Quite a lot of the "generic" use cases that leap to mind that aren't data structures parameterized by types are covered by interfaces. Even some of the "data structures parameterized by types" use cases are covered by interfaces too, just with less compiler assistance. To my mind, Go didn't "get generics" in 1.18, it merely added in the remaining 25% or so. This isn't the whole story, but it's a fair bit of it.)

Re: My real life use-case for generics in Go: API for client-side pagination

#27
post #23

Earlier quoted context omitted.

I guarantee you that less than 1% of users of generic languages have the knowledge to argue about this. Java devs are in a special position since all had to find out the hard way you can't acquire generic parameters at runtime due to type erasure. In Java generics are just syntactic sugar, but this gives them the lowest (none?) runtime overhead.

Type erasure definitely does not give the lowest runtime overhead most of the time, although (a) you can always find special cases and (b) it's great for code size, which sometimes is performance-determining at the system level due to caches. The huge thing that type erasure gives up compared to per-type instantiation is the ability to do per-type inlining and the further optimizations that enables.

Yeah, monomorphization of a method is probably cheaper and faster than boxing every argument and result. I expect value types to help a lot in JVM footprint.

Re: My real life use-case for generics in Go: API for client-side pagination

#28
post #12
post #10

Earlier quoted context omitted.

Built-in map and vector types are generic. E.g. map[int]*MyType Using interface{} is quite common in the absence of sum types (or inheritance with base class). I guess interface{} is like Object in Java. It's not worse than Python or other dynamic languages that many people are fine with. The run-time panics when asserting that a type is something it's not. E.g. https://go.dev/play/p/c4hx8HSiB8I That said, no, it's n…

>Built-in map and vector types are generic. I understand what people mean by this, but it's not true for any reasonable notion of 'generic'. Pre-generics Go no more has generic maps than C has generic arrays. Yes, you can declare a map or a slice of values of any given type, but you can't write a generic function that abstracts over these types. That's what is usually meant by 'generics'.

There were three or four generic types and a few generic functions (close, len, cap, make, append, delete, x[y], <-, ==, for-range, select), they just didn’t let normal users define new ones without forking the compiler.

Re: My real life use-case for generics in Go: API for client-side pagination

#29
post #12

Earlier quoted context omitted.

>Built-in map and vector types are generic. I understand what people mean by this, but it's not true for any reasonable notion of 'generic'. Pre-generics Go no more has generic maps than C has generic arrays. Yes, you can declare a map or a slice of values of any given type, but you can't write a generic function that abstracts over these types. That's what is usually meant by 'generics'.

There were three or four generic types and a few generic functions (close, len, cap, make, append, delete, x[y], <-, ==, for-range, select), they just didn’t let normal users define new ones without forking the compiler.

I don’t think it makes sense to see built in operations on arrays and maps as generic functions. If 'len' was some kind of built-in generic function then you'd expect to be able to monomorphize it like this:

    func intLen(foo []int, lenfunc func ([]int) int) int {
      return lenfunc(foo)
    }

    intLen([]int{1,2,3}, len)
There is just no sense in which Go 1.17 has “generic types” and (e.g.) C doesn’t. All statically typed languages allow you to define arrays of different types and use the same operators on these arrays. Go adds a handful of additional built in types (slices, maps, channels).

The idea that some completely ordinary language features somehow constitute a crippled version of generics that has been 'turned off' for regular users seems to be an artefact of certain communities' hobbyhorsing over Go's (former) lack of generics.

Re: My real life use-case for generics in Go: API for client-side pagination

#30
post #29

Earlier quoted context omitted.

There were three or four generic types and a few generic functions (close, len, cap, make, append, delete, x[y], <-, ==, for-range, select), they just didn’t let normal users define new ones without forking the compiler.

I don’t think it makes sense to see built in operations on arrays and maps as generic functions. If 'len' was some kind of built-in generic function then you'd expect to be able to monomorphize it like this: func intLen(foo []int, lenfunc func ([]int) int) int { return lenfunc(foo) } intLen([]int{1,2,3}, len) There is just no sense in which Go 1.17 has “generic types” and (e.g.) C doesn’t. All statically typed langua…

As a thing that takes an argument and returns a result, I would have expected len to be an ordinary function. That I don’t is only because I remember the disappointing state of the language at launch.
Post reply on HN