Go 2 generics counterproposal: giving up restricting types

941 views
Skip to first unread message

Michal Strba

unread,
May 30, 2019, 12:29:03 PM5/30/19
to golang-nuts
Hi Gophers! :)

I've been thinking about generics in Go 2 ever since the original contracts proposal and few days ago, ideas finally clicked. One of the main things about this proposal is that it deliberately omits the ability to restrict the set of types a function can work with. This is a limitation, but I hope to convince you that we can still do a vast majority of the things we were missing, when we were missing generics.

I'd love to share my proposal with you and engage in a good faith conversation.


Here's what the proposal covers:

1. Syntax of a new gen keyword.
2. Generic functions.
3. Unnamed generic arguments (a.k.a. a way to gve a type to the built-in new function).
4. Semantics of generic values (ability to use them as map keys, ...).
5. Generic array lengths.
6. Reflection and interface{}.
7. Generic types (with two examples: List and Matrix).
8. Generic methods and their limitations due to reflection.
9. Generic interfaces.
10. List of things this proposal can't do.

Thanks,
faiface

lgo...@gmail.com

unread,
May 30, 2019, 1:24:55 PM5/30/19
to golang-nuts
one of the annoying things you have to deal with as a team member is being assigned an "update" of code written by someone who no longer works for the team. What makes this annoying is possibility of running into code sections that contains "crytic" statements that require lots of effort to understand. After looking at the link you provided my input, based on dealing with cryptic C++  is:
  w

lgo...@gmail.com

unread,
May 30, 2019, 1:29:09 PM5/30/19
to golang-nuts


On Thursday, May 30, 2019 at 1:24:55 PM UTC-4, L Godioleskky wrote:
one of the annoying things you have to deal with as a team member is being assigned an "update" of code written by someone who no longer works for the team. What makes this annoying is possibility of running into code sections that contain "crytic" statements that require lots of effort to understand. After looking at the link you provided my input, based on dealing with cryptic C++  is: Go should not allow cryptic syntax.
Generics are useful except when their syntax becomes cryptic 

lgo...@gmail.com

unread,
May 30, 2019, 1:29:24 PM5/30/19
to golang-nuts
llow


On Thursday, May 30, 2019 at 12:29:03 PM UTC-4, Michal Strba wrote:

Michal Strba

unread,
May 30, 2019, 1:33:11 PM5/30/19
to golang-nuts
> Generics are useful except when their syntax becomes cryptic

I agree, are you referring to anything specific?

Dňa štvrtok, 30. mája 2019 19:29:09 UTC+2 L Godioleskky napísal(-a):

lgo...@gmail.com

unread,
May 30, 2019, 1:41:36 PM5/30/19
to golang-nuts
Sorry again for the power failure...let me try one last time

one of the annoying things you have to deal with as a team member is being assigned an "update" of code written by someone who no longer works for the team.
What makes this annoying is possibility of running into code sections that contain "crytic" statements that require lots of effort to understand.
 After looking at the link you provided, based on my history dealing with unnecessary and avoidable 'cryptic C++,
 my input  is:  Generics are a great idea EXCEPT when they allow use of cryptic syntax

On Thursday, May 30, 2019 at 12:29:03 PM UTC-4, Michal Strba wrote:

Michal Strba

unread,
May 30, 2019, 1:45:04 PM5/30/19
to lgo...@gmail.com, golang-nuts
I agree with that. What exactly do you consider cryptic, though, about
my proposal? I thought the syntax was very clean. Furthermore,
regarding relating this to C++, I quote:

> Just to make it clear, you aren't allowed to use operators like +, -, <, call methods, or access struct fields of a generic value

I'm just not sure how your sentiment relates to the proposal.

št 30. 5. 2019 o 19:41 <lgo...@gmail.com> napísal(a):
> --
> 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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/4e266f34-32d8-4b3d-8f45-55da5651ed9e%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Raffaele Sena

unread,
May 30, 2019, 2:08:32 PM5/30/19
to Michal Strba, lgo...@gmail.com, golang-nuts
Completely agree about "Generics are useful except when their syntax becomes cryptic". But reading this proposal (quickly, while doing a bunch of other stuff :), the syntax is very clean and the proposal is very well thought. 
 

Ian Lance Taylor

unread,
May 30, 2019, 2:26:34 PM5/30/19
to Michal Strba, golang-nuts
One of my guidelines for an acceptable generics proposal is that
people can write Min and Max. Your proposal admits that it doesn't
permit that. I think that is a problem. I'm fine with the general
idea of "do 80% of the job" but in practice people really do want to
write Min and Max. I think they are part of the 80% that needs to be
handled, not the 20% that can be omitted.

You need to think about scoping. The "gen" keyword doesn't just mean
that the next identifier is a generic type; it also defines that
identifier for some scope, since your examples use it that way. The
proposal needs to carefully spell out the scope of an identifier, and
exactly when it shadows or is shadowed by other objects with the same
name.

Ian

David Riley

unread,
May 30, 2019, 3:44:50 PM5/30/19
to Ian Lance Taylor, Michal Strba, golang-nuts
On May 30, 2019, at 2:25 PM, Ian Lance Taylor <ia...@golang.org> wrote:
>
> One of my guidelines for an acceptable generics proposal is that
> people can write Min and Max. Your proposal admits that it doesn't
> permit that. I think that is a problem. I'm fine with the general
> idea of "do 80% of the job" but in practice people really do want to
> write Min and Max. I think they are part of the 80% that needs to be
> handled, not the 20% that can be omitted.

I agree strongly with this metric. My principal reason for wanting generics is precisely so I can avoid writing the kind of repetitive code that I currently need to write to perform the exact same simple operations on similar datatypes. Min and Max are perfect examples of that, Map and Filter are slightly more complex ones.

If I can't write Min and Max for generic data types, I'm not using it. YMMV.


- Dave

Michal Strba

unread,
May 30, 2019, 4:00:49 PM5/30/19
to David Riley, Ian Lance Taylor, golang-nuts
Ian and David, thanks for the response! I personally don't consider MIn and Max to be so important, however, I understand if you do. I've added a new little part to the proposal that describes one possible way for them to be supported:

Currently, the type-checker has to distinguish between three kinds of generic parameters:

1. Any type.
2. Any type with `==`.
3. Integer constant.

This list could be extended to include support for _any numeric type_ (with operators like `+`, `-`, ...). This would make it possible to make functions like `Min`, `Max`, and so on.
 
I've also added a better description of the scope of the identifiers declared with the gen keyword as Ian pointed out:

The identifier after `gen` is then a generic type identifier visible in the whole rest of the function (signature and body).


št 30. 5. 2019 o 21:44 David Riley <frave...@gmail.com> napísal(a):

Nick Keets

unread,
May 31, 2019, 5:56:10 AM5/31/19
to Ian Lance Taylor, Michal Strba, golang-nuts
On Thu, May 30, 2019 at 9:26 PM Ian Lance Taylor <ia...@golang.org> wrote:
One of my guidelines for an acceptable generics proposal is that
people can write Min and Max.  Your proposal admits that it doesn't
permit that.  I think that is a problem.  I'm fine with the general
idea of "do 80% of the job" but in practice people really do want to
write Min and Max.  I think they are part of the 80% that needs to be
handled, not the 20% that can be omitted.

 At some point we should decide if a 90% solution is possible at all and if not, maybe a 80% solution is what we should aim. 

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).

fge...@gmail.com

unread,
May 31, 2019, 8:05:47 AM5/31/19
to Nick Keets, golang-nuts
On 5/31/19, Nick Keets <nick....@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?

Michal Strba

unread,
May 31, 2019, 8:53:11 AM5/31/19
to Ian Lance Taylor, golang-nuts

@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:

  1. Inability to do Min/Max and other generic numeric functions.

  2. 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:

  1. gen n for generic array lengths.
  2. gen T for arbitrary types (convertible to interface{}).
  3. gen eq T for equalable types (comparable with == and usable as map keys).
  4. 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):
--
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...@googlegroups.com.

Robert Johnstone

unread,
May 31, 2019, 9:06:56 AM5/31/19
to golang-nuts
Hello,

I'm not sure that Min and Max need to be in the 80%.  It's annoying to write them repeatedly, but they are also very short.  The place where I typically miss generics is larger chunks of code, such as concurrency patterns.  I'm certain others are looking at datatypes.  Why do Min and Max need to be in the 80%?

Robert

David Riley

unread,
May 31, 2019, 10:05:48 AM5/31/19
to Robert Johnstone, golang-nuts
Because Min and Max are very good and simple indicators of whether the mechanism is generic enough to handle a fairly common idiom: small functions for similarly behaved items, say comparable items, which are annoying and repetitive to write for every data type which might support the operation (not to mention the fact that increases the surface area for errors).

It's also worth noting that if Min and Max can't be written in a generic system, it's likely that Sort can't, either.

If the purpose of a generic system is to reduce repetitive code in a readable way, it's probably not doing its job very well if it can't do Min and Max. They're good canaries.


- Dave
> --
> 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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/e91e761e-92cd-452a-a387-e0741ebacd66%40googlegroups.com.

Robert Engels

unread,
May 31, 2019, 11:46:19 AM5/31/19
to David Riley, Robert Johnstone, golang-nuts

Is that really true though? You can have one package that defines min/max for the built-in types (because it uses operators), and then one that uses method(s) Less() and Equals() that works with generics.

A similar technique can be used in sorting.
>To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/A5807C0F-B951-45A1-9EBE-00629FE40B22%40gmail.com.

Michal Strba

unread,
May 31, 2019, 12:45:31 PM5/31/19
to Robert Engels, David Riley, Robert Johnstone, golang-nuts
Btw, as is demonstrated in the proposal, sorting can be solved by passing a comparator to the function:

```go
func Sort(a []gen T, less func(T, T) bool)
```

This is actually a far more flexible way than sorting based on an operator or a `Less` method. Sorting based on an operator or `Less` limits each type to one way of sorting. But, by passing a comparator, you can sort any type, any way you like. You can sort number in ascending, descending order, sort structs by one field, sort them by another. Without any need to introduce new types, operators, or methods.

pi 31. 5. 2019 o 17:46 Robert Engels <ren...@ix.netcom.com> napísal(a):

Randall O'Reilly

unread,
May 31, 2019, 6:29:02 PM5/31/19
to Michal Strba, Ian Lance Taylor, golang-nuts
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
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAO6k0usrzSrh1j-xboqtxh8jJCz0eRDpfvTggfgi-0%3D10XhNoA%40mail.gmail.com.

Randall O'Reilly

unread,
Jun 3, 2019, 4:53:48 AM6/3/19
to Michal Strba, Ian Lance Taylor, golang-nuts
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

Martin Schnabel

unread,
Jun 3, 2019, 6:54:06 AM6/3/19
to golan...@googlegroups.com
Hi,

is my impression correct, that this proposal adds types as values to the
language? It's seems like it does the section 'Unnamed generic
arguments'. That by itself would go a long way and warrants some
discussion, I'd say.

If so, then why use a new keyword 'gen'? Why not 'type' itself.
It would have some symmetry with how the func and struct keywords are
used for closures and unnamed structs. The 'type' keyword has no
possible meaning in the parameter list currently.

I use the 'gen' keyword a lot as identifier, mostly for generators
and generated code. While nobody can claim to use 'type'. This would
make converting code so much easier, if this proposal is accepted.

Just a though. Please tell me whether this would be possible.

Thanks for your work, it's much appreciated.
Martin


