On Fri, Sep 7, 2018 at 11:39 AM, Axel Wagner
<[email protected]> wrote:
> On Fri, Sep 7, 2018 at 3:10 PM Ian Lance Taylor <[email protected]> wrote:
>>
>> This does surprise me. I'm certainly too close to the problem, but to
>> me it always seems quite clear which type arguments a contract allows
>> and excludes. It's exactly the set of types that type check successfully.
>
>
> I yield that it's a bit nit-picky, but I believe we agreed that to not be
> *quite* the case. e.g. `[1]int` is not type-checking for the body of
> `contract indexable (a T) { a[1] = 42 }`, but the contract will likely
> allow it, because you can't enumerate all possible indices.
I'm not precisely sure what you are saying, but I do think that given
contract indexable(a T) {
a[1] = 42
}
then [1]int will not satisfy that contract. For better or for worse,
compiling that function body with T set to [1]int will give a compile
time error, so [1]int is not permitted.
> Similarly, I'm not sure how I'd specify contractually that an integer is
> supposed to be signed or unsigned. Naively, I could require signedness by `i
> = -1` and maybe unsignedness by `i = 1 << (8*unsafe.Sizeof(i)-1)`, I guess
> (though requiring unsafe, ugh)? But that would also, in a way, back to the
> array-case: If we would allow those contracts, then `i << 1` wouldn't allow
> to shift by more than 1, but if we'd do `i << 63`, then anything below a
> uint64 isn't allowed. So, just as with arrays, we seem to have to disable
> the "constant overflows" check in contracts. But then… I can't figure out a
> way to require an integer to be un/signed.
I think your contracts do require signedness and unsignedness. When
you ask whether `i << 1` should permit shifting by values other than
1, you are going back to the question of what generic function bodies
are permitted by a given contract. Constants in general are
definitely one of the more confusing aspects that have to be sorted
out.
>> It's true that sometimes this can be a surprising type,
>> but to me that seems just like the fact that it can be surprising
>> which types implement an interface.
>
>
> ISTM that these cases are pretty straight forward to enumerate: For a type
> to satisfy an interface, all methods in that interface either a) are
> declared with that type as a receiver or b) are promoted by an embedded
> struct field. I guess there could be some confusion around unexported
> identifiers?
>
> I don't know, obviously this is a subjective question and it's hard to argue
> what's confusing and what isn't. But what am I missing about interfaces
> here? Compared to contracts, that seems pretty straight forward.
I don't think you're missing anything, I just meant to allude to the
fact that a type may have a method such that it unexpectedly satisfies
an interface, although it was not intended to.
Ian
--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.