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.
You can compose multiple contracts for a parameterized type similarly to how you compose interfaces, by creating a new one that embeds the others:
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:
This is analogous to anonymously composing interfaces:
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.