On 30.05.19 14:08, Michal Strba wrote:
> Hi Gophers! :)
>
> I've been thinking about generics in Go 2 ever since the original
> contracts proposal and few days ago, ideas finally clicked. One of the
> main things about this proposal is that it deliberately omits the
> ability to restrict the set of types a function can work with. This is a
> limitation, but I hope to convince you that we can still do a vast
> majority of the things we were missing, when we were missing generics.
>
> I'd love to share my proposal with you and engage in a good faith
> conversation.
>
> Link to the proposal.
> <https://gist.github.com/faiface/e5f035f46e88e96231c670abf8cab63f>
>
> Here's what the proposal covers:
>
> 1. Syntax of a new gen keyword.
> 2. Generic functions.
> 3. Unnamed generic arguments (a.k.a. a way to gve a type to the built-in
> newfunction).
> 4. Semantics of generic values (ability to use them as map keys, ...).
> 5. Generic array lengths.
> 6. Reflection and interface{}.
> 7. Generic types (with two examples: Listand Matrix).
> 8. Generic methods and their limitations due to reflection.
> 9. Generic interfaces.
> 10. List of things this proposal can't do.
>
> Thanks,
> faiface
>
> --
> 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...@googlegroups.com
> <mailto:golang-nuts...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/6f5f0785-93f7-475a-991c-fc919c5e6730%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/6f5f0785-93f7-475a-991c-fc919c5e6730%40googlegroups.com?utm_medium=email&utm_source=footer>.

Michal Strba

unread,
Jun 3, 2019, 8:21:40 AM6/3/19
to Martin Schnabel, golang-nuts
Hi Martin.

The proposal adds types as "values", but not really. You can only accept a type to a function, but you cannot return a type. That makes the system far from a dependent type system, even with the support for generic array lengths.

Being able to return types from functions and use those functions in types is what brings all the power (and complexity) of dependent typing, but what I proposed is just a simple system for explicit type anotation directly in the function signature.

Regarding the 'gen' keyword, I chose it because I propose not only generic types, but also generic array lengths. But you are right that using 'type' would probably be better. Do you think that using the 'type' keyword also in the context of generic array lengths would be fine?

To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/739d147e-162d-14fc-a13a-9e7962f074e2%40mb0.org.

Martin Schnabel

unread,
Jun 3, 2019, 9:27:01 AM6/3/19
to golan...@googlegroups.com
Hi Michal,

I would argue that the 'const' keyword would by more correct. Because
the array length is and needs to be constant anyway. And it has
currently no valid meaning in a parameter list, just like with
the 'type' keyword. However i would argue that the array length, if
written as part of the array syntax, as in '[n]elem' does not need an
explicit keyword qualifier, because - again - it's unambiguous in the
parameter context. Would you agree?

Best regards
Martin
> <mailto:golang-nuts%2Bunsu...@googlegroups.com>
> > <mailto:golang-nuts...@googlegroups.com
> <mailto:golang-nuts%2Bunsu...@googlegroups.com>>.
> > To view this discussion on the web visit
> >
> https://groups.google.com/d/msgid/golang-nuts/6f5f0785-93f7-475a-991c-fc919c5e6730%40googlegroups.com
>
> >
> <https://groups.google.com/d/msgid/golang-nuts/6f5f0785-93f7-475a-991c-fc919c5e6730%40googlegroups.com?utm_medium=email&utm_source=footer>.
> > 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...@googlegroups.com
> <mailto:golang-nuts%2Bunsu...@googlegroups.com>.
> To view this discussion on the web visit
> --
> 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...@googlegroups.com
> <mailto:golang-nuts...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAO6k0ut8W8STeA6_AadA9FbL7HxkVimKMfMT3bTBtxDyP1N5_w%40mail.gmail.com
> <https://groups.google.com/d/msgid/golang-nuts/CAO6k0ut8W8STeA6_AadA9FbL7HxkVimKMfMT3bTBtxDyP1N5_w%40mail.gmail.com?utm_medium=email&utm_source=footer>.

Michal Strba

unread,
Jun 3, 2019, 9:50:26 AM6/3/19
to Martin Schnabel, golang-nuts
'const' could be fine too. I guess this is mostly a matter of personal preference.

Regarding the array length syntax. It does require qualifying for two reasons:

1. Unnamed arguments.
2. Using 'gen' (or 'type', 'const') makes it easy to say "gen is not allowed in the return types", which is an important rule. Without qualification, this rule would be hard to express.

To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/068a6b44-4c52-73fc-9ac7-fe46b4cdbe1d%40mb0.org.

Martin Schnabel

unread,
Jun 3, 2019, 10:57:54 AM6/3/19
to golan...@googlegroups.com
I agree. That is a good point. I consider arrays an edge case. Although
still important, it will probably not be all too common. So the extra
verbosity should not be a problem.

I am happy you generally agree and think these minor tweaks can make a
big difference for the roll-out of the proposed feature, if accepted.

I also think, that this is one of the better proposals. It at least
feels more like go, syntax-wise, than most, except for the num part,
which seems like an afterthought.

Again thank you for your work exploring this!

