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 :) ) On Tue, Sep 11, 2018 at 1:21 AM Jonathan Amsterdam <jbamster...@gmail.com> wrote: > > > On Monday, September 10, 2018 at 4:17:57 PM UTC-4, Axel Wagner wrote: >> >> On Mon, Sep 10, 2018 at 8:57 PM Jonathan Amsterdam <jbams...@gmail.com> >> wrote: >> >>> FWIW, I think Ian's criticism of not wanting a list of new identifiers >>>> to express operator constraints is fair. It is a genuine roadblock to c) >>>> and if we're dead set of setting that as a baseline requirement, I agree >>>> that a declarative/interface-based approach won't work. >>>> >>> >>> I don't understand. Why are names so important? Why couldn't you use "T >>> == T" to mean "T is comparable"? Or "To(From)" to mean "From is convertible >>> to To"? >>> >> >> It's not the name that is important, it's the declarative nature. I and >> other people have already gone into detail with the problems we are having >> with using imperative constructs to define constraints (mainly that they >> are ambiguous and that it's hard both to enumerate the sets allowed by a >> contract and to define a suitable contract for an intended set of >> constraints). >> > > I completely agree with you there (although I find the > declarative/imperative terminology confusing). I think that except for > interface-like constraints, we should be constraining by broad properties > of types like comparable, ordered and numeric, rather than specific > operations. > >> >> > I don't care if the declarative instruction is called "flooglehorn" or >> "comparable". But I do care that it's an an actual declaration, mapping 1:1 >> in a clear way to intent. Not an ambiguous statement from Go's current >> Grammar. >> > > It wouldn't be ambiguous. The spec would say "in type constraints, `T == > T` means that T is comparable". I think people would learn to understand > that, just as they understand that for a type T, `*T` means "pointer to T," > not "dereference T". > > > > >> >> > >> Personally, I don't think that should be a requirement. Personally I >>>> think it's worth adding extra identifiers, if we get declarative >>>> constraint-specs for that - but that's just my opinion and everyone has one >>>> of those. >>>> >>>> But the issues you are bringing up are IMO not "fundamental'. a) to c) >>>> from above aren't really touched by your criticism, AIUI. To me, they seem >>>> like issues of syntax and how to phrase the spec. >>>> >>>> But if generics are to have operator constraints like T == T, then >>>>> something in the language has to change. Either not all interfaces are >>>>> types, or some interfaces have methods that can't be called, or Go >>>>> operators can have operands of different types. These changes are not >>>>> minor >>>>> tweaks: they alter fundamental aspects of the language. >>>>> >>>>> Contracts, on the other hand, are purely additive. They only come into >>>>> play when writing generic code. If I'm not mistaken, the draft design >>>>> doesn't change or even add anything to non-generic Go. There is something >>>>> attractive about that orthogonality. >>>>> >>>> >>>> I agree. I think that's fair. I don't think for that they need to be >>>> imperative specifications though. >>>> >>>> (or, allow embedding interfaces into contract-declarations, remove the >>>>>> "type-checking function body" idea and instead define a set of >>>>>> base-contracts you can use for operators) and you'd end up with pretty >>>>>> much >>>>>> my design. >>>>>> >>>>> >>>>> That doesn't sound like your original design at all. >>>>> >>>> >>>> You need to squint harder :) From the rest of your mail, ISTM that we >>>> are putting emphasis on different aspects of my description and the >>>> contracts design. What I was trying to say is that IMO the things about my >>>> design I like and the things about the contract design you like can >>>> probably be reconciled. >>>> >>>> The first seems problematic, because for multi-parameter contracts you >>>>> wouldn't know which type the parameter referred to. >>>>> >>>> >>>> FWIW (we are now getting lost in ifs-and-buts and it's no longer clear >>>> what the specific ideas are we are talking about), in my original design as >>>> well as that ad-how handwaving you're quoting, constraints always apply to >>>> a single type and you'd use parametric interfaces (or… interfaces+) to >>>> express simultaneous restrictions. >>>> >>>> But FTR, I did not intend to start an actual discussion around that, >>>> its far too underspecified for that. I was sincere when I said your >>>> criticism is fair and that I had to think about it. My handwaving was just >>>> to explain why I don't think it can justifiable be called a >>>> *fundamental* issue. >>>> >>>> >>>>> The second seems reasonable to me. Now we can talk about issues like >>>>> whether this adds too many names to the language, or whether you've >>>>> described all the important constraints (I think conversion and >>>>> assignability are important, for instance). >>>>> >>>> >>>> Again, the caveat of handwaving still applies (IMO we should constrain >>>> ourselves to talk about sufficiently spelled out designs - Ian's contract >>>> design qualifies and I'd also feel fine with the thing I wrote down in my >>>> blog, as long as we agree that its conditional on polishing the "are >>>> pseudo-interfaces usable as types" question), but: Given that we have >>>> type-parameters, adding that is fairly straightforward in the form of (in >>>> the words of my blog post) parametric pseudo-interfaces >>>> "convertible{To,From}(T)" and "assignable{To,From}(T)". >>>> >>>> But yeah, talking about in too much depth here would IMO constitute >>>> high-jacking of threads about Ian's design. I'm also totally cool to start >>>> a new thread about this after I had time to incorporate your feedback. >>>> Unfortunately this isn't my job, so I have to find time between other >>>> things :) >>>> >>>> Anyway. I think I've been ranty enough for today :) >>>> >>>> On Sunday, September 9, 2018 at 5:21:28 PM UTC-4, Axel Wagner wrote: >>>>>> >>>>>> I don't think saying that is is productive. contracts are more than >>>>>> just "identifiers used as constraints", they are also a syntactic >>>>>> construct >>>>>> to specify those. I specifically don't allow that and that's the whole >>>>>> point I'm making. So this doesn't seem like a particularly nice way to >>>>>> have >>>>>> a discussion. >>>>>> >>>>>> But yes, if it makes you happier, we can call them "contracts", allow >>>>>> to embed them into interfaces and remove contract declarations from the >>>>>> design (or, allow embedding interfaces into contract-declarations, remove >>>>>> the "type-checking function body" idea and instead define a set of >>>>>> base-contracts you can use for operators) and you'd end up with pretty >>>>>> much >>>>>> my design. >>>>>> >>>>>> On Sun, Sep 9, 2018 at 11:17 PM Jonathan Amsterdam < >>>>>> jbams...@gmail.com> wrote: >>>>>> >>>>>>> >>>>>>> >>>>>>> On Sunday, September 9, 2018 at 3:19:16 PM UTC-4, Axel Wagner wrote: >>>>>>>> >>>>>>>> On Sun, Sep 9, 2018 at 8:49 PM Jonathan Amsterdam < >>>>>>>> jbams...@gmail.com> wrote: >>>>>>>> >>>>>>>>> The problem is that this program seems to type-check, but it is >>>>>>>>> invalid. The == operator is specified to work on operands of the same >>>>>>>>> type, >>>>>>>>> and it is being used on operands of different types. >>>>>>>>> >>>>>>>> >>>>>>>> Good point. I have to think about it. An ad-hoc solution, FWIW, >>>>>>>> would be to only take into account (or allow) pseudo-interfaces for >>>>>>>> type-constraints. >>>>>>>> >>>>>>> >>>>>>> The draft design has a name for those: contracts. >>>>>>> >>>>>>> -- >>>>>>> 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...@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...@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.