Live data from Hacker News

Generic interfaces

go.dev

71–78 of 78 posts

Re: Generic interfaces

#71
post #70

Earlier quoted context omitted.

> You need to have something that uses those templates. Exactly. That is what I said: > because you need to know the actual type arguments used, regardless of what the constraints might say. It is because type-checking concept code is NP complete - it is trivial to check that a particular concrete type satisfies constraints, but you can not efficiently prove or disprove that all types which satisfy one constraint als…

There are common solutions for the library issue. Authors of libraries for example can force instantiations for a dummy type that checks their concepts. template void foo(Dummy); This can be done at the consumer side as well. I don't see a big deal of this. Dummy checks are common in Go too. For example, to check if a type satisfies an interface. var _ MyInterface = (*MyType)(nil) var _ SomeInterface = GenericType[Co…

> There are common solutions for the library issue. Authors of libraries for example can force instantiations for a dummy type that checks their concepts.

But that just ensures that the code type-checks for `Dummy`. It doesn't ensure that the code type-checks for any type you can put into `foo`. And that's the point of type constraints: To give you the necessary and sufficient conditions under which a generic function can be used.

That is simply not the case with C++ templates and concepts. That doesn't mean you can't still like them. I'm not trying to talk you out of liking C++ or even preferring it over Go. I'm just trying to explain that C++ concepts where something that we looked at specifically and found that it has properties that we don't like. And that - to us - the fact that Go generics are limited in comparison is a feature, not a bug.

And let's not forget that despite specifically reducing the safety of concepts in this way, the design ended up being NP-complete anyways and you can make a compiler use functionally infinite memory and time to compile a very small program: https://godbolt.org/z/crK89TW9G

For a language like Go, that prides itself on fast compilation times it is simply unacceptable to require a SAT solver to type-check. Again, doesn't mean one has to dislike C++. But one should be able to acknowledge that it is reasonable to choose a different tradeoff.

> I would actually make the argument that it explodes complexity - for the developer, instead of constraining it.

The title is a pun. Because it is about the computational complexity of checking constraints.

Re: Generic interfaces

#72
post #70

Earlier quoted context omitted.

There are common solutions for the library issue. Authors of libraries for example can force instantiations for a dummy type that checks their concepts. template void foo(Dummy); This can be done at the consumer side as well. I don't see a big deal of this. Dummy checks are common in Go too. For example, to check if a type satisfies an interface. var _ MyInterface = (*MyType)(nil) var _ SomeInterface = GenericType[Co…

> There are common solutions for the library issue. Authors of libraries for example can force instantiations for a dummy type that checks their concepts. But that just ensures that the code type-checks for `Dummy`. It doesn't ensure that the code type-checks for any type you can put into `foo`. And that's the point of type constraints: To give you the necessary and sufficient conditions under which a generic functio…

> But that just ensures that the code type-checks for `Dummy`. It doesn't ensure that the code type-checks for any type you can put into `foo`

Sure, that is C++ specific design decision. Just like Go made the design decision of not type checking interfaces leading to tens-of-thousands of lines of dummy checking concrete types against interfaces in popular Go repos.

I understand the design thinking even if I don't fully agree as a standard user of Go. Thanks for the detailed explanation in the blog.

Minor nitpick: It isn't all that difficult to come up with type structural/generic edge cases for ANY language compiler where compilation takes forever and times out in a playground. Here is a small program of ~100 lines leveraging Go Generics: https://go.dev/play/p/XttCbEhonXg

This will build for several minutes on your laptop if you use `go build`. It can be easily extended to several hours with a few modifications.

Re: Generic interfaces

#73
post #11
post #7

If I'm being honest, the magic of Go was lost when generics were introduced. It now feels akin to Java, which I guess was inevitable and for anyone to really take it seriously maybe it needed to get here. But I am not a fan of generics. While that level of abstraction and composability is clever, it also lends itself to more complexity and systems that can be harder to concretely understand. Just an opinion that I kn…

No one is forcing you to use the full scope of language features for every project. This kind of argument comes up every time a new C# language version rolls out - as if it's a breaking change and now everyone is going to be forced to refactor for it. The only other way I can read this is in terms of wishing others would use tools in the way you prefer, which is clearly a waste of energy.