Best regards
Marin
> >     <mailto:golang-nuts%2Bunsu...@googlegroups.com
> <mailto:golang-nuts%252Buns...@googlegroups.com>>
> >      > <mailto:golang-nuts...@googlegroups.com
> <mailto:golang-nuts%2Bunsu...@googlegroups.com>
> >     <mailto:golang-nuts%2Bunsu...@googlegroups.com
> <mailto:golang-nuts%252Buns...@googlegroups.com>>>.
> >      > To view this discussion on the web visit
> >      >
> >
> https://groups.google.com/d/msgid/golang-nuts/6f5f0785-93f7-475a-991c-fc919c5e6730%40googlegroups.com
> >
> >      >
> >
>  <https://groups.google.com/d/msgid/golang-nuts/6f5f0785-93f7-475a-991c-fc919c5e6730%40googlegroups.com?utm_medium=email&utm_source=footer>.
> >      > 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...@googlegroups.com
> <mailto:golang-nuts%2Bunsu...@googlegroups.com>
> >     <mailto:golang-nuts%2Bunsu...@googlegroups.com
> <mailto:golang-nuts%252Buns...@googlegroups.com>>.
> >     To view this discussion on the web visit
> >
> https://groups.google.com/d/msgid/golang-nuts/739d147e-162d-14fc-a13a-9e7962f074e2%40mb0.org.
> >     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...@googlegroups.com
> <mailto:golang-nuts%2Bunsu...@googlegroups.com>
> > <mailto:golang-nuts...@googlegroups.com
> <mailto:golang-nuts%2Bunsu...@googlegroups.com>>.
> > To view this discussion on the web visit
> >
> https://groups.google.com/d/msgid/golang-nuts/CAO6k0ut8W8STeA6_AadA9FbL7HxkVimKMfMT3bTBtxDyP1N5_w%40mail.gmail.com
>
> >
> <https://groups.google.com/d/msgid/golang-nuts/CAO6k0ut8W8STeA6_AadA9FbL7HxkVimKMfMT3bTBtxDyP1N5_w%40mail.gmail.com?utm_medium=email&utm_source=footer>.
> > 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...@googlegroups.com
> <mailto:golang-nuts%2Bunsu...@googlegroups.com>.
> To view this discussion on the web visit
> --
> 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...@googlegroups.com
> <mailto:golang-nuts...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAO6k0usVH6GMsqu%2BpDJ%2BOfeTnF0XDZq-RK_DKW5kxXRkEHsUmA%40mail.gmail.com
> <https://groups.google.com/d/msgid/golang-nuts/CAO6k0usVH6GMsqu%2BpDJ%2BOfeTnF0XDZq-RK_DKW5kxXRkEHsUmA%40mail.gmail.com?utm_medium=email&utm_source=footer>.

Michal Strba

unread,
Jun 4, 2019, 3:51:43 AM6/4/19
to Martin Schnabel, golang-nuts
It at least
feels more like go, syntax-wise, than most, except for the num part, 
which seems like an afterthought.

It is an afterthought. It wasn't in the original proposal and was invented as a way to enable functions like Min, Max, and so on. But I realized that it actually enables many cool things like various generic math structures, vectors, matrices to work with arbitrary numeric types.

It is a special case, but if you try and make it general, you end up with some sort of contracts, which may or may not be what you want, but is what I've been trying to avoid here.

To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/11395c55-4cd4-7c35-2f39-77e49b28799a%40mb0.org.

dpavlenk...@gmail.com

unread,
Jun 4, 2019, 1:16:52 PM6/4/19
to golang-nuts


On Tuesday, June 4, 2019 at 3:51:43 AM UTC-4, Michal Strba wrote:
It at least
feels more like go, syntax-wise, than most, except for the num part, 
which seems like an afterthought.

It is an afterthought. It wasn't in the original proposal and was invented as a way to enable functions like Min, Max, and so on. But I realized that it actually enables many cool things like various generic math structures, vectors, matrices to work with arbitrary numeric types.

It is a special case, but if you try and make it general, you end up with some sort of contracts, which may or may not be what you want, but is what I've been trying to avoid here.

I commented on your gist, but let me add this here. I don't believe there's anything wrong with the concept of contracts. They are necessary to validate usage. What your proposal suggests to me, however, is that contracts can be defined inline, at the point of generic function definition, instead of having a separate "contract" construct. It'll be compiler's job then to validate generic function usage.

Randall O'Reilly

unread,
Jun 5, 2019, 1:47:48 PM6/5/19
to Michal Strba, Ian Lance Taylor, golang-nuts
It’s great to see that so many people share my considerable enthusiasm for this proposal! Seriously, nobody is willing to take a look and provide any feedback?

- Randy

Ian Lance Taylor

unread,
Jun 5, 2019, 2:04:27 PM6/5/19
to Randall O'Reilly, Michal Strba, golang-nuts
On Wed, Jun 5, 2019 at 10:47 AM Randall O'Reilly <rcore...@gmail.com> wrote:
>
> It’s great to see that so many people share my considerable enthusiasm for this proposal! Seriously, nobody is willing to take a look and provide any feedback?
>
> - Randy
>
> > On Jun 3, 2019, at 2:53 AM, Randall O'Reilly <rcore...@gmail.com> wrote:
> >
> > 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,


I don't understand how to use this proposal to write a type-safe
concurrent hash map. I think that is one of the key features that a
generics implementation needs to support.

As a less important issue, relying on a general construct like
"number" is problematic in Go. There are many different ways to slice
up Go's types. "number" is just one of them. There is also integer,
signed integer, unsigned integer, comparable, ordered, float, complex.
One can even think of addable (includes string) and indexable and
sliceable.

Ian

Randall O'Reilly

unread,
Jun 5, 2019, 2:59:32 PM6/5/19
to Ian Lance Taylor, Michal Strba, golang-nuts
On Jun 5, 2019, at 12:03 PM, Ian Lance Taylor <ia...@golang.org> wrote:
>
> On Wed, Jun 5, 2019 at 10:47 AM Randall O'Reilly <rcore...@gmail.com> wrote:
>>
>> It’s great to see that so many people share my considerable enthusiasm for this proposal! Seriously, nobody is willing to take a look and provide any feedback?
>>
>> - Randy
>>
>>> On Jun 3, 2019, at 2:53 AM, Randall O'Reilly <rcore...@gmail.com> wrote:
>>>
>>> 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,
>
>
> I don't understand how to use this proposal to write a type-safe
> concurrent hash map. I think that is one of the key features that a
> generics implementation needs to support.

you can do any valid map operation on the generic type “map”, so at a minimum it seems like you could just add an appropriate mutex around each of the different operations, using a struct interface:

package safemap

type M struct interface {
Map map
Mu sync.RWMutex
}

func (m *M) Set(k key(m), v elem(m)) {
m.Mu.Lock()
if m.Map == nil {
m.Map = make(m.Map)
}
m.Map[k] = v
m.Mu.Unlock()
}



