On Sat, 18 Jul 2020, 13:25 Jan Mercl, <0xj...@gmail.com> wrote:

> On Sat, Jul 18, 2020 at 1:39 PM roger peppe <rogpe...@gmail.com> wrote:
>
> > I didn't say there was exactly one construct for each kind of name
> definition. In current Go, when a name is defined, it's defined inside a
> construct that is explicitly about defining that name. By contrast, in your
> proposal, we take an arbitrary type and add a dollar qualifier on a name
> somewhere inside it, and that turns the construct into a definition. That
> doesn't feel very Go-like to me.
>
> I think about type parameters in the same way as variables. We don't
> list all the variables in a function in a special list.


The variables in a function aren't part of its publicly visible API.

A _value_
> variable holds a number, for instance. A type parameter holds a
> _type_. Both variable and type parameters are declared where
> necessary, not upfront. Well, the parameter list of a function is an
> upfront list, but that's the only place.
>

It's an important distinction to make: the parameter list of a function is
part of its type definition the same way that the type parameter list of a
generic function is part of its type definition.

Another way to think about type parameters, let me call them also type
> variables, is that value variables are a run time thing while type
> variables exist only at compile time. Otherwise they seem pretty
> similar to me.


> > It's an arbitrary place because it's somewhere buried inside the generic
> type
> > or function. ISTM that it's not great that the form of the types or code
> should
> > directly determine the order of the type parameters. To take an example,
> > say I have some code that uses some generic container defined externally:
>
> Ok, I think now I understand better.
>
> >     type S struct {
> >         container *external.Container@T1@T2
> >     }
>
> Note this would be invalid under the alternative proposal. The correct
> form would have to be:
>
> type S struct {
>         container *external.Container@$T1@$T2
> }
>
> And with the order fixing hack (Types is an example. Whatever name
> works, even _, but making  it exported enables it to be shown in
> godocs):
>
> type S struct {
>         Types [0]struct{$T1, $T2}
>

I think you'd need a semicolon there, not a comma, for the record (and I
think that gofmt would format this differently).

       container *external.Container@T1@T2
> }
>

What if S isn't a struct type?


>
> > Now what if we want to change the private field to use some alternative
> container implementation that happens to take
> > its type arguments in a different order?
> >
> >     type S struct {
> >         container *other.Container@T2@T1
> >     }
>
> type S struct {
>         Types [0]struct{$T1, $T2}
>         container *other.Container@T2@T1
> }
>
> IOW, the type parameter list will in some cases appear as it does in
> the original proposal, just not in the prominent position. In other,
> possibly most cases the type parameter list is no longer needed. And
> let's not forget that the original draft also has its "hacks", kind
> of. It requires writing interface{} constraint in some cases


That's just an omission of convenience - all type parameters without
constraints are implicitly "interface{}", so really is the case without
that qualification which is the "hack" (or syntax sugar if you prefer).

, it
> requires parenthesis in other places to resolve parsing ambiguities.
> Both of which the alternative draft does not seem to suffer from.
> Compromises...
>

Which compromises are you referring to here?


> >> I guess that type parameters will in practice appear most often right
> >> in the signature anyway.
> >
> >
> > I'm not keen on this rationalisation. It feels like working around
> something that could have been done correctly from the outset.
>
> It's just my guess. A corpus of real existing generic Go2 code is
> needed to get some real numbers.
>
> > Here's another example:
> >
> >     type S struct {}
> >
> >     func (s S) Bz() $B {
> >         var b B
> >         return b
> >     }
> >
> >     func (s S) Az() $A {
> >         var a A
> >         return a
> >     }
> >
> > AFAICS in this case the ordering of the methods of S influences the
> order of the type parameters required to instantiate S.
> > If we reorder the Az and Bz methods, then we're breaking compatibility.
> What if they're in different files?!
>
> You're right and this hadn't occurred to me before. The only solution
> I can see is:
>
> type S struct { Types [0]{$A, $B} }
>
> But I have to say that this particular example seems rather artificial
> to me.


It may be, it may not, but it's clear to me that the current draft proposal
copes with this case easily and elegantly which yours does not. (also ,
what if S is not a struct type?)

And

maybe then the occasional Types hack does not hurt that
> much. After all, it then makes the alternative draft, in such cases
> only, become in some approximation more or less the same as the
> original one - with the explicit type parameter list. While
> substantially less verbose in other, again possibly more common cases.
>
> >> It's subjective, so saying I like it does not matter. Not sure what is
> >> meant by "the merging of reference and definition", can you please
> >> clarify?
> >
> >
> > I mean that we have one place that's both defining new names and acting
> as a type declaration. It feels to me like you're really trying to avoid
> defining the generic types as parameters, but you end up with them as
> implicitly declared parameters anyway, with some additional problems picked
> up along the way.
>
> I like the note from @bugpowder (another example why I see the @ sign
> as a natural fit) that you can think of type parameters as the
> property of a name like in exported vs non exported names.


It's clearly not just a property of the name though, in my view - it's a
property of the type that's associated with the name. If it was genuinely a
property of the name, then you wouldn't need the $ qualifier.

Exported
> names are also nowhere explicitly _declared_ as being exported. They
> are just such when they start with a capital letter in the place where
> they are _used_. So type parameters may be thought about like being
> such when they start with the $ sign.
>
> Very subjective, but it makes sense to me.
>
> Honestly, I think there's about zero chance for the alternative draft
> to be seriously considered by the Go team. But the discussion about
> it, like this one, can maybe bring some new and/or interesting
> views/ideas on/about the topic.
>
> Thanks to all for participating in this hopefully useful process.
>

-- 
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/CAJhgacgDUvYEb383CaPg3Z2PTN8o_BWL%3Dffbg25OU0pm98vm7g%40mail.gmail.com.

Reply via email to