So, for example, with both the existing interfaces and these contracts (which I think should really be 1 feature) you end up needing to define wrappers, with everyone defining their own, and needing to implement these methods over and over again. I don't really understand it.
Conversation
There's serious a need for the standard library to define some basic contracts and provide wrappers around the built-in types so people can reuse those instead of making their own. However, this smells a lot like Java. I don't see any benefits from forcing both int and Integer.
1
So, once you have those standard types, the next step on the Java path is to provide auto-conversion to and from them for convenience since it's painful. These are solutions to an unnecessarily created problem though. In terms of deciding between boxing and specialized code...
1
1
... Swift generics simply treat that as an optimization decision, which you can force. It can either reuse the code or specialize it. It also doesn't need to actually force boxing (heap allocation for indirection), but rather it can be generic across different sizes of types.
1
Another major example of an unnecessarily self-inflicted wound is having nullable pointers by default instead of not supporting implicit zero init or assigning nil, and then not having null pointer dereferences except when opting into to nullable pointers. I just don't get it.
1
1
Clearly need an equivalent to Swift (vs. Objective-C) or Kotlin (vs. Java) for the Go ecosystem providing a well designed modern language interoperable with it without all the backwards compatibility warts. Interested to see what happens with it having (ugly) generics though.
1
A lot of people have told me they use Go because it doesn't have generics or because it's not like C++ with features piled on in ways that conflict and don't work well together. To me, that describes the situation well, especially the Java-like issues with primitive types...
1
1
Replying to
For me, simplicity of language and build speed with reasonable runtime performance have been the biggest drivers. I also haven’t used generics since C++ templates long ago (and don’t want to go back to it). So, I’ve been wary of generics designs that change the reasons I use go.
1
Replying to
I don't really consider C++ templates as a form of generics but rather a different approach to the problem space. To me, generics means having type parameters where you can't assume anything about those types like calling a method or using an operator without requiring that.
1
Template expansion and the pattern matching involved in finding valid matches (SFINAE) is something else entirely. It's possible to choose to compile generics in a way that ends up resembling the same end result, but it's not mandatory. Rust used to reuse a single implementation.
1
Rust would compile the code in a way that it could reuse the generated code for any type parameters, without needing boxing. It was complex in the compiler and had a runtime cost, so it adopted "monomorphization" i.e. making specialized variants for each set of type parameters.
Swift supports both, and it's treated as an optimization decision. C# uses monomorphization for value types and reuses an implementation for reference types, which are already boxed, so it makes some sense to use dynamic dispatch, but it could still specialize if they wanted to.
1
That's an implementation detail other than performance and code size characteristics though. C++ templates don't have that as a choice because they aren't generics, but rather they are inherently expanding templates and doing pattern matching to pick the template specialization.
1
Show replies