any concrete map that shares that struct interface type signature automatically gets the associated methods:

import safemap

// MySafeMap implements the safemap.M struct interface
type MySafeMap struct {
Map map[string]string
Mu sync.RWMutex
}

func MyFunc() {
m := MySafeMap{}
m.Set(“mykey”, “myval”) // at this point the Set method knows the concrete type of “m”, can compile Set
}

> As a less important issue, relying on a general construct like
> "number" is problematic in Go. There are many different ways to slice
> up Go's types. "number" is just one of them. There is also integer,
> signed integer, unsigned integer, comparable, ordered, float, complex.
> One can even think of addable (includes string) and indexable and
> sliceable.
>
> Ian

The proposal already does include some of those number subtypes (I did leave out complex, for simplicity..). There is probably some optimal 80/20 choice to decide exactly which generic number categories to include. For example, ordered could just be identical to number (i.e., all the different ints, floats, but excluding complex which is not really a number in the same sense — it is more like a vector). You could add comparable to include complex+number but it might be simpler to just say that if you’re writing a generic function that operates on complex numbers, you have to use the “complex” generic to subsume 64 and 128 variants, and otherwise it is excluded from the “number” category and probably few people will notice or complain.. Likewise, maybe you don’t need generic “integer” in addition to both “signed” and “unsigned” (I’ll update my proposal to use “signed” instead of “integer” as that is more specific), but maybe the one extra keyword is worth it. Anyway it seems like these details could definitely be worked out if the overall idea holds water.

I wasn’t really sure to do about string — might be useful to see how far you can get just treating it as a byte array from the generic perspective — otherwise it already stands alone in a type class by itself, so it doesn’t really need a generic version.

Adhering to the minimalist approach, I’m pretty sure you could most of what you want while avoiding things like addable, indexable and sliceable, and just using map, slice, array and their existing operators in a generic way.


Robert Engels

unread,
Jun 5, 2019, 3:17:49 PM6/5/19
to Randall O'Reilly, Ian Lance Taylor, Michal Strba, golang-nuts






-----Original Message-----
>From: Randall O'Reilly <rcore...@gmail.com>
>Sent: Jun 5, 2019 1:58 PM
>To: Ian Lance Taylor <ia...@golang.org>
>Cc: Michal Strba <faifa...@gmail.com>, golang-nuts <golan...@googlegroups.com>
>Subject: Re: [go-nuts] Go 2 generics counterproposal: giving up restricting types
>
>--
>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...@googlegroups.com.
>To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/DA59DC24-5C4A-4712-9CB2-B155A7C459DD%40gmail.com.
>For more options, visit https://groups.google.com/d/optout.

That is not sufficient. You can't require the usage of the built-in map, as specialized maps may have a completely different structure (special hash tables when the keys are ints, or more commonly special CAS techniques for highly concurrent lock-free maps).

Randall O'Reilly

unread,
Jun 5, 2019, 3:33:58 PM6/5/19
to Robert Engels, Ian Lance Taylor, Michal Strba, golang-nuts
That is a good point of clarification about the specific limitation of this proposal: it specifically reifies the existing Go type system and does NOT enable the generic-ification of arbitrary novel types. If you can build a specialized type out of generic versions of existing Go types, then you’re good, but if you need something entirely different, then this won’t do it. The key question is whether having a really simple and tractable “native types” version of generics solves enough problems, while avoiding the challenges of going “fully generic”, to hit that “Go” minimalism sweet spot..

- Randy

Robert Engels

unread,
Jun 5, 2019, 4:19:16 PM6/5/19
to Randall O'Reilly, Ian Lance Taylor, Michal Strba, golang-nuts






-----Original Message-----
>From: Randall O'Reilly <rcore...@gmail.com>
>Sent: Jun 5, 2019 2:33 PM
>To: Robert Engels <ren...@ix.netcom.com>
>Cc: Ian Lance Taylor <ia...@golang.org>, Michal Strba <faifa...@gmail.com>, golang-nuts <golan...@googlegroups.com>
>Subject: Re: [go-nuts] Go 2 generics counterproposal: giving up restricting types
>
>--
>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...@googlegroups.com.
>To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/735428D9-5630-4F56-88AD-0F8E9E8CC473%40gmail.com.
>For more options, visit https://groups.google.com/d/optout.

Even more common data structures like linked maps, tree maps/sets wouldn't be possible. I think custom data structures are the prime usage for generics - which is why I suggested that rather than doing generics, you could do something like this:

map:=make(map[String]String,"ordered,concurrent")

which would use different implementations as decided by the Go platform (with maybe some way of registering additional ones via C, etc.)

It keeps the simplicity of Go, using the existing syntax, but allows custom data structures (although not written in Go - maybe?)

I think data structures are 95% of the use case of generics, but that is just my opinion (although earlier Java based studies I referred to seemed to support the claim).

Michal Strba

unread,
Jun 5, 2019, 6:03:12 PM6/5/19
to Robert Engels, Randall O'Reilly, Ian Lance Taylor, golang-nuts
Ian, have you had the time to evaluate the improvements to my proposal (the original one in this thread)? I'd love to hear if it has some more significat shortcomings and know what to think about. Or, if it has no perspective, I'd love to hear why.

I know you're busy, so responding with "I haven't had the time yet" is completely understandable.

Thanks

lgo...@gmail.com

unread,
Jun 5, 2019, 7:06:07 PM6/5/19
to golang-nuts
Michael,
Considering all  improvements you've made to the original, is the current version of your proposal clear to all following this thread ?


On Wednesday, June 5, 2019 at 6:03:12 PM UTC-4, Michal Strba wrote:
Ian, have you had the time to evaluate the improvements to my proposal (the original one in this thread)? I'd love to hear if it has some more significat shortcomings and know what to think about. Or, if it has no perspective, I'd love to hear why.

I know you're busy, so responding with "I haven't had the time yet" is completely understandable.

