Skip to content

Instantly share code, notes, and snippets.

@seebs
Created August 29, 2018 15:16
Show Gist options
  • Save seebs/8f943b8b15a8c63c28c7f6f4e5ca6c53 to your computer and use it in GitHub Desktop.
Save seebs/8f943b8b15a8c63c28c7f6f4e5ca6c53 to your computer and use it in GitHub Desktop.
contract design feedback for go2 generics

One question occurs me with regards to this example:

contract mappable(k K, _ V) { k == k }

Why not

contract mappable[_ K, _ V] { var _ map[K]V }

This would, I think, make the intent much clearer.

I am also conflicted on the fact that a single contract must be specified for multiple types. I would sort of like the ability to express a thing roughly like:

func X(type T1 contract1, T2 contract2)(...)

For instance, consider:

func MapKeysSortedByValue(type T1 keyworthy, type T2 orderable)(map[T1]T2)([]T1) { ... }

I can express this with a single contract on both T1 and T2, but each contract makes sense to talk about separately.

Counterargument: It's necessary to be able to specify a contract on multiple types, and at that point, if you can specify contracts per-type OR per-multiple-types, you need more ()s or something and it's just awful.

@brandondyck
Copy link

brandondyck commented Aug 29, 2018

You can compose multiple contracts for a parameterized type similarly to how you compose interfaces, by creating a new one that embeds the others:

contract keyworthy(x T) { ... }

contract orderable(x T) { ... }

contract keyworthyOrderable(_ K, _ O) {
	keyworthy(K)
	orderable(O)
}

func MapKeysSortedByValue(type T1, T2 keyworthyOrderable)(map[T1]T2)([]T1) { ... }

I agree with you that also allowing per-parameter contracts would be both useful and very messy. An alternative would be to allow anonymous contracts:

func MapKeysSortedByValue(type T1, T2 contract {
	keyworthy(T1)
	orderable(T2)
})(map [T1]T2) []T1 { ... }

This is analogous to anonymously composing interfaces:

type A interface {}
type B interface {}
func abber(ab interface{A;B}) { ... }

EDIT: I asked Ian Lance Taylor for his thoughts on this at Gophercon, and if I remember correctly, he said that inline contracts were originally written into the design but then removed because they were so ugly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment