* Andy Balholm <andybalh...@gmail.com> [181024 17:52]: > What I’m doing with structural contracts is basically the same as what > you’re doing with struct and interface types as contracts, except that > (I hope) the syntax is a little clearer. > > I added the support for operators basically to avoid having the > supportsEqual contract as a special case that needs to be built in. > Most other operators could be handled just as well with an enumerated > contract, so maybe it would be better to just have supportsEqual or > comparable as a built-in contract. > > The equivalent to your StrNum example in my syntax would be: > > contract num int, int8, int16… > > contract StrNum { > num > String() string > }
The most powerful feature of the contracts described in the original design draft is the ability to describe interactions between two types in a type specification. Your proposal doesn't seem to allow this. Also, you seem to be trying to use "familiar" Go constructs for your contract body, but you mix types, fields, and operators at the same syntactical level. This is bound to be a source of significant cognitive load both when writing and reading contracts. My mini-proposal, given earlier in one of these threads (all the different partially-related threads have become rather jumbled!), is a change to the contract body syntax from the original design draft. It has the following features: ∙ The syntax is extremely simple and consistent. It is trivial for the compiler to parse and trivial for the programmer to both write and read. ∙ It adds zero keywords outside of a contract body, regardless of how many contract keywords are added and at what time (absolute extensibility). ∙ The keywords can and should be descriptive enough that once you have used a keyword one time, you will rarely need to return to the documentation to remember what it does. ∙ A keyword can have any number of arguments, as needed for its particular semantics (see next point). Each argument can conceivably have any syntax that is not ambiguous with parens and commas to enclose and separate the arguments, though I would encourage limiting it to a very small set of possible choices, such as an identifier, a type, an operator, and possibly a string constant. ∙ A keyword can have any semantic meaning desired. It can identify another type that must be, at some recursive level, an underlying type. It can identify a list of types, one of which must be (recursively) an underlying type. It can identify an operator along with the method that must implement that operator for the type. It can name an interface that the type must implement. It can specify that the type must be a slice of another type (perhaps another type in the type specification, linking the two types). It can specify that it is a map whose keys and or values are particular types. It can specify that the type has a particular size on (or based on) the current architecture. As a ridiculous example just to show the flexibility, it could specify that the type is a struct with a public field whose name ends in a vowel, that does not satisfy a particular interface, and that has an import path matching a specific regular expression. This last point, along with the absolute extensibility means that we can start with a small number of contract keywords, and add new ones as we determine the need. There will never be a need to change the contract syntax just because a new desirable feature might have a conflicting Go syntax or namespace with an existing contract specification. E.g. a type and a field name have separate namespaces, yet your syntax uses both names at the same syntactic level; with my syntax these would be used as arguments to different contract keywords, so there would be no ambiguity. I think the primary goal of adding generics to Go is to allow writing code once that can be used with multiple types with compile-time type safety. There are two mutually independent, specific features that appear to be desired by a significant number of Go programmers: parametrically-specified types for functions and/or types, and operator overloading. I am wholly in favor of parametric types if it can be done without falling down the C++ rabbit-hole. I like the idea of operator overloading, but only if it can be done in a way that visually distinguishes native operators from user operators (see a previous post). However, I could easily do without operator overloading if necessary. Andy, if your proposal is just taking the design draft and replacing the contract syntax, then I like it, but I believe my syntax is significantly better. While I like the idea and simplicity of the "implements" proposal, I think it falls way short of what most people want (or subconsciously expect) with generics. Furthermore, I am not sure many people understand how and why that is the case. It has to do, in part, with boxed values vs concrete types, and the trade-offs between what information the programmer puts in the source code and where, compiler speed, and execution speed. On a separate thread, Axel Wagner and roger peppe are having a discussion related to this, and I have to say that I am firmly in roger's camp. With interfaces, in order for the compiler to know the set of possible types so that it can optimize the code for individual types, it must generate a call graph and look back an undetermined number of call levels. With parametrically specified types, the set of possible types is known immediately at the site where and argument is passed and where a result is returned. This information is directly available as a result of parsing, without any semantic analysis. So, by having the programmer parametrically specify the types, the compiler can be much faster and produce better (or at least equally) optimized code. I believe the disadvantages of the "implements" proposal, specifically less flexibility and expressiveness and slower compilation and/or execution times, significantly outweigh its beauty and simplicity. ...Marvin -- 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.