Thanks

On Wed, Jun 5, 2019, 22:18 Robert Engels <ren...@ix.netcom.com> wrote:






-----Original Message-----
>From: Randall O'Reilly <rcore...@gmail.com>
>Sent: Jun 5, 2019 2:33 PM
>To: Robert Engels <ren...@ix.netcom.com>
>Cc: Ian Lance Taylor <ia...@golang.org>, Michal Strba <faifa...@gmail.com>, golang-nuts <golan...@googlegroups.com>
>Subject: Re: [go-nuts] Go 2 generics counterproposal: giving up restricting types
>
>That is a good point of clarification about the specific limitation of this proposal: it specifically reifies the existing Go type system and does NOT enable the generic-ification of arbitrary novel types.  If you can build a specialized type out of generic versions of existing Go types, then you’re good, but if you need something entirely different, then this won’t do it.  The key question is whether having a really simple and tractable “native types” version of generics solves enough problems, while avoiding the challenges of going “fully generic”, to hit that “Go” minimalism sweet spot..
>
>- Randy
>
>> On Jun 5, 2019, at 1:17 PM, Robert Engels <ren...@ix.netcom.com> wrote:
>>
>> That is not sufficient. You can't require the usage of the built-in map, as specialized maps may have a completely different structure (special hash tables when the keys are ints, or more commonly special CAS techniques for highly concurrent lock-free maps).
>
>--
>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 golan...@googlegroups.com.

Ian Lance Taylor

unread,
Jun 5, 2019, 7:09:15 PM6/5/19
to Michal Strba, Robert Engels, Randall O'Reilly, golang-nuts
On Wed, Jun 5, 2019 at 3:02 PM Michal Strba <faifa...@gmail.com> wrote:
>
> Ian, have you had the time to evaluate the improvements to my proposal (the original one in this thread)? I'd love to hear if it has some more significat shortcomings and know what to think about. Or, if it has no perspective, I'd love to hear why.
>
> I know you're busy, so responding with "I haven't had the time yet" is completely understandable.

I really can't promise to ever fully evaluate all generics proposals.
There are simply too many of them. All I can honestly do is throw out
some quick comments, as I've done already. If you want detailed
feedback, I encourage you to seek it from other people.

As I said in my reply to Randall earlier " relying on a general
construct like "number" is problematic in Go. There are many
different ways to slice up Go's types. "number" is just one of them.
There is also integer, signed integer, unsigned integer, comparable,
ordered, float, complex. One can even think of addable (includes
string) and indexable and sliceable."

I'm also still concerned about scoping. You added some text, but it's
still unusual in Go for a name that appears in a list to become in
scope for the rest of the list and for the following body.

Ian

Burak Serdar

unread,
Jun 5, 2019, 10:36:48 PM6/5/19
to Randall O'Reilly, Michal Strba, Ian Lance Taylor, golang-nuts
On Wed, Jun 5, 2019 at 11:47 AM Randall O'Reilly <rcore...@gmail.com> wrote:
>
> It’s great to see that so many people share my considerable enthusiasm for this proposal! Seriously, nobody is willing to take a look and provide any feedback?

This reminds me of a proposal I wrote some months ago that uses
existing types as contracts with a new "like" keyword for primitives.
Your proposal takes that idea further and gets rid of contracts
completely. Even though the syntax is cleaner, I think you lost some
of the expressive power of contracts. For instance:

Edges []Edge : does this mean that Edges is an array where each
element is a type that satisfies Edge (and thus each element can have
a different type), or that it is an array where each element is the
same concrete type of Edge?

The motivation behind contracts was to ensure generic types can be
compiled before instantiation. This proposal seems to give up on that.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/9750CFE8-C9B2-40D2-B768-37D8F01602DB%40gmail.com.

Randall O'Reilly

unread,
Jun 6, 2019, 12:31:48 AM6/6/19
to Burak Serdar, Michal Strba, Ian Lance Taylor, golang-nuts
On Jun 5, 2019, at 8:36 PM, Burak Serdar <bse...@ieee.org> wrote:
>
> On Wed, Jun 5, 2019 at 11:47 AM Randall O'Reilly <rcore...@gmail.com> wrote:
>>
>> It’s great to see that so many people share my considerable enthusiasm for this proposal! Seriously, nobody is willing to take a look and provide any feedback?
>
> This reminds me of a proposal I wrote some months ago that uses
> existing types as contracts with a new "like" keyword for primitives.
> Your proposal takes that idea further and gets rid of contracts
> completely. Even though the syntax is cleaner, I think you lost some
> of the expressive power of contracts. For instance:
>
> Edges []Edge : does this mean that Edges is an array where each
> element is a type that satisfies Edge (and thus each element can have
> a different type), or that it is an array where each element is the
> same concrete type of Edge?
>
> The motivation behind contracts was to ensure generic types can be
> compiled before instantiation. This proposal seems to give up on that.

Just to be clear, the proposal is definitely NOT to get rid of contracts at all! The point is actually very similar to your proposal (as you noted) — here’s the link for reference: https://gist.github.com/bserdar/8f583d6e8df2bbec145912b66a8874b3

Specifically any contract specified using like(), e.g., your SignedNumber example (which becomes simply `signed` as the builtin generic type in my proposal) should be essentially identical from the compiler’s perspective, right? They specify the same exact contract, just using a different syntax.

Likewise, any use of a generic native “slice” or “map” type definitely specifies a very concrete “contract” — it is just not an *arbitrary* contract — it is just the familiar existing contract that we all know and love..

I’m not sure about the claim that some of the examples in your proposal could actually be compiled effectively in advance of instantiation. For example, anything involving a struct with specific fields (which is achieved using the struct interface syntax in my proposal, but is essentially functionally the same as the corresponding structs in your proposal and the draft proposal, again just with a different simpler syntax that avoids explicit type parameters), would presumably benefit considerably by knowing the concrete types involved to know about field offsets and specific types used in operations etc. If you don’t know the concrete type(s), then you’re stuck using virtualized “boxing” kinds of approaches for everything in the code, right? If you wait until you have the concrete type, the compiler can decide the best way to optimize the various costs associated with boxing vs. code bloat etc.

Anyway, just to reiterate, the core idea is definitely *not* to abandon contracts — just to use existing native contracts, which constitute a well-known, well-tested finite “basis set” of contracts. By using this very limited space of contracts, we can use builtin keywords and a much simpler syntax, and the compiler should actually have an *easier* time compiling generic code compared to supporting arbitrary contracts. I think it really is the same basic idea from your like() proposal, so I “like” it :)

- Randy

Carl

unread,
Jun 6, 2019, 4:28:46 PM6/6/19
to golang-nuts
This proposal makes sense to me. 

Disclaimer: 
I don't know enough about language design to provide feedback on how it may be refined. This is just my perspective as a potential future user.
  1. It is one of the simplest proposals I've read so far (but I have not read them all - there are too many to keep up with)
  2. It is easy to understand and visualise where it would be used
  3. It is orthogonal - it does not tread on the capabilities of other keywords, but complements them nicely
  4. In conjunction with the "gen eq" and "gen num" keywords, it would be sufficient for all the work I've needed to do


On Friday, May 31, 2019 at 4:29:03 AM UTC+12, Michal Strba wrote:
Hi Gophers! :)

I've been thinking about generics in Go 2 ever since the original contracts proposal and few days ago, ideas finally clicked. One of the main things about this proposal is that it deliberately omits the ability to restrict the set of types a function can work with. This is a limitation, but I hope to convince you that we can still do a vast majority of the things we were missing, when we were missing generics.

I'd love to share my proposal with you and engage in a good faith conversation.


Here's what the proposal covers:

1. Syntax of a new gen keyword.
2. Generic functions.
3. Unnamed generic arguments (a.k.a. a way to gve a type to the built-in new function).
4. Semantics of generic values (ability to use them as map keys, ...).
5. Generic array lengths.
6. Reflection and interface{}.
7. Generic types (with two examples: List and Matrix).

Burak Serdar

unread,
Jun 6, 2019, 5:09:09 PM6/6/19
to Randall O'Reilly, Michal Strba, Ian Lance Taylor, golang-nuts
On Wed, Jun 5, 2019 at 10:31 PM Randall O'Reilly <rcore...@gmail.com> wrote:
>
> On Jun 5, 2019, at 8:36 PM, Burak Serdar <bse...@ieee.org> wrote:
> >
> > On Wed, Jun 5, 2019 at 11:47 AM Randall O'Reilly <rcore...@gmail.com> wrote:
> >>
> >> It’s great to see that so many people share my considerable enthusiasm for this proposal! Seriously, nobody is willing to take a look and provide any feedback?
> >
> > This reminds me of a proposal I wrote some months ago that uses
> > existing types as contracts with a new "like" keyword for primitives.
> > Your proposal takes that idea further and gets rid of contracts
> > completely. Even though the syntax is cleaner, I think you lost some
> > of the expressive power of contracts. For instance:
> >
> > Edges []Edge : does this mean that Edges is an array where each
> > element is a type that satisfies Edge (and thus each element can have
> > a different type), or that it is an array where each element is the
> > same concrete type of Edge?
> >
> > The motivation behind contracts was to ensure generic types can be
> > compiled before instantiation. This proposal seems to give up on that.
>
> Just to be clear, the proposal is definitely NOT to get rid of contracts at all! The point is actually very similar to your proposal (as you noted) — here’s the link for reference: https://gist.github.com/bserdar/8f583d6e8df2bbec145912b66a8874b3
>
> Specifically any contract specified using like(), e.g., your SignedNumber example (which becomes simply `signed` as the builtin generic type in my proposal) should be essentially identical from the compiler’s perspective, right? They specify the same exact contract, just using a different syntax.
>
> Likewise, any use of a generic native “slice” or “map” type definitely specifies a very concrete “contract” — it is just not an *arbitrary* contract — it is just the familiar existing contract that we all know and love..
>
> I’m not sure about the claim that some of the examples in your proposal could actually be compiled effectively in advance of instantiation. For example, anything involving a struct with specific fields (which is achieved using the struct interface syntax in my proposal, but is essentially functionally the same as the corresponding structs in your proposal and the draft proposal, again just with a different simpler syntax that avoids explicit type parameters), would presumably benefit considerably by knowing the concrete types involved to know about field offsets and specific types used in operations etc. If you don’t know the concrete type(s), then you’re stuck using virtualized “boxing” kinds of approaches for everything in the code, right? If you wait until you have the concrete type, the compiler can decide the best way to optimize the various costs associated with boxing vs. code bloat etc.

You don't need boxing with contracts specified as a list of possible
types. If you have a contract that lists types T1, T2, ... as possible
types, then you can compile the types and functions using that
contract once for each minimal concrete type that implements T1,
T2,.... A minimal concrete type that implements T1, T2,.. can be
obtained from the contract definition by creating a struct/interface
containing the list of fields/methods contract type has.

Michal Strba

unread,
Jun 6, 2019, 5:38:31 PM6/6/19
to Ian Lance Taylor, Robert Engels, Randall O'Reilly, golang-nuts

I really can’t promise to ever fully evaluate all generics proposals.

Perfectly understandable. I’ll show the benefits without you needing to fully evaluate the proposal then :)

it’s still unusual in Go for a name that appears in a list to become in scope for the rest of the list and for the following body.

Okay, so here is the main benefit of the scoping.

Let’s take this simple function that returns a static array with all elements filled with some provided value.

Here’s how the signature would look in my proposal:

func Filled(gen n, x gen T) [n]T

And here’s how it would look if we had to list the generic arguments in a separate list (feel free to supply gen with any other word):

func Filled(gen n, T)(x T) [n]T

