On Sat, 27 Oct 2018, 5:46 pm <alan.f...@gmail.com wrote: > So you're basically saying that an identifier should either be reserved or > not and that there should be no *contextual* keywords at all, not even > *contract*. >
Yes, I agree with this. FWIW the generics draft proposal has at least one suggestion for avoiding "contract" as a context-sensitive token: - We could make contract be a keyword only at the start of a top-level declaration, and otherwise be a normal identifier. That's easy to implement in a tokenizer, at least, and it probably doesn't matter too much if gofmt barfs on in-function Go code that uses "contract" as an identifier. For keywords like "check" I think my preference is to state up front which version of the language is being parsed. The default could come from the local go.mod file. > Well, it's a clear and simple stance to take but it inevitably means that > adding any new keyword will not be backwards compatible and I'm not sure > the Go team will be happy with it because of that. > > Alan > > On Saturday, October 27, 2018 at 1:31:49 PM UTC+1, rog wrote: >> >> I'm not keen on this idea (including Ian's idea too). It makes parsing >> context-sensitive because the set of syntactic tokens varies would depend >> on the names declared in the package. That is, you can't parse a file in >> isolation because without reading all the files in a package, you don't >> know which of the keywords have been defined as local names. It would mean >> that you couldn't just pipe an arbitrary Go file to gofmt, for example. >> >> The context-insensitive grammar is one of Go's great strengths. Let's not >> lose that, please. >> >> >> >> >> >> On Fri, 26 Oct 2018 at 11:22, <alan...@gmail.com> wrote: >> >>> Inspired to some extent by Ian's idea, I've had another idea which could >>> rid us of the *new keyword problem* not just for Go 1.xx or Go 2 but >>> for ever. We wouldn't even have to worry about whether a new keyword could >>> be restricted to *contextual* use or not. >>> >>> Suppose any new keyword introduced from Go 1.xx onwards could only begin >>> with a lower case letter and could *optionally* be followed by the *!* >>> symbol for disambiguation purposes. So, one could potentially have check!, >>> handle!, contract! and so on. >>> >>> Suppose further that: >>> >>> 1. If you didn't use *!* and there was some local entity in an *encompassing >>> scope* with the same name as the keyword, the compiler flagged it as an >>> error. >>> >>> 2. If you did use *!* unnecessarily, the compiler would also flag that >>> as an error. >>> >>> Now in the first case, you'd have the choice of either changing the name >>> of the local entity to a non-keyword or adding *!* to the keyword >>> usage(s). In practice, most people would probably choose the former. >>> >>> In the second case, you'd simply remove the *!* and that would be the >>> end of the matter. >>> >>> Technically, an *encompassing scope* would be any scope which was or >>> included the scope in which the new keyword were being used. It would >>> therefore always include package scope as a minimum. >>> >>> The advantages of this approach would be: >>> >>> 1. *!* would probably be seldom needed and so shouldn't impact too >>> adversely on the *look* of the code. Over time, people might simply >>> learn to avoid using the new keywords as normal identifiers at least at top >>> level within the package. >>> >>> 2. Existing code or new code using the *old* approach would continue to >>> compile without problem. >>> >>> 3. Any function or method which didn't use any new keywords as such >>> could still freely use them as identifiers for parameters, local variables >>> or local constants. Disambiguation (or the lack of it) with similarly named >>> top level entities (including new keywords) would be the same as it is >>> today - the latter would simply be hidden. >>> >>> 4. Basically, you could just program normally (without *!*) knowing >>> that the compiler would flag up any clashes. >>> >>> 5. Clashes with imported names would never be a problem because they'd >>> usually be qualified by their package name and would begin with an upper >>> case letter anyway. >>> >>> Although other symbols such as $, %, @ or ? could be used in place of* >>> !*, I think the latter is probably the best choice as (to me at least) >>> it looks less intrusive than the others and doesn't have any other >>> connotation. It's also used (for different disambiguation purposes) in >>> other modern languages such as Rust and Swift. >>> >>> As far as the generics proposal is concerned, the use of the contract >>> keyword (which always appears at top level within the package) would only >>> be flagged as ambiguous if there were another similarly named top level >>> entity. Any use of *contract* within a function or method would not be >>> a problem because of #3 above >>> >>> So what do you think, a viable idea or not? >>> >>> Alan >>> >>> On Wednesday, October 24, 2018 at 3:22:03 PM UTC+1, Ian Lance Taylor >>> wrote: >>>> >>>> On Wed, Oct 24, 2018 at 3:49 AM, alanfo <alan...@gmail.com> wrote: >>>> > >>>> > I quite like the draft error handling design and haven't (so far) >>>> suggested >>>> > that any changes be made. >>>> > >>>> > However, one aspect I don't like is 'check' and 'handle' having to be >>>> > keywords which means that the design is not Go 1 compatible. Also, >>>> whilst I >>>> > agree that these words are probably the best ones for the job (and I >>>> would >>>> > hate to see them replaced by obscure symbols) it seems a pity that >>>> such >>>> > commonly used words will no longer be available as ordinary >>>> identifiers. >>>> > >>>> > So all I'm asking here is whether - if the design were adopted as it >>>> stands >>>> > - they could be 'contextual' rather than 'full' keywords? I couldn't >>>> find >>>> > any mention of this in the draft papers but apologize in advance if >>>> it's >>>> > been addressed and I've missed it. >>>> > >>>> > As far as this thread is concerned, I'm only interested in this >>>> question and >>>> > not what people think of the design generally. >>>> > >>>> > It seems to me that they probably could be 'contextual' keywords i.e. >>>> they >>>> > could still be used as ordinary identifiers in the same package or >>>> even >>>> > within the same function (though the latter wouldn't be a great idea >>>> from a >>>> > readability perspective). >>>> > >>>> > Considering first 'handle' which must be the first word in a line and >>>> then >>>> > be followed by an identifier. It cannot be any of the following: >>>> > >>>> > 1. A function call because its not followed by (. >>>> > >>>> > 2. An assignment because it's not followed by an =, := or , token. >>>> > >>>> > 3. An indexation expression because it's not followed by [. >>>> > >>>> > 4. A struct literal because it's not (directly) followed by {. >>>> > >>>> > 5. Any other expression because it's not followed by an operator. >>>> > >>>> > So can anyone think of anything else it could be? >>>> > >>>> > However, 'check' is more awkward because it's followed by an >>>> expression (not >>>> > an identifier) and need not be the first word in the line. If the >>>> expression >>>> > were bracketed or preceded by a unary operator then there would be a >>>> > potential ambiguity with #1 or #5 respectively. >>>> > >>>> > So would it suffice for the compiler to try and interpret 'check' in >>>> these >>>> > situations as a 'normal' identifier and issue an error if it couldn't >>>> but >>>> > otherwise to interpret it as a error handling keyword? >>>> > >>>> > The error would of course be easy enough to fix but, even if there >>>> are no >>>> > other ambiguities, would it just be too confusing and should we >>>> simply >>>> > accept that 'check' has to be a 'full' keyword as the design stands? >>>> >>>> I think that if a package does define `check` as a local function, >>>> then making contextual choices about whether `check` in an expression >>>> refers to the function or to the error checking behavior can only be >>>> confusing. >>>> >>>> One approach that could perhaps work--and I'm not at all endorsing >>>> this, just pointing it out--is that if a package defines `check` as a >>>> local name of any sort, the compiler could simply disable the error >>>> checking behavior of `check`. That is, `check` would only be a >>>> keyword if there were no local definition of `check`. >>>> >>>> Ian >>>> >>> -- >>> 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...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >> -- > 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. > -- 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.