Quoting alan.f...@gmail.com (2018-10-20 16:59:52) > I haven't checked them all but I did notice one example which your > paper doesn't appear to cover, namely the add1K example which has been > a stumbling block for a lot of proposals including my own though I did > eventually find a way of dealing with it.
This is a fair point. I have a couple of initial thoughts, but will think about it. The contract there actually brings up my other big complaint about contracts besides non-orthogonality; they are not a good expression of intent. For reference: contract add1K(x T) { x = 1000 x + x } While it's possible to piece together what has to be true about a type to satisfy this contract, it's really not obvious at the outset what the point of it is. Looking at the contracts in the draft design, I feel like I would generally speaking have to jump through mental hoops to understand what concepts were being expressed by a given contract. > 1. If interfaces were used, a way would need to be devised to express > that a type supports a particular operator or operators. To be > compatible with methods something like the following seems best: > � � � +(T, T) T > However, this would mean that someone writing an interface to be used > for generic constraint purposes would have to know and write out the > signature for each operator used. This seems like a relatively minor problem. Eric sketched out a possible syntax, here is another: type Ordered[type T] interface { operator < (other T) bool } func (MyType) operator < (other T) bool { ... } (where `operator` becomes a keyword) I'm not convinced having to remember the type signatures is a problem -- for most operators they are fairly self-evident, and we already have to do this for a wide range of interfaces in the standard library. I think adding a whole new concept to the language is a much bigger cognitive load. > 2. As your own paper clearly shows, it is possible to deal with > multiple type parameters which refer to each other using an interface > based approach and even the draft design paper itself admits this is > possible. However, it seems to me to be less elegant than a contract > based approach. > An interface can only express the methods which a single type needs to > satisfy and so a separate interface is needed for each mutually > referential type parameter. A contract on the other hand doesn't have > this constraint and, indeed, the type parameters as a group have to > satisfy a single contract which, to my mind, ties the whole thing > together in a much nicer way. I actually have a fairly clear design in my head for adding associated types to interfaces, which my current design generalizes to cleanly, but I left it out because I'm not convinced that this kind of thing is common enough to be worth optimizing for. My gut is that this kind of contract will be the exception, rather than the rule, and I would err on the side of leaving things out. I think it will be common enough that we'll want it to be *doable*, but I'm not convinced being a little more concise is worth adding conceptual complexity. > 3. Interfaces don't deal with fields at all and so would need to be > extended to cope with a struct constraint. To be fair, some people have > questioned whether such constraints are important enough to be catered > for at all but the draft design does nevertheless deal with them and so > does my own paper. There's an issue on Github that Ian T ha referred to in several threads re: adding fields to interfaces, which has been rejected. I think the arguments against it all also apply to using contracts to do the same thing (see also my complaints about expressing intent) I'm not convinced that the fact that contracts can express this is a good thing. > 4. There are a number of minor (though tricky) issues which interfaces > can't currently deal with but contracts can and which I listed in my > paper. To take one in particular - excluded types - it is difficult to > see how interfaces could deal with something like that though, as it's > a novel idea anyway, perhaps some other way could be found to achieve > the same result. Are there other use cases for this besides the numeric range issue? If not I think this falls into the same bucket as the add1k example, and I will have to think about it. > 5. Finally - and you might think this is a bit silly - but there are a > lot of people who don't like the idea of generics at all and will > probably try to avoid them if they can. Now, hopefully they will change > their minds when they see how convenient generics can be to use. > Nevertheless, I still think it's important to cater for such people and > leaving interfaces as they are and confining the generic stuff to > contracts should help here. My proposal doesn't really change interfaces themselves in any meaningful way -- it just applies them to bounding type parameters, mostly as-is. -- 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. For more options, visit https://groups.google.com/d/optout.