Hi, Axel,

You're certainly right: we can *get around* not having access to specific 
fields in generic functions.  And my MinKeys example may've been 
suboptimal, or not a great example to begin with.

And the fact that you have to hard-code the field name(s) to be accessed in 
the contract also seems a little sub-optimal.  On the other hand, trying to 
figure out a reasonable way to make the field names variable would probably 
be worse.  ... Even just trying to come up with an example here got ugly 
pretty quickly.

I guess I kind of imagine that, for any example in the draft, you could put 
the generic variable in a struct, and there you'd have accessing a field in 
a generic struct type.

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

If you're going to argue that "you can just write access functions", 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 
> <javascript:>> 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 <javascript:>.
>> 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