I think it's fair to say that dealing with untyped numeric constants is one
of the most opaque areas of the draft design and I remember thinking when I
first read it that a clearer and more intuitive solution would have to be
found.
As far as the 'excluded types' idea is concerned, I can't really think of
any other use cases apart from numeric ranges though it's worth noting in
my paper I had this example:
contract add1K(T) {
T + T
T(unsigned int)
exclude{string, int8, uint8}(T) // can't add a thousand to these
}
where I had to explicitly exclude 'string' because it supports both the +
operator and a conversion from any integer value.
Alan
On Saturday, October 20, 2018 at 11:36:02 PM UTC+1, Ian Denhardt wrote:
>
> Quoting [email protected] <javascript:> (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 [email protected].
For more options, visit https://groups.google.com/d/optout.