On Thu, Aug 1, 2019 at 6:35 AM, Max <massimiliano.ghila...@gmail.com> wrote:

> Thus it would require 'T' to be a pointer - namely '*big.Int' - to match.
> It would mean that the receiver itself of the contract 'T Cmp(other T)
> int' is a pointer. Is it a case allowed by contracts?
>

Yes, this is something which is supported be contracts. But this does raise
the point that the ability to try and fudge over whether `T` or `*T` (where
`T` is a contract parameter) satisfies a method constraint is limited by
the fact that constraint parameters can appear in multiple positions in a
given method signature, and only one of those places (the receiver) has
conventionally allowed auto-referencing. Also, it doesn't matter much that
`Cmp` can be in the method set of both `A` and `*A` (where `A` is a
concrete value type) when only one of those types will be identical to the
type the `other` method parameter, so only one type can satisfy the
contract.

Personally, I think the implication of this is that contract method
constraints should be based on method sets, i.e. `A` can't satisfy a
contract using a method defined on `*A`, just like with interfaces.

This does rule out being able to write the generic function I showed above,
where we want to be able to accept a slice of either `A` or `*A`, and call
`*A` methods without needing to know which type is represented by the type
parameter. I'm not sure how strong the desire to support this sort of use
case is. Forcing you to use a `[]*A` in this case would be slightly
unfortunate (or `[]A` and `*T DoStuff()`, but that would require that `T`
be a value type).

This case could technically be handled with some rather more involved uses
of contracts, like

contract Slice(S, Elem, Base) {
    S []Elem
    S Index(int) *Base
    *Base DoStuff()
}

You'd just need two helper types to wrap your slice, one where `Elem` and
`Base` are identical, and one where `Elem` is identical to *Base.

It's unfortunate that you'd need to specify `Elem` and `Base` in the
signature of any function using this contract, given that they can be
inferred from `S`, but I'm not sure whether there'd be any willingness to
add associated types to the design, i.e.

contract Slice(S) {
    type S.Elem
    type S.ElemBase
    S []S.Elem
    S Index(int) *S.ElemBase
    *S.ElemBase DoStuff()
}

On Thu, Aug 1, 2019 at 6:35 AM, Max <massimiliano.ghila...@gmail.com> wrote:

> I think that a single syntax allowing both pointer receivers and value
> receivers - with no mechanism to distinguish them - creates unnecessary
> ambiguity, and in some cases it can concretely be a problem.
>
> Consider the following example, adapted from 'math/big.Int`:
> ```
> contract Comparable(T) {
>   // return -1 if receiver is lesser than 'other'
>   // return +1 if receiver is greater than 'other'
>   // return 0 if they are equal
>   T Cmp(other T) int
> }
> ```
> it seems perfectly reasonable yet, depending on the exact semantics of
> contracts, `math/big.Int` may have troubles satisfying it, because its
> method 'Cmp' has the signature
> ```
> func (recv *big.Int) Cmp(other *big.Int) int
> ```
> Thus it would require 'T' to be a pointer - namely '*big.Int' - to match.
> It would mean that the receiver itself of the contract 'T Cmp(other T)
> int' is a pointer. Is it a case allowed by contracts?
> And how does it interact with the rule that both pointer receivers and
> value receivers are allowed?
>
>
> If you ignore for a moment the ability of contracts to specify a union of
> types,
> I prefer my proposal https://github.com/cosmos72/gomacro#generics where
> contracts are just generic interfaces,
> and they can *optionally* specify the receiver type - used in case you
> want to *remove* the ambiguity between pointer and value receiver types.
> They clearly require the possibility to specify multiple contracts in a
> generic type or function signature, while the current proposal
>
> https://go.googlesource.com/proposal/+/master/design/go2draft-contracts.md#methods
> allows only a single contract in a in a generic type or function
> signature, thus requiring contracts to be able to specify the methods of
> several unrelated types.
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/cf04c27c-6ac0-4b64-96b4-f0e7a1a2a99d%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/cf04c27c-6ac0-4b64-96b4-f0e7a1a2a99d%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANjmGJst06QzPTP%3DdEPzCEk0ztgQzx9R%2BSroQ3gXkNoQZRC3rw%40mail.gmail.com.

Reply via email to