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 <rcoreil...@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,
> 
> - 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/9750CFE8-C9B2-40D2-B768-37D8F01602DB%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to