New keywords in java

    In the near future, new features will appear in the Java language, over which work is currently underway in the framework of the Valhalla, Panama and Loom projects. Expansion of a language is not an easy task, all the more so with a language in which emphasis is placed on backward compatibility; therefore, in order for their integration in Java to go smoothly, the architects of the language have to solve the accumulated fundamental issues.

    Yesterday (January 8), Brian Goetz, who works for Oracle at the Java Language Architect position, published a letter in the Amber mailing list “We need more keywords, captain!” , In which he proposed a way to solve the problem of adding new keywords to the language. As a result, keywords such as non-null , non-final , eventually-final , may appear in the language.and this-return (the full list is waiting for you under the cut at the end of the post).

    Since in the past this problem occurred infrequently in the language, they usually didn’t particularly think about it and “tried to get out of the neck as quickly as possible”; due to the shortcomings of the already existing approaches in the future, their application will be problematic, and therefore it was decided to work ahead. Proposed solution: try to expand the set of lexical forms that can be used as keywords: allow keywords separated by a hyphen, which will include one (or more) existing keyword or a reserved identifier.

    Important note: Brown notes that new keywords are given solely as an illustrative example, and that you shouldn’t focus your attention on them. However, it is obvious that we have a deliberate demonstration of how the syntax of a language can change in the future - the author mentions in the letter that this idea will help add many desired missing language constructs to Java.

    "Old" methods


    As is known, today in the Java language there are 50 keywords ( keywords ), which are forbidden to be used as identifiers of variables. Their complete list is given in the JLS language specification in clause 3.9 . This list has not changed much from the first version of the language - only assert was added in 4 versions, enum in 5 and _ in 9. Besides them, there are also “reserved identifiers” - this is true , false and null - which behave similar to keywords in a way.

    When developers need to add a new keyword to the language, they have to resort to one of the following methods.

    • Compulsory alienation of property: we take the words that were previously identifiers, and turn them into keywords (for example, assert ).
    • Disposal: an existing keyword begins to be used in a way that it was never intended to use (an example is the use of default for annotation values ​​or default methods).
    • Do without it: find a way to use syntax that does not require a new keyword — for example, use the interface for annotations instead of annotation — or discard the feature altogether.
    • Appearance creation: create an illusion of context-dependent keywords using heroic linguistic achievements ( restricted keywords, reserved type names ).

    In principle, you can usually use any of these methods, but each of them has its drawbacks, and for a serious full-scale language extension these methods alone are not enough - for future innovations, it will be necessary to eliminate the impossibility of a full-scale language syntax extension.

    Adding new keywords


    Against “just” taking and adding new words, there are the following arguments.

    • The more convenient and popular the chosen keyword is, the more often it will appear in the source code of programs, which will add incompatibility to the language (for example, when the word assert appeared in Java SE 1.4, all test frameworks stopped working).
    • The cost of eliminating such incompatibility of code by the developer will vary greatly from small (renaming a local variable) to fatal (when an interface or public type method becomes invalid).
    • Words most likely to be used by language developers are popular identifiers (for example, value , var , or method );
    • If you choose words that are rarely used in the source code and which will have fewer collisions, you will have to use constructions like usually_but_not_always_final , which naturally I would like to avoid.
    • If, after all, resorting to the choice of rarely used words, then using this method too often will not work - breaking compatibility is not good, and there are not that many more successful combinations.

    Reuse of “old” keywords


    In order to "just" continue to live with those words, have your own thoughts.

    • The use cases of keyword reuse in different contexts are found in many programming languages ​​(an example from Java is the use of ( (ab) use ) final for the symbols "not changeable", "not redefinable" and "not extensible").
    • Sometimes this approach makes sense and comes by itself, but usually it is not a priority.
    • Over time, the set of requirements for a set of keywords expands, and things can get ridiculous - no one wants to use null final in their code .
    • If the latter seemed to be an exaggeration to you, then keep in mind that while working on JEP 325 , it was quite seriously suggested to use the new switch construct to describe a switch with different semantics than accepted - if we continue in the same spirit, in ten years we can reach new new switch .

    How to live without new keywords? You can only completely stop doing the evolution of the language, as some suggest. But this is not serious and does not fit with the opinion of the others, since there is a healthy interest on the part of developers to the new possibilities of the language.

    Contextual keywords


    Contextual keywords that are used to provide a specific value in the code, but they are not reserved words ( used in C # ) at first glance seem to be the very “magic wand”, but here Brian sets out his own view on their use based on practice ( for example, the var implementation in Java 10, which is not the keyword, but the reserved type name ). In exchange for the illusion of adding new keywords without having to “break” existing programs, we get increased complexity and distortion in the language.

    Contextual keywords create difficulties for authors of specifications, compilers, and IDEs. In the case of one or two special cases, this does not cause problems, but when they are used everywhere, it results in a much higher cost of maintaining the code or the tail of the bugs.

    One could brush aside this - they say, this is not a problem of the users of the language, but of its creators and those who write compilers and IDE. But in fact, all end up suffering. For an IDE, this can be a significant problem: more input information is required in order to guess what the developer is introducing — the context keyword or identifier. As a result, users get a deterioration in the work of syntax highlighting code, autocompletion and refactoring capabilities.

    You can use this tool, but it should be done with caution.

    Language distortion


    It would seem that with the problems that cause the listed approaches - with awkward syntax, unnecessary complication of life and bugs - in principle it would be possible to accept. But there is another not the most obvious problem - the nuances of using keywords lead to a distorted design of the language itself.

    For Java developers, writing the interface instead of annotation is a common thing today, but everyone agrees that using the clear term annotation instead of the combination of @ and the "old" keyword would be much more logical.

    Another example: the set of available modifiers (public, private, static, final, etc.) cannot be called complete - we can’t say not final or not static. In turn, this means that you cannot create features in which variables or classes are final by default , or members are static by default , since there is no way to indicate that we would like to discard this modifier.

    This problem is not so obvious for those who use the language - but the authors of the language itself, because of their desire to develop it, are constantly faced with it and pay for such decisions (when it is obvious, when it is implicit) that we all end up with.

    The conclusion from all of the above suggests itself: we need another source of keywords.

    Proposed solution


    In the experimental possibilities of the language, the syntax is used to preliminarily designate new keywords, in which the new keywords themselves are preceded by two underscores (for example, in the Project Valhalla prototype this is __ByValue ). The reason for this decision is clear - you need to point out that this is a temporary replacement, for which you will need to make a decision about the final syntax in the future, and you can easily avoid collisions with existing code. One could suggest using a similar format for new keywords - start them with one or two underscores - but this solution cannot be called beautiful, because in this case we will get confusion from ordinary and new keywords at the output.

    Therefore, it is proposed to use keywords constructed using a hyphen, which will include one or more “old” keywords or reserved identifiers.

    Unlike restricted keywords , this approach will create far fewer problems for parsing, since (hereinafter - an example) not-null cannot be confused with the expression of subtraction, and the lexer can always determine whether ab isthree tokens or one. Thanks to this, new opportunities are opening up for us to create keywords that are much less likely to conflict with existing source code or with each other. On top of that, they are much more likely to have meaningful names, since much of what the creators of the language want to add to Java is based on the language constructs that already exist in it — for example, non-null .

    As examples of new keywords, there are likely candidates for new keywords (I remind you that, according to the author, at the moment this list is purely illustrative):

    - non-null ;
    - non-final ;
    - package-private(modifier of the level of access to the members of the class by default, which is currently not indicated in any way);
    - public-read (publicly read, privately written);
    - null-checked ;
    - type-static (a concept necessary for Valhalla ; means static with respect to a specific specialization of a class, not the class itself);
    - default-value ;
    - Eventually-final (what is now supposed to do with annotations Stable ),
    - the semi-final (alternatively sealed );
    - exhaustive-switch;
    - enum-class , annotation-class , record-class (the authors of the language could use these keywords as an alternative to enum and interface if they had such an opportunity);
    - this-class (to describe the class literal for the current class);
    - this-return (often asked to add a way to mark the setter / builder method as returning its recipient).

    Surely there are other versions of lexical schemes, according to which it would be possible to make keywords so that they minimally overlap with the already written source code. The proposed option with a hyphen is quite readable for both cars and humans.

    It is implied that this approach in no way excludes the possibility of using together with those used previously, but will be used along with them.

    Only registered users can participate in the survey. Sign in , please.

    How do you like the idea?


    Also popular now: