On Tue, Sep 11, 2018 at 4:39 PM Larry Clapp <la...@theclapp.org> wrote:

> Directly accessing a field in a generic struct might be *rare*, but it
> seems like it shouldn't be *impossible*.
>

I think it would be better if it is, but if it introduces additional cost,
that cost needs to be weighed against the benefit :) That's why having real
use cases is useful :)


> If you're going to argue that "you can just write access functions"
>

Note that there is a difference in what I provided, in that it actually
doesn't require the *user* of the type to write any boilerplate (and the
author only has to write a tiny amount). This is already progress over the
current situation :)


> , well, then it seems like the whole generics discussion could be rebutted
> with "but you can just write a code generator", and with the same rejoinder
> (to wit, more or less, "that's what the compiler *is*, and we're trying
> to standardize it and make it easier").
>
> — L
>
> On Tuesday, September 11, 2018 at 9:53:33 AM UTC-4, Axel Wagner wrote:
>>
>> Hi Larry,
>>
>> On Tue, Sep 11, 2018 at 3:25 PM Larry Clapp <la...@theclapp.org> wrote:
>>
>>> This question frankly struck me odd, given the context.  To paraphrase:
>>> "Do I have examples of where accessing a field in a generic struct type
>>> might be useful?"  I kind of assumed that, hip-deep as we are in a
>>> discussion of generic functions, that such a thing might be understood?  I
>>> mean, accessing struct fields in functions is ... useful?  Would not
>>> accessing struct fields in generic functions be ... similarly useful?
>>>
>>
>> TBH I'm not sure. Struct fields, to me, have always been a property of a
>> concrete type and I don't see a need to abstract over them. Maybe I'm
>> suffering from Stockholm syndrome, but consider that Go *never* had the
>> ability to specify existence of fields in an interface - and that's not
>> because it would've been very hard to implement.
>>
>> 1. The draft proposal discusses the Corresponding function, to assign
>>> fields of the same name from one struct to another, of different types (
>>> here
>>> <https://go.googlesource.com/proposal/+/master/design/go2draft-contracts.md#fields>
>>> ).
>>>
>>
>> I saw that example and I find it kind of contrived (as I said in the new
>> thread I started). If you look at the examples section in the design doc,
>> they are all very practical and motivated by experience reports. Or to put
>> it another way: This example looks an awful lot like "because we can", not
>> a "we need to, because".
>>
>> 2. To quote the draft proposal, "ever popular Min and Max functions", as
>>> applied to structs.
>>>
>>
>> Personally, I find that an odd case to make. The function would
>> inherently prescribe the field name to sort by (so, e.g., you couldn't sort
>> a "Person"). So to use it, you already need some control over the struct.
>> But if you have that control, then why not
>>
>> type Key(type T ordered) T
>> func (k Key(T)) SortKey() T { return k }
>>
>> contract key(v T) {
>>     var _ interface{SortKey() T} = v
>>     v.SortKey() < v.SortKey()
>> }
>>
>> func MinKeys(type T key) (x, y T) T {
>>     if x.SortKey() < y.SortKey() {
>>         return x
>>     }
>>     return y
>> }
>>
>> used as
>>
>> type MyStruct struct {
>>     sort.Key(string)
>>     Other int
>>     Field float64
>> }
>>
>> I'd argue that is… the same-ish? It's a little bit more code, but it also
>> allows a) the MinKeys function to be used with any defined type, by adding
>> a method to it, b) to unexport the method name of the interface, so you
>> actually get package-scoped requirements on "keys" (i.e. a crypto.Key
>> contract and a sort.Key contract wouldn't collide) and c) used just as
>> conveniently, once you accept that putting a constraint on the name of a
>> field is similar to putting a constraint on the field being an embedded
>> field of a specific type.
>>
>> i.e. IMO it's strictly more generic and useful.
>>
>>
>>>   Somewhat to my surprise, the draft doesn't actually give a sample
>>> implementation of these, at least not that I could find.  So here's my
>>> attempt:
>>>
>>
>>> contract key(x T) {
>>>         x.Key < x.Key // specify that T must have a Key field and that
>>> it must be ordered
>>> }
>>>
>>> func MinKeys(type T key)(x, y T) T {
>>>         if x.Key < y.Key {
>>>                 return x
>>>         }
>>>         return y
>>> }
>>>
>>> So, I think accessing fields of generic struct types would be handy,
>>> yeah.
>>>
>>> — L
>>>
>>> On Tuesday, September 11, 2018 at 6:54:06 AM UTC-4, Jonathan Amsterdam
>>> wrote:
>>>>
>>>> Do you have actual examples of how that would be useful to you?
>>>>
>>>> On Monday, September 10, 2018 at 9:45:12 PM UTC-4, Larry Clapp wrote:
>>>>>
>>>>> The conversation here is deep, and I haven't followed all of it.  I
>>>>> *think* y'all are discussing some different contract system than the
>>>>> actual draft proposal?
>>>>>
>>>>> If that's the case:
>>>>>
>>>>> You can't express field-accessors, which is an actual, inarguable
>>>>>> reduction in power that I'm perfectly fine with
>>>>>
>>>>>
>>>>> How would you instantiate a generic function that wanted to access
>>>>> field F of a generic type T?
>>>>>
>>>>> if you can't do that, well, I'm not fine with that.
>>>>>
>>>>> But I may have misunderstood.
>>>>>
>>>>> — L
>>>>>
>>>>> On Monday, September 10, 2018 at 7:45:04 PM UTC-4, Axel Wagner wrote:
>>>>>>
>>>>>> The unambiguous cases aren't ambiguous of course. It's the ambiguous
>>>>>> cases I'm concerned about :) My post and this thread contain a bunch of
>>>>>> those. They are mostly growing out of builtin functions and things like
>>>>>> `range` statements and index-expressions.
>>>>>>
>>>>>> You can translate all of my "pseudo-interfaces" into a clear and
>>>>>> short contract
>>>>>>
>>>>>> contract comparable (v T) { v == v } // also allows !=
>>>>>> contract ordered (v T) { v < v } // also allows <=, >, >=
>>>>>> contract boolean (v T) { v || v } // also allows &&, !
>>>>>> contract bitwise (v T) { v & v } // also allows |, ^, <<, >>
>>>>>> contract arith (v T) { v * v } // also allows +, -, /
>>>>>> // well, this one's a bit harder…
>>>>>> contract concat (v T) { v + v; v == "" } // also allows range,
>>>>>> index[int], copy
>>>>>> contract complex (v T) { real(v) } // also allows imag(v)
>>>>>> contract nilable (v T) { v == nil } // also allows != nil
>>>>>>
>>>>>> There is some discussion about maps, slices and channels to be had -
>>>>>> but I think the vast majority of interesting cases can be covered by 
>>>>>> taking
>>>>>> e.g. a `chan T`. A defined type with underlying type `chan T` is 
>>>>>> assignable
>>>>>> to that, so it would appear a perfectly fine way to express this contract
>>>>>> contract Chan (ch C, el T) { var x T = <-ch; ch <- x }
>>>>>> (and correspondingly for send/recv-only channels).
>>>>>>
>>>>>> You can't express field-accessors, which is an actual, inarguable
>>>>>> reduction in power that I'm perfectly fine with (similarly to how we're
>>>>>> fine with interfaces not being able to express that).
>>>>>>
>>>>>> Which IMO brings up the question: If we can express the vast majority
>>>>>> (or even all) of the needed contracts as combinations of this handful of
>>>>>> base-cases, why would we need to allow the full power of Go syntax, which
>>>>>> enables to write all the less than obvious ones too?
>>>>>>
>>>>>> (to re-emphasize: All of this isn't polished. I did sanity-check
>>>>>> against the examples in the contract design doc, but I have not put 
>>>>>> enough
>>>>>> thought into it that there might not be a couple nooks and crannies I
>>>>>> haven't thought of, as you've proven before :) )
>>>>>>
>>>>> [snip]
>>>
>>> --
>>> 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.
>>> 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.
> 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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to