I wrote up a coherent proposal based on the core of the idea below, and added 
it to the feedback wiki:

https://gist.github.com/rcoreilly/bfbee2add03c76ada82810423d81e53d

Overall I think it seems quite promising as perhaps the most “Go” version of 
generics possible, which solves the major use-cases, while retaining 
essentially the same existing syntax and just adding a few additional keywords. 
 I can’t see any major limitations other than those intrinsic to the idea 
itself (e.g., you can’t define a Min function that works across any type 
whatsoever), and I don’t think it introduces any violations of existing static 
type safety.  Curious to hear what others think!  Cheers,

- Randy

> On May 31, 2019, at 4:28 PM, Randall O'Reilly <rcoreil...@gmail.com> wrote:
> 
> This seems similar to previous proposals based on introducing kind-based type 
> categories for contracts.  Putting the kind right there in the arg instead of 
> a separate contract seems like an improvement, keeping it more local to where 
> it is used.  Why not just take this one step further and just introduce 
> entirely new types:
> 
> * number
> * slice
> * map (re-useable from existing use-case?)
> * etc
> 
> func Min(x, y number) number {
>   if x < y {
>      return x
>   }
>   return y
> }
> 
> func Delete(sl *slice, idx int) {
>   *sl = append((*sl)[:idx], (*sl)[idx+1:])
> }
> 
> The compiler would just do its normal thing based on whatever actual kind you 
> pass in — an implicit type switch basically..
> 
> You could convert any `number` into a specific type (e.g., float64) when you 
> need to, and if you passed two different underlying types of numbers as args 
> to Min, it would automatically up-convert to the one with highest precision.  
> Essentially, this is undoing all the strict type specificity of Go, and 
> making it work like C, or Python..
> 
> This minimalist approach avoids all the complexity and ugliness of 
> parameterizing types etc — it is just a more generic type of type, and is 
> more or less how the generic builtin operators and functions like len, copy, 
> etc already work on their respective kinds.
> 
> Composite types seem like they might even just work without a type parameter:
> 
> type Vec2 struct {
>   X, Y number
> }
> 
> func (u Vec2) Add(v Vec2) Vec2 {
>   return Vec2{u.X + v.X, u.Y + u.Y}
> }
> 
> In summary, this is really just introducing a very controlled dose of dynamic 
> typing into the language (adding a dash of Python into Go).  Probably this 
> has already been considered and rejected hundreds of times over the course of 
> these discussions, but I’ve lost track, and seems at least like a very simple 
> conceptual proposal: you can achieve a lot of generics functionality by just 
> introducing dynamic typing.  Syntactically and conceptually, it is far 
> cleaner and simpler than anything else I’ve seen in the generics discussion, 
> at least.
> 
> - Randy
> 
>> On May 31, 2019, at 6:52 AM, Michal Strba <faiface2...@gmail.com> wrote:
>> 
>> @Ian, I have been thinking and I’ve come up with a possible solution to 
>> yours and some other problems. I’d love to hear your thoughts on it. Note, 
>> that this is a very fresh idea.
>> 
>> I’m addressing two problems here:
>> 
>>      • Inability to do Min/Max and other generic numeric functions.
>>      • There are a few kinds of generic parameters, but the kind is always 
>> implicit. This can be a problem because changing the body of a function can 
>> result in a backward-incompatible change, even when the signature remains 
>> the same.
>> Here are the ideas (also described in the proposal now, in the section 
>> called ‘Further ideas’).
>> 
>> The kind of a generic parameters is currently completely implicit. Some 
>> annotation could be added. One possible syntax could be like this:
>> 
>>      • gen n for generic array lengths.
>>      • gen T for arbitrary types (convertible to interface{}).
>>      • gen eq T for equalable types (comparable with == and usable as map 
>> keys).
>>      • gen num T for numeric types (with operators like +, -, <, …).
>> Array lengths and arbitrary types can have the same notation because it’s 
>> always possible to distinguish them by context. Alternatively, they could be 
>> distinguished by capitalization (lower-case for array lengths, upper-case 
>> for types).
>> 
>> Syntax-wise, eq and num would not be keywords on their own. Rather, gen eq 
>> and gen num would be two-word keywords.
>> 
>> The syntax is rather ad-hoc, I admit. It’s a very fresh idea, completely 
>> open to refinement. However, since there are only four cases, an ad-hoc 
>> syntax may actually be the right choice.
>> 
>> It’s also easily extensible with new possible “contracts”, but I’d generally 
>> advise against that.
>> 
>> The addition of the num restriction would actually enable many cool things. 
>> First, the Min/Max functions:
>> 
>> func
>> Min(x, y gen num T) T {
>> 
>> if
>> x < y {
>> 
>> return
>> x
>>    }
>> 
>> return
>> y
>> }
>> 
>> It would also be useful for generic math types, like vector and matrices. 
>> The matrix example above uses float64, but it could be generalized to all 
>> numeric types.
>> 
>> As an example, let’s take a look at a possible implementation of a 2D vector 
>> type:
>> 
>> type Vec2(T) struct
>> {
>>    X, Y T
>> }
>> 
>> There are no restrictions specified in the type definition. This is because 
>> it’s methods and functions that require restrictions, not the types 
>> themselves. For example, this String method requires no restrictions:
>> 
>> func (u Vec2(gen T)) String() string
>> {
>> 
>> return fmt.Sprintf("(%v, %v)"
>> , u.X, u.Y)
>> }
>> 
>> This Eq method requires the types to be comparable with ==:
>> 
>> func (u Vec2(gen eq T)) Eq(v Vec2(T)) bool
>> {
>> 
>> return
>> u.X == v.X && u.Y == v.Y
>> }
>> 
>> But, this Add method requires the types to be numeric:
>> 
>> func
>> (u Vec2(gen num T)) Add(v Vec2(T)) Vec2(T) {
>> 
>> return
>> Vec2(T){u.X+v.X, u.Y+v.Y}
>> }
>> 
>> Consequently, Vec2([]float64) would only have the String method, 
>> Vec2(string) would have the Eq method in addition, and Vec2(float64), 
>> Vec2(int32), and so on, would have all the methods.
>> 
>> Yes, the idea basically is to introduce two "contracts" into the system. 
>> However, there's no ability to create own contracts and the syntax is very 
>> concise and non-disruptive. I believe this would really cover the vast 
>> majority of use-cases.
>> 
>> 
>> pi 31. 5. 2019 o 14:05 <fge...@gmail.com> napísal(a):
>> On 5/31/19, Nick Keets <nick.ke...@gmail.com> wrote:
>> ...
>>> This proposal is very interesting and seems to fit nicely into Go, with
>>> minimal disruption. And speaking personally, it would cover 99% of my needs
>>> for generics (I'm not that interested in Min/Max, but writing functions to
>>> get map keys gets old fast).
>> Interesting, could you please share the problems where the usual
>> iterating idiom is not good enough?
>> 
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/CA%2Bctqro9o-RAa6QRVCEQ%2BPu_tre%2BCtJQZaP4LbBTB_6LQntWyg%40mail.gmail.com.
>> For more options, visit https://groups.google.com/d/optout.
>> 
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/CAO6k0usrzSrh1j-xboqtxh8jJCz0eRDpfvTggfgi-0%3D10XhNoA%40mail.gmail.com.
>> For more options, visit https://groups.google.com/d/optout.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/EC3BD38A-48A0-4EBA-AE8D-54445D51C0CB%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to