[generics] bring contracts back

247 views
Skip to first unread message

Denis Cheremisov

unread,
Jun 17, 2020, 12:58:08 PM6/17/20
to golang-nuts
IMO a groups of constraints are horrible with interfaces

type CommonResponse(type E) interface {
    GetError() E
}

type CommonError interface {
    GetCode() int32
}

func IsOK(type R CommonResponse(E), E CommonError)(r R) bool {
    switch r.GetError().GetCode() {
    case 0, 200, 201:
        return true
    default:
    return false
    }
}

vs

constract CommmonResponse(R, E) {
    R GetError() E
    E GetCode() int32
}

func IsOK(type R, E CommonResponse)(r R) bool {
    switch r.GetError().GetCode() {
    case 0, 200, 201:
        return true
    default:
    return false
    }
}

That trickery with commas to express dependcy of types is hard

Axel Wagner

unread,
Jun 17, 2020, 2:36:44 PM6/17/20
to Denis Cheremisov, golang-nuts
You can always combine multiple interface constraints:

type ConstraintA(type A) interface {
    Foo() A
}

type ConstraintB(type B) interface {
    Bar() B
}

type CombinedConstraint(type A, B) interface {
    (ConstraintA(A))
    (ConstraintB(B))
}

func F(type A, B CombinedConstraint(A, B)) (...) { ... }

So I don't think removing contracts prevents you from getting the same if you find it more readable.

--
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.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/4e25a228-4c96-44ba-b33a-bbde3460ea2ao%40googlegroups.com.

Axel Wagner

unread,
Jun 17, 2020, 2:38:10 PM6/17/20
to Denis Cheremisov, golang-nuts
Ah sorry, I misunderstood. Please disregard :)

Denis Cheremisov

unread,
Jun 17, 2020, 2:55:52 PM6/17/20
to golang-nuts
There's an advantage though, for rather narrow cases though: reuse of interfaces:

https://go2goplay.golang.org/p/HJr3QIzgQuX

среда, 17 июня 2020 г., 19:58:08 UTC+3 пользователь Denis Cheremisov написал:

Denis Cheremisov

unread,
Jun 17, 2020, 2:58:14 PM6/17/20
to golang-nuts
oops, an infitie loop in the As implementation, now the right one:

https://go2goplay.golang.org/p/5NnZBnmIC96

среда, 17 июня 2020 г., 21:55:52 UTC+3 пользователь Denis Cheremisov написал:

Я

unread,
Jun 17, 2020, 3:21:36 PM6/17/20
to Axel Wagner, golang-nuts
if you find it more readable

not only readable. I still can't get why they banned constraints on structs having some fields of certain type. With contracts they are easy to allow:

contract NameField(T) {
    T Name string
}

and there's no hope with interfaces

ср, 17 июн. 2020 г. в 21:37, Axel Wagner <axel.wa...@googlemail.com>:

Ian Lance Taylor

unread,
Jun 17, 2020, 6:11:22 PM6/17/20
to Denis Cheremisov, golang-nuts
I think there is no question that complex cases are more difficult to
express using parameterized interfaces as constraints.

But the overall change to the language seems to be simpler. There was
clear feedback on earlier versions of the design draft that contracts
could be hard to understand. And with parameterized interfaces as
constraints it is still possible to express the complex cases, albeit
in a more complicated way. It's OK if complicated are hard to
express, as long as they remain possible.

Ian

Denis Cheremisov

unread,
Jun 18, 2020, 5:07:45 PM6/18/20
to golang-nuts
> clear feedback on earlier versions of the design draft that contracts
could be hard to understand.

Yeah, sure. Now expect lots of materials throughout the web explaining "this part is for interface that is not supposed to be in a runtime but for compile time constraints". You understand better than me albeit these concepts (interfaces and contractrs) has a lot in common they are not the same. At last, take your language as an example: it shines as a glue between services and its set of primitives (goroutines, channels, full async) is what made it so successful in this domain. But you won't try to use it for serious Linux kernel module. You won't even try these primitives for GUI development (which also has asynchronous nature) because they have a huge overweight for the task.



PS I am afraid these people I were listening also want <> 


четверг, 18 июня 2020 г., 1:11:22 UTC+3 пользователь Ian Lance Taylor написал:

Denis Cheremisov

unread,
Jun 20, 2020, 11:59:31 AM6/20/20
to golang-nuts
Got one: https://rakyll.org/generics-proposal/

At the very bottom of the page, a person wrote a strange code 

func Do(type T io.Reader)(r T) {
	switch r.(type) {
	case io.ReadCloser:
		fmt.Println("ReadCloser")
	}
}
prog.go2:19:9: r (variable of type T) is not an interface type

and has a strange question.

They are strange, but still valid: why can't I cast an interface to another one. Because this is a source of confusion, two kinds of interfaces where one is called interface but is not actually an interface.

So, points are:

  • Two kind of interfaces appear, where one cannot be used anywhere except a contract: https://go2goplay.golang.org/p/rYOD-n_mV9U

  • There's a confusion between an interface used as a contract and an interface. People think if they have interface contract their type is an interface (it is not of course): https://www.reddit.com/r/golang/comments/hamaxm/few_things_on_generics_go_the_unwritten_parts/fv66zp8/?context=3. A brainless example of course, but still an example.

  • If fields will be allowed to be a part of contract (limiting allowed types to structs having some set of fields of certain types) the difference between interfaces and interfaces for contracts will grow even bigger. I see lots of questions like fron ones who just start learning Go "why can't I use a pure field interface as a function parameter type?"

  • contract also meant a built-in mechanism of type bounding, with interfaces you need to promote each type exclusively, the increased signature size is the consequence of this. Remeber, with contracts you may put a constraint on each of the parameter types and with an interface you should write them all.

  • interface flood. There's a possibility to use them as an variable/paremeter/return value type although they are only needed for a generic contract.



пятница, 19 июня 2020 г., 0:07:45 UTC+3 пользователь Denis Cheremisov написал:

Bebop Leaf

unread,
Jun 20, 2020, 1:19:14 PM6/20/20
to golang-nuts
Personally I am happy with the current way of expressing constraints, i.e., interface-like + type lists, but I do think constraints and interfaces, are two different concepts, and forcing them into a same box does not mitigate the extra cognitive load needed to understand generics (which, as in the current draft proposal, is rather light).

On the other hand, I am not sure how to balance this against other factors (many of which I am not even aware of), like backward compatibility, so this is just my two cents.
Reply all
Reply to author
Forward
0 new messages