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 <[email protected]
> <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 <[email protected]>
>>> 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 <
>>>>>>> [email protected]> 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 <
>>>>>>>>> [email protected]> 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 [email protected].
>>>>>>>> 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 [email protected].
>>>>>> 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 [email protected].
>>>> 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 [email protected] <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 [email protected].
For more options, visit https://groups.google.com/d/optout.