On Fri, Sep 7, 2018 at 10:51 AM, jimmy frasche <soapboxcic...@gmail.com> wrote: > > To describe a sufficiently-tight contract you need to be able to come > up with an elaborate conjunction of properties that allow everything > needed while disallowing everything that would cause your code to > break. To read such a contract, you need to be able to know all the > rules involved and to be able to run the solver in your head that > says: okay X, Y, Z can do A. X and Y can do B. And Y and Z can do C. > Ah, so it must be Y.
What does "sufficiently-tight" mean, though? As you know, in general Go encourages programming with code rather than programming with types. Being able to precisely specify the set of types that a generic function can use is not really a goal. Keeping the type system simple has a higher priority. > In the generics thread, we were talking about embedding type arguments > and what would happen if you embedded a regular type and a type > argument. If that's allowed that would cause issues when a selector in > the type argument and the regular type collided so the contract would > need to be > > struct{ io.Reader; T}{}.Read > > To express that T cannot have a Read selector. That's a somewhat > subtle contract to write and to read. Once you know what it means and > memorize the pattern it's clear, but it would be a hard ask to wake > someone up in the middle of the night who's never seen it and have > them explain the implications. Just to make it worse, T would be permitted if T is a struct with an embedded field that has a Read method. It's not clear to me why anybody would write a contract like this. I suppose the next question is whether we need to ban weird code from contracts, or whether contracts are so prone to weird code that they are inherently hard to use. > Any contract that's more than a few lines is going to need a large > comment explaining what is and is not allowed by the contract. While > you have to do that with properties of values inexpressible in the > type system anyway but I don't think you should have to do that for > what should amount to "any unsigned integral type". Again I'm not sure why it's important to be able to write a contract that only permits unsigned integer types. That said, here is one: contract unsigned(v T) { // Require T to be an integer type. v % 1 // This is satisfied by any unsigned integer type, but not by a signed integer type. v = 1<<(unsafe.Sizeof(v) * 8 - 1) } 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 golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.