Yeah but imagine a horrible feature. Let's say a macro language in brain fuck.

Sure don't use it.

But then half the libraries you use force it upon you.

You soon have no choice!

Re: Generic interfaces

#74
post #72

Earlier quoted context omitted.

> There are common solutions for the library issue. Authors of libraries for example can force instantiations for a dummy type that checks their concepts. But that just ensures that the code type-checks for `Dummy`. It doesn't ensure that the code type-checks for any type you can put into `foo`. And that's the point of type constraints: To give you the necessary and sufficient conditions under which a generic functio…

> But that just ensures that the code type-checks for `Dummy`. It doesn't ensure that the code type-checks for any type you can put into `foo` Sure, that is C++ specific design decision. Just like Go made the design decision of not type checking interfaces leading to tens-of-thousands of lines of dummy checking concrete types against interfaces in popular Go repos. I understand the design thinking even if I don't ful…

> Minor nitpick: It isn't all that difficult to come up with type structural/generic edge cases for ANY language compiler where compilation takes forever and times out in a playground. Here is a small program of ~100 lines leveraging Go Generics: https://go.dev/play/p/XttCbEhonXg

Fair point

Re: Generic interfaces

#75
post #34

Earlier quoted context omitted.

> It is a technical solution for a people problem. It is better to guide and to mentor people in designing the right abstractions. What we should learn from this experiment is that this is the wrong approach. Nah, it was just the wrong solution. People problems are basically intractable in the grand scheme of things. Whenever you can turn a people problem into a technical problem, that's an opportunity for progress.…

I agree it was the wrong solution. The problem is that Go is quite popular and lots of code has been written in a language that cannot be fixed. And that is also a people problem, because living daily with a programming language feels like a marriage. People keep fixing the unfix-able rather than moving on. I see the same happening with Python.

Python has gotten a lot better over the years. Though I'm not sure exactly which problem(s) with Python you are talking about, there are still plenty left.

Re: Generic interfaces

#76
post #61
post #31

Earlier quoted context omitted.

C++ templates are duck typed at compile time. Look at Haskell type classes or Rust's traits for some classic examples of how to 'type' your generics. (And compare to what Go and C++ are doing.)

> C++ templates are duck typed at compile time. This is not really true after C++ 20. C++ templates can leverage concepts that specify compile-time constraints and type checking on template parameters during template argument substitution

Yes, concepts are the fix to that duck typing. Not sure how widespread they are in the wild yet (nor how good compiler support is already at the moment.)

Re: Generic interfaces

#77

When I first learned about Go I thought the idea was to have a simple C-like language with a frozen feature set. A language that would look the same today and ten years from now. And I thought that boringness was a wonderful feature, actually. If they're going to be adding features to the language, albeit at a slower pace than Java/C#, what's the point really? On a long enough timeline Go is going to be indistinguish…

> A language that would look the same today and ten years from now.

You can still write Go 1.11 code and compile it with the Go 1.24 compiler. If you specify 1.11 in your go.mod it compiles your code with the 1.11 syntax.

Re: Generic interfaces

#78
post #50

Earlier quoted context omitted.

> the downside of writing out explicit types and repetition matters very little That’s not the main reason. You can have a library by author X that provides a container type Heap[T] and you can use it with your type T which is unknown by X and requires no coordination. If the proto-generic maps and slices did not exist in Go it would not be a useful language at all. This pain point was glaring in Sort and Heap in std…

As far as I've seen, a heap implementation using generics is not any shorter or simpler than the old `heap.Interface` - what it gained is reusability. > Code is read more often than written, and still needs to be reviewed, understood and maintained. Which takes us back to the points above. AI is really good at generating repetitive patterns, like plain types, or code that implements a certain interface. If you reduce…

> AI is really good at generating repetitive patterns, like plain types, or code that implements a certain interface. If you reduce the cost of creating the verbose code [at write time] we can all enjoy the benefit of reduced complexity [at read time] without resorting to generics.

Though humans are very bad at reviewing repetitive patterns. I'd much rather review a single generic implementation, than 10 monomorphic ones, that look the same, but where I can't be sure and actually have to check.

So unless you are making the argument that generated code doesn't require review (compliance auditors would disagree) I would personally still much rather have generics.

Post reply on HN