Now, in this latter version, it’s not really clear how and where the generic type gets inferred. Do I need to specify it manually? Under what circumstances? When is the compiler able to infer it for me? Answers to these questions are not clear.

On the other hand, in my proposal, the answers are very clear: unnamed arguments get specified, everything else gets inferred.

func Filled(gen n, x gen T) [n]T
//           ^        ^
//      specified  inferred

Furthermore, there is never a choice between specifying and inferring a generic type. The signature tells exactly which one the user must do.

One more minor benefit of this syntax is that it eliminates any extra parentheses, keeping the clutter down and parsing easy.

I’ll respond to one more of your concerns.

There is also integer, signed integer, unsigned integer, comparable, ordered, float, complex. One can even think of addable (includes string) and indexable and sliceable.

Sure, we can imagine many ways of dividing types into groups. But just because we can imagine that does not mean we need to.

I would argue that the “number contract” is far more useful than “addable”, “indexable”, or anything else you can imagine.

The “number contract” would include all the number types (int*, uint*, float*, complex*). Arithmetic and logic operations common to these types would be available. This is a rich set of operations: +, -, *, /, <, >, and so on. Also, all of these types allow using untyped integer constants as their values.

Sure, you wouldn’t be able to put strings in Sum function with this proposal, but do you really need to do that? I don’t think so.


št 6. 6. 2019 o 1:08 Ian Lance Taylor <ia...@golang.org> napísal(a):

Luis Furquim

unread,
Jun 7, 2019, 9:32:42 AM6/7/19
to golang-nuts


Hello gophers,

I have almost no experience on language definitions/proposals and on generics. 
But an idea came to my mind and I wanted to share it. 
It is an idea, not a proposal, I haven't worked on detailing/elaboration, etc.
As stated on my gist, I got the text and examples from Faiface gist and adapted to my idea. 
No plagiarism intent, just to quickly have something readable by people. 
But, if people finds the copy/edit method I used is offensive, just point this and I may delete the gist.

So, here is the gist:
https://gist.github.com/luisfurquim/548c37870f7ed5a57a1f91a696cfc62f

Best regards,
Luis Otavio

Burak Serdar

unread,
Jun 7, 2019, 11:17:48 AM6/7/19
to Luis Furquim, golang-nuts
On Fri, Jun 7, 2019 at 7:32 AM Luis Furquim <luisf...@gmail.com> wrote:
>
>
>
> Hello gophers,
>
> I have almost no experience on language definitions/proposals and on generics.
> But an idea came to my mind and I wanted to share it.
> It is an idea, not a proposal, I haven't worked on detailing/elaboration, etc.
> As stated on my gist, I got the text and examples from Faiface gist and adapted to my idea.
> No plagiarism intent, just to quickly have something readable by people.
> But, if people finds the copy/edit method I used is offensive, just point this and I may delete the gist.


One problem with this type of generic types is the lack of type
checking at the time of generic compilation. You can only type check
the generic functions when they are instantiated and that can cause
hard to decipher error messages. The contracts idea was promoted to
eliminate those.

>
> So, here is the gist:
> https://gist.github.com/luisfurquim/548c37870f7ed5a57a1f91a696cfc62f
>
> Best regards,
> Luis Otavio
>
>
> Em quinta-feira, 30 de maio de 2019 13:29:03 UTC-3, Michal Strba escreveu:
>>
>> Hi Gophers! :)
>>
>> I've been thinking about generics in Go 2 ever since the original contracts proposal and few days ago, ideas finally clicked. One of the main things about this proposal is that it deliberately omits the ability to restrict the set of types a function can work with. This is a limitation, but I hope to convince you that we can still do a vast majority of the things we were missing, when we were missing generics.
>>
>> I'd love to share my proposal with you and engage in a good faith conversation.
>>
>> Link to the proposal.
>>
>> Here's what the proposal covers:
>>
>> 1. Syntax of a new gen keyword.
>> 2. Generic functions.
>> 3. Unnamed generic arguments (a.k.a. a way to gve a type to the built-in new function).
>> 4. Semantics of generic values (ability to use them as map keys, ...).
>> 5. Generic array lengths.
>> 6. Reflection and interface{}.
>> 7. Generic types (with two examples: List and Matrix).
>> 8. Generic methods and their limitations due to reflection.
>> 9. Generic interfaces.
>> 10. List of things this proposal can't do.
>>
>> Thanks,
>> faiface
>
> --
> 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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/d284f74d-1e2c-474e-bc0d-a30413d17d98%40googlegroups.com.

Luis Furquim

unread,
Jun 7, 2019, 1:13:39 PM6/7/19
to Burak Serdar, golang-nuts
Hi Burak,

So, how about to change the idea to accept contracts as restrictions to generic types? 
For example:

contract stringer(x T) {
	var s string = x.String()
}

Could be expressed this way:
type stringer generic{
   contract String() string
}


Alternatively it could have multiple definitions:

contract adjustable(x T) {
	var _ T = x.Adjust()
	x.Apply()
}

Could be expressed this way:
type adjustable generic{
	contract (
           Adjust() adjustable
	   Apply()
        )
}


So, changing this way could solve this issue?

Best regard,
Luis Otávio



--
Luis Otavio de Colla Furquim

alanfo

unread,
Jun 7, 2019, 3:02:48 PM6/7/19
to golang-nuts
Michal,

Without wishing to over-complicate your proposal, I think you should at least consider adding "gen int" to the mix.

The reason I say this is because the integer types support a lot more operators than the floating point and complex types do, namely:

1. The remainder operator (%).

2. The bitwise operators (&,|, ^, &^).

3. The shift operators (<<, >>).

4. String conversion (using string(x)).

Also integers are always ordered, whereas complex types are not, and are subject to overflow which is something floating point types never do,

So having both 'num' and 'int' would give you better coverage of the available operators and often times you only want a generic function to operate on integer types anyway.

Alan


Reply all
Reply to author
Forward
0 new messages