A lot of those just pick out a subset of built-in types (or a type whose 
underlying type is a built-in). boolean is an obvious example, but arith is 
just all the numeric types.

We already have names for those: int, bool, etc. We just need to combine 
them with "or". E.g. bool is "underlying(bool)", complex is 
"underlying(complex64) | underlying(complex128)".

I don't think any of the index or channel constraints are necessary. You 
can just put those in the function definition, e.g.

   func collect(type T)(c chan T) []T


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 :) )
>
> On Tue, Sep 11, 2018 at 1:21 AM Jonathan Amsterdam <jbams...@gmail.com 
> <javascript:>> 